Rollup merge of #125282 - WaffleLapkin:never-type-unsafe-improvements, r=compiler-errors

Never type unsafe lint improvements

- Move linting code to a separate method
- Remove mentions of `core::convert::absurd` (#124311 was rejected)
- Make the lint into FCW

The last thing is a bit weird though. On one hand it should be `EditionSemanticsChange(2024)`, but on the other hand it shouldn't, because we also plan to break it on all editions some time later. _Also_, it's weird that we don't have `FutureReleaseSemanticsChangeReportInDeps`, IMO "this might cause UB in a future release" is important enough to be reported in deps...

IMO we ought to have three enums instead of [`FutureIncompatibilityReason`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/enum.FutureIncompatibilityReason.html#):

```rust
enum IncompatibilityWhen {
     FutureRelease,
     Edition(Edition),
}

enum IncompatibilyWhat {
    Error,
    SemanticChange,
}

enum IncompatibilityReportInDeps {
    No,
    Yes,
}
```

Tracking:
- https://github.com/rust-lang/rust/issues/123748
This commit is contained in:
Matthias Krüger 2024-05-20 08:31:41 +02:00 committed by GitHub
commit 88552615e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 86 additions and 47 deletions

View File

@ -364,41 +364,11 @@ fn calculate_diverging_fallback(
}; };
let mut fallback_to = |ty| { let mut fallback_to = |ty| {
let unsafe_infer_vars = unsafe_infer_vars.get_or_init(|| { self.lint_never_type_fallback_flowing_into_unsafe_code(
let unsafe_infer_vars = compute_unsafe_infer_vars(self.root_ctxt, self.body_id); &unsafe_infer_vars,
debug!(?unsafe_infer_vars); &coercion_graph,
unsafe_infer_vars root_vid,
});
let affected_unsafe_infer_vars =
graph::depth_first_search_as_undirected(&coercion_graph, root_vid)
.filter_map(|x| unsafe_infer_vars.get(&x).copied())
.collect::<Vec<_>>();
for (hir_id, span, reason) in affected_unsafe_infer_vars {
self.tcx.emit_node_span_lint(
lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
hir_id,
span,
match reason {
UnsafeUseReason::Call => {
errors::NeverTypeFallbackFlowingIntoUnsafe::Call
}
UnsafeUseReason::Method => {
errors::NeverTypeFallbackFlowingIntoUnsafe::Method
}
UnsafeUseReason::Path => {
errors::NeverTypeFallbackFlowingIntoUnsafe::Path
}
UnsafeUseReason::UnionField => {
errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField
}
UnsafeUseReason::Deref => {
errors::NeverTypeFallbackFlowingIntoUnsafe::Deref
}
},
); );
}
diverging_fallback.insert(diverging_ty, ty); diverging_fallback.insert(diverging_ty, ty);
}; };
@ -464,6 +434,41 @@ fn calculate_diverging_fallback(
diverging_fallback diverging_fallback
} }
fn lint_never_type_fallback_flowing_into_unsafe_code(
&self,
unsafe_infer_vars: &OnceCell<UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)>>,
coercion_graph: &VecGraph<ty::TyVid, true>,
root_vid: ty::TyVid,
) {
let unsafe_infer_vars = unsafe_infer_vars.get_or_init(|| {
let unsafe_infer_vars = compute_unsafe_infer_vars(self.root_ctxt, self.body_id);
debug!(?unsafe_infer_vars);
unsafe_infer_vars
});
let affected_unsafe_infer_vars =
graph::depth_first_search_as_undirected(&coercion_graph, root_vid)
.filter_map(|x| unsafe_infer_vars.get(&x).copied())
.collect::<Vec<_>>();
for (hir_id, span, reason) in affected_unsafe_infer_vars {
self.tcx.emit_node_span_lint(
lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
hir_id,
span,
match reason {
UnsafeUseReason::Call => errors::NeverTypeFallbackFlowingIntoUnsafe::Call,
UnsafeUseReason::Method => errors::NeverTypeFallbackFlowingIntoUnsafe::Method,
UnsafeUseReason::Path => errors::NeverTypeFallbackFlowingIntoUnsafe::Path,
UnsafeUseReason::UnionField => {
errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField
}
UnsafeUseReason::Deref => errors::NeverTypeFallbackFlowingIntoUnsafe::Deref,
},
);
}
}
/// Returns a graph whose nodes are (unresolved) inference variables and where /// Returns a graph whose nodes are (unresolved) inference variables and where
/// an edge `?A -> ?B` indicates that the variable `?A` is coerced to `?B`. /// an edge `?A -> ?B` indicates that the variable `?A` is coerced to `?B`.
fn create_coercion_graph(&self) -> VecGraph<ty::TyVid, true> { fn create_coercion_graph(&self) -> VecGraph<ty::TyVid, true> {

View File

@ -4263,8 +4263,7 @@
/// ///
/// // where absurd is a function with the following signature /// // where absurd is a function with the following signature
/// // (it's sound, because `!` always marks unreachable code): /// // (it's sound, because `!` always marks unreachable code):
/// fn absurd<T>(_: !) -> T { ... } /// fn absurd<T>(never: !) -> T { ... }
// FIXME: use `core::convert::absurd` here instead, once it's merged
/// ``` /// ```
/// ///
/// While it's convenient to be able to use non-diverging code in one of the branches (like /// While it's convenient to be able to use non-diverging code in one of the branches (like
@ -4321,7 +4320,12 @@
/// [`()`]: https://doc.rust-lang.org/core/primitive.unit.html /// [`()`]: https://doc.rust-lang.org/core/primitive.unit.html
pub NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, pub NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
Warn, Warn,
"never type fallback affecting unsafe function calls" "never type fallback affecting unsafe function calls",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange,
reference: "issue #123748 <https://github.com/rust-lang/rust/issues/123748>",
};
report_in_external_macro
} }
declare_lint! { declare_lint! {

View File

@ -7,6 +7,7 @@ fn _zero() {
if false { if false {
unsafe { mem::zeroed() } unsafe { mem::zeroed() }
//~^ warn: never type fallback affects this call to an `unsafe` function //~^ warn: never type fallback affects this call to an `unsafe` function
//~| warn: this will change its meaning in a future release!
} else { } else {
return; return;
}; };
@ -21,6 +22,7 @@ fn _trans() {
struct Zst; struct Zst;
core::mem::transmute(Zst) core::mem::transmute(Zst)
//~^ warn: never type fallback affects this call to an `unsafe` function //~^ warn: never type fallback affects this call to an `unsafe` function
//~| warn: this will change its meaning in a future release!
} }
} else { } else {
return; return;
@ -36,6 +38,7 @@ union Union<T: Copy> {
unsafe { Union { a: () }.b } unsafe { Union { a: () }.b }
//~^ warn: never type fallback affects this union access //~^ warn: never type fallback affects this union access
//~| warn: this will change its meaning in a future release!
} else { } else {
return; return;
}; };
@ -45,6 +48,7 @@ fn _deref() {
if false { if false {
unsafe { *ptr::from_ref(&()).cast() } unsafe { *ptr::from_ref(&()).cast() }
//~^ warn: never type fallback affects this raw pointer dereference //~^ warn: never type fallback affects this raw pointer dereference
//~| warn: this will change its meaning in a future release!
} else { } else {
return; return;
}; };
@ -62,6 +66,7 @@ unsafe fn internally_create<T>(_: Option<T>) {
unsafe { internally_create(x) } unsafe { internally_create(x) }
//~^ warn: never type fallback affects this call to an `unsafe` function //~^ warn: never type fallback affects this call to an `unsafe` function
//~| warn: this will change its meaning in a future release!
x.unwrap() x.unwrap()
} else { } else {
@ -73,9 +78,11 @@ fn _stored_function() {
if false { if false {
let zeroed = mem::zeroed; let zeroed = mem::zeroed;
//~^ warn: never type fallback affects this `unsafe` function //~^ warn: never type fallback affects this `unsafe` function
//~| warn: this will change its meaning in a future release!
unsafe { zeroed() } unsafe { zeroed() }
//~^ warn: never type fallback affects this call to an `unsafe` function //~^ warn: never type fallback affects this call to an `unsafe` function
//~| warn: this will change its meaning in a future release!
} else { } else {
return; return;
}; };
@ -90,6 +97,7 @@ unsafe fn internally_create<T>(_: Option<T>) {
let x = None; let x = None;
let f = internally_create; let f = internally_create;
//~^ warn: never type fallback affects this `unsafe` function //~^ warn: never type fallback affects this `unsafe` function
//~| warn: this will change its meaning in a future release!
unsafe { f(x) } unsafe { f(x) }
@ -113,6 +121,7 @@ unsafe fn create_out_of_thin_air(&self) -> T {
unsafe { unsafe {
S(marker::PhantomData).create_out_of_thin_air() S(marker::PhantomData).create_out_of_thin_air()
//~^ warn: never type fallback affects this call to an `unsafe` method //~^ warn: never type fallback affects this call to an `unsafe` method
//~| warn: this will change its meaning in a future release!
} }
} else { } else {
return; return;
@ -129,6 +138,7 @@ macro_rules! msg_send {
() => { () => {
match send_message::<_ /* ?0 */>() { match send_message::<_ /* ?0 */>() {
//~^ warn: never type fallback affects this call to an `unsafe` function //~^ warn: never type fallback affects this call to an `unsafe` function
//~| warn: this will change its meaning in a future release!
Ok(x) => x, Ok(x) => x,
Err(_) => loop {}, Err(_) => loop {},
} }

View File

@ -4,75 +4,93 @@ warning: never type fallback affects this call to an `unsafe` function
LL | unsafe { mem::zeroed() } LL | unsafe { mem::zeroed() }
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
| |
= warning: this will change its meaning in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the type explicitly = help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
warning: never type fallback affects this call to an `unsafe` function warning: never type fallback affects this call to an `unsafe` function
--> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:22:13 --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:23:13
| |
LL | core::mem::transmute(Zst) LL | core::mem::transmute(Zst)
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= warning: this will change its meaning in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the type explicitly = help: specify the type explicitly
warning: never type fallback affects this union access warning: never type fallback affects this union access
--> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:37:18 --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:39:18
| |
LL | unsafe { Union { a: () }.b } LL | unsafe { Union { a: () }.b }
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
| |
= warning: this will change its meaning in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the type explicitly = help: specify the type explicitly
warning: never type fallback affects this raw pointer dereference warning: never type fallback affects this raw pointer dereference
--> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:46:18 --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:49:18
| |
LL | unsafe { *ptr::from_ref(&()).cast() } LL | unsafe { *ptr::from_ref(&()).cast() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= warning: this will change its meaning in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the type explicitly = help: specify the type explicitly
warning: never type fallback affects this call to an `unsafe` function warning: never type fallback affects this call to an `unsafe` function
--> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:63:18 --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:67:18
| |
LL | unsafe { internally_create(x) } LL | unsafe { internally_create(x) }
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
| |
= warning: this will change its meaning in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the type explicitly = help: specify the type explicitly
warning: never type fallback affects this call to an `unsafe` function warning: never type fallback affects this call to an `unsafe` function
--> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:77:18 --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:83:18
| |
LL | unsafe { zeroed() } LL | unsafe { zeroed() }
| ^^^^^^^^ | ^^^^^^^^
| |
= warning: this will change its meaning in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the type explicitly = help: specify the type explicitly
warning: never type fallback affects this `unsafe` function warning: never type fallback affects this `unsafe` function
--> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:74:22 --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:22
| |
LL | let zeroed = mem::zeroed; LL | let zeroed = mem::zeroed;
| ^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= warning: this will change its meaning in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the type explicitly = help: specify the type explicitly
warning: never type fallback affects this `unsafe` function warning: never type fallback affects this `unsafe` function
--> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:91:17 --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:98:17
| |
LL | let f = internally_create; LL | let f = internally_create;
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
| |
= warning: this will change its meaning in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the type explicitly = help: specify the type explicitly
warning: never type fallback affects this call to an `unsafe` method warning: never type fallback affects this call to an `unsafe` method
--> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:114:13 --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:122:13
| |
LL | S(marker::PhantomData).create_out_of_thin_air() LL | S(marker::PhantomData).create_out_of_thin_air()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= warning: this will change its meaning in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the type explicitly = help: specify the type explicitly
warning: never type fallback affects this call to an `unsafe` function warning: never type fallback affects this call to an `unsafe` function
--> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:130:19 --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:139:19
| |
LL | match send_message::<_ /* ?0 */>() { LL | match send_message::<_ /* ?0 */>() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -80,6 +98,8 @@ LL | match send_message::<_ /* ?0 */>() {
LL | msg_send!(); LL | msg_send!();
| ----------- in this macro invocation | ----------- in this macro invocation
| |
= warning: this will change its meaning in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the type explicitly = help: specify the type explicitly
= note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)