diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 454ec7ddcaf..74136b54628 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -290,6 +290,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ExprKind::Let(..) | ExprKind::Loop(..) | ExprKind::Match(..) => {} + // Do not warn on `as` casts from never to any, + // they are sometimes required to appeal typeck. + ExprKind::Cast(_, _) => {} // If `expr` is a result of desugaring the try block and is an ok-wrapped // diverging expression (e.g. it arose from desugaring of `try { return }`), // we skip issuing a warning because it is autogenerated code. diff --git a/tests/ui/reachable/expr_cast.rs b/tests/ui/reachable/expr_cast.rs index 58ebe2a7b9f..aa412c99b2e 100644 --- a/tests/ui/reachable/expr_cast.rs +++ b/tests/ui/reachable/expr_cast.rs @@ -1,12 +1,21 @@ +//@ check-pass //@ edition: 2024 +// +// Check that we don't warn on `as` casts of never to any as unreachable. +// While they *are* unreachable, sometimes they are required to appeal typeck. #![deny(unreachable_code)] fn a() { - _ = {return} as u32; //~ error: unreachable + _ = {return} as u32; } fn b() { - (return) as u32; //~ error: unreachable + (return) as u32; +} + +// example that needs an explicit never-to-any `as` cast +fn example() -> impl Iterator { + todo!() as std::iter::Empty<_> } fn main() {} diff --git a/tests/ui/reachable/expr_cast.stderr b/tests/ui/reachable/expr_cast.stderr deleted file mode 100644 index cf711d4436e..00000000000 --- a/tests/ui/reachable/expr_cast.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: unreachable expression - --> $DIR/expr_cast.rs:5:9 - | -LL | _ = {return} as u32; - | ^------^^^^^^^^ - | || - | |any code following this expression is unreachable - | unreachable expression - | -note: the lint level is defined here - --> $DIR/expr_cast.rs:2:9 - | -LL | #![deny(unreachable_code)] - | ^^^^^^^^^^^^^^^^ - -error: unreachable expression - --> $DIR/expr_cast.rs:9:5 - | -LL | (return) as u32; - | --------^^^^^^^ - | | - | unreachable expression - | any code following this expression is unreachable - -error: aborting due to 2 previous errors - diff --git a/tests/ui/reachable/unreachable-try-pattern.rs b/tests/ui/reachable/unreachable-try-pattern.rs index 22cbfb95af0..1358722e229 100644 --- a/tests/ui/reachable/unreachable-try-pattern.rs +++ b/tests/ui/reachable/unreachable-try-pattern.rs @@ -18,7 +18,7 @@ fn bar(x: Result) -> Result { fn foo(x: Result) -> Result { let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?; //~^ WARN unreachable pattern - //~| WARN unreachable expression + //~| WARN unreachable call Ok(y) } diff --git a/tests/ui/reachable/unreachable-try-pattern.stderr b/tests/ui/reachable/unreachable-try-pattern.stderr index 40b11613105..468af427249 100644 --- a/tests/ui/reachable/unreachable-try-pattern.stderr +++ b/tests/ui/reachable/unreachable-try-pattern.stderr @@ -1,11 +1,10 @@ -warning: unreachable expression - --> $DIR/unreachable-try-pattern.rs:19:36 +warning: unreachable call + --> $DIR/unreachable-try-pattern.rs:19:33 | LL | let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?; - | -^^^^^^^ - | | - | unreachable expression - | any code following this expression is unreachable + | ^^ - any code following this expression is unreachable + | | + | unreachable call | note: the lint level is defined here --> $DIR/unreachable-try-pattern.rs:3:9