Skip to content

Commit

Permalink
Handle irrufutable or unreachable let-else
Browse files Browse the repository at this point in the history
  • Loading branch information
camsteffen committed Aug 31, 2021
1 parent dc028f6 commit df9a2e0
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 13 deletions.
21 changes: 20 additions & 1 deletion compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Expand Up @@ -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) {
Expand Down Expand Up @@ -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`");
Expand All @@ -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,
Expand Down Expand Up @@ -755,6 +767,7 @@ pub enum LetSource {
GenericLet,
IfLet,
IfLetGuard,
LetElse(Span),
WhileLet,
}

Expand All @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions src/test/ui/pattern/usefulness/top-level-alternation.rs
@@ -1,3 +1,5 @@
#![feature(let_else)]

#![deny(unreachable_patterns)]

fn main() {
Expand Down Expand Up @@ -53,4 +55,5 @@ fn main() {
1..=2 => {}, //~ ERROR unreachable pattern
_ => {},
}
let (0 | 0) = 0 else { return }; //~ ERROR unreachable pattern
}
30 changes: 18 additions & 12 deletions 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

0 comments on commit df9a2e0

Please sign in to comment.