diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index e456bd7fd4a..e8533c68c79 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -364,41 +364,11 @@ impl<'tcx> FnCtxt<'_, 'tcx> { }; let mut fallback_to = |ty| { - 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::>(); - - 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 - } - }, - ); - } + self.lint_never_type_fallback_flowing_into_unsafe_code( + &unsafe_infer_vars, + &coercion_graph, + root_vid, + ); diverging_fallback.insert(diverging_ty, ty); }; @@ -464,6 +434,41 @@ impl<'tcx> FnCtxt<'_, 'tcx> { diverging_fallback } + fn lint_never_type_fallback_flowing_into_unsafe_code( + &self, + unsafe_infer_vars: &OnceCell>, + coercion_graph: &VecGraph, + 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::>(); + + 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 /// an edge `?A -> ?B` indicates that the variable `?A` is coerced to `?B`. fn create_coercion_graph(&self) -> VecGraph { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 53694545772..3b8bec887ea 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4263,8 +4263,7 @@ declare_lint! { /// /// // where absurd is a function with the following signature /// // (it's sound, because `!` always marks unreachable code): - /// fn absurd(_: !) -> T { ... } - // FIXME: use `core::convert::absurd` here instead, once it's merged + /// fn absurd(never: !) -> T { ... } /// ``` /// /// While it's convenient to be able to use non-diverging code in one of the branches (like @@ -4321,7 +4320,12 @@ declare_lint! { /// [`()`]: https://doc.rust-lang.org/core/primitive.unit.html pub NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, Warn, - "never type fallback affecting unsafe function calls" + "never type fallback affecting unsafe function calls", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange, + reference: "issue #123748 ", + }; + report_in_external_macro } declare_lint! { diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs index 0ae498c134f..d65bfee843e 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs @@ -7,6 +7,7 @@ fn _zero() { if false { unsafe { mem::zeroed() } //~^ warn: never type fallback affects this call to an `unsafe` function + //~| warn: this will change its meaning in a future release! } else { return; }; @@ -21,6 +22,7 @@ fn _trans() { struct Zst; core::mem::transmute(Zst) //~^ warn: never type fallback affects this call to an `unsafe` function + //~| warn: this will change its meaning in a future release! } } else { return; @@ -36,6 +38,7 @@ fn _union() { unsafe { Union { a: () }.b } //~^ warn: never type fallback affects this union access + //~| warn: this will change its meaning in a future release! } else { return; }; @@ -45,6 +48,7 @@ fn _deref() { if false { unsafe { *ptr::from_ref(&()).cast() } //~^ warn: never type fallback affects this raw pointer dereference + //~| warn: this will change its meaning in a future release! } else { return; }; @@ -62,6 +66,7 @@ fn _only_generics() { unsafe { internally_create(x) } //~^ warn: never type fallback affects this call to an `unsafe` function + //~| warn: this will change its meaning in a future release! x.unwrap() } else { @@ -73,9 +78,11 @@ fn _stored_function() { if false { let zeroed = mem::zeroed; //~^ warn: never type fallback affects this `unsafe` function + //~| warn: this will change its meaning in a future release! unsafe { zeroed() } //~^ warn: never type fallback affects this call to an `unsafe` function + //~| warn: this will change its meaning in a future release! } else { return; }; @@ -90,6 +97,7 @@ fn _only_generics_stored_function() { let x = None; let f = internally_create; //~^ warn: never type fallback affects this `unsafe` function + //~| warn: this will change its meaning in a future release! unsafe { f(x) } @@ -113,6 +121,7 @@ fn _method() { unsafe { S(marker::PhantomData).create_out_of_thin_air() //~^ warn: never type fallback affects this call to an `unsafe` method + //~| warn: this will change its meaning in a future release! } } else { return; @@ -129,6 +138,7 @@ fn _objc() { () => { match send_message::<_ /* ?0 */>() { //~^ warn: never type fallback affects this call to an `unsafe` function + //~| warn: this will change its meaning in a future release! Ok(x) => x, Err(_) => loop {}, } diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr index 84c9385fd13..fbd92f8f662 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr @@ -4,75 +4,93 @@ warning: never type fallback affects this call to an `unsafe` function LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 = help: specify the type explicitly = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default 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) | ^^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 = help: specify the type explicitly 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 } | ^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 = help: specify the type explicitly 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() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 = help: specify the type explicitly 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) } | ^^^^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 = help: specify the type explicitly 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() } | ^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 = help: specify the type explicitly 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; | ^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 = help: specify the type explicitly 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; | ^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 = help: specify the type explicitly 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() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 = help: specify the type explicitly 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 */>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,6 +98,8 @@ LL | match send_message::<_ /* ?0 */>() { LL | msg_send!(); | ----------- in this macro invocation | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 = 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)