diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 90c451517c03f..b34c1e07be71c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::lint::builtin::BINDINGS_WITH_VARIANT_NAME; use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS}; use rustc_session::Session; -use rustc_span::Span; +use rustc_span::{DesugaringKind, ExpnKind, Span}; use std::slice; crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) { @@ -381,6 +381,10 @@ fn irrefutable_let_pattern(tcx: TyCtxt<'_>, id: HirId, span: Span) { } let source = let_source(tcx, id); + let span = match source { + LetSource::LetElse(span) => span, + _ => span, + }; tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, |lint| match source { LetSource::GenericLet => { emit_diag!(lint, "`let`", "`let` is useless", "removing `let`"); @@ -401,6 +405,14 @@ fn irrefutable_let_pattern(tcx: TyCtxt<'_>, id: HirId, span: Span) { "removing the guard and adding a `let` inside the match arm" ); } + LetSource::LetElse(..) => { + emit_diag!( + lint, + "`let...else`", + "`else` clause is useless", + "removing the `else` clause" + ); + } LetSource::WhileLet => { emit_diag!( lint, @@ -755,6 +767,7 @@ pub enum LetSource { GenericLet, IfLet, IfLetGuard, + LetElse(Span), WhileLet, } @@ -768,6 +781,12 @@ fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource { }) if hir_id == pat_id => { return LetSource::IfLetGuard; } + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Let(..), span, .. }) => { + let expn_data = span.ctxt().outer_expn_data(); + if let ExpnKind::Desugaring(DesugaringKind::LetElse) = expn_data.kind { + return LetSource::LetElse(expn_data.call_site); + } + } _ => {} } let parent_parent = hir.get_parent_node(parent); diff --git a/src/test/ui/pattern/usefulness/top-level-alternation.rs b/src/test/ui/pattern/usefulness/top-level-alternation.rs index 4b47b978930f3..076de846129e6 100644 --- a/src/test/ui/pattern/usefulness/top-level-alternation.rs +++ b/src/test/ui/pattern/usefulness/top-level-alternation.rs @@ -1,3 +1,5 @@ +#![feature(let_else)] + #![deny(unreachable_patterns)] fn main() { @@ -53,4 +55,5 @@ fn main() { 1..=2 => {}, //~ ERROR unreachable pattern _ => {}, } + let (0 | 0) = 0 else { return }; //~ ERROR unreachable pattern } diff --git a/src/test/ui/pattern/usefulness/top-level-alternation.stderr b/src/test/ui/pattern/usefulness/top-level-alternation.stderr index 76bc4f8d0910a..dd5936fdcc429 100644 --- a/src/test/ui/pattern/usefulness/top-level-alternation.stderr +++ b/src/test/ui/pattern/usefulness/top-level-alternation.stderr @@ -1,68 +1,74 @@ error: unreachable pattern - --> $DIR/top-level-alternation.rs:4:23 + --> $DIR/top-level-alternation.rs:6:23 | LL | while let 0..=2 | 1 = 0 {} | ^ | note: the lint level is defined here - --> $DIR/top-level-alternation.rs:1:9 + --> $DIR/top-level-alternation.rs:3:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:5:20 + --> $DIR/top-level-alternation.rs:7:20 | LL | if let 0..=2 | 1 = 0 {} | ^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:9:15 + --> $DIR/top-level-alternation.rs:11:15 | LL | | 0 => {} | ^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:14:15 + --> $DIR/top-level-alternation.rs:16:15 | LL | | Some(0) => {} | ^^^^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:19:9 + --> $DIR/top-level-alternation.rs:21:9 | LL | (0, 0) => {} | ^^^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:39:9 + --> $DIR/top-level-alternation.rs:41:9 | LL | _ => {} | ^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:43:9 + --> $DIR/top-level-alternation.rs:45:9 | LL | Some(_) => {} | ^^^^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:44:9 + --> $DIR/top-level-alternation.rs:46:9 | LL | None => {} | ^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:49:9 + --> $DIR/top-level-alternation.rs:51:9 | LL | None | Some(_) => {} | ^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:53:9 + --> $DIR/top-level-alternation.rs:55:9 | LL | 1..=2 => {}, | ^^^^^ -error: aborting due to 10 previous errors +error: unreachable pattern + --> $DIR/top-level-alternation.rs:58:14 + | +LL | let (0 | 0) = 0 else { return }; + | ^ + +error: aborting due to 11 previous errors