Skip to content

Commit df9a2e0

Browse files
committed
Handle irrufutable or unreachable let-else
1 parent dc028f6 commit df9a2e0

File tree

3 files changed

+41
-13
lines changed

3 files changed

+41
-13
lines changed

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
1717
use rustc_session::lint::builtin::BINDINGS_WITH_VARIANT_NAME;
1818
use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS};
1919
use rustc_session::Session;
20-
use rustc_span::Span;
20+
use rustc_span::{DesugaringKind, ExpnKind, Span};
2121
use std::slice;
2222

2323
crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
@@ -381,6 +381,10 @@ fn irrefutable_let_pattern(tcx: TyCtxt<'_>, id: HirId, span: Span) {
381381
}
382382

383383
let source = let_source(tcx, id);
384+
let span = match source {
385+
LetSource::LetElse(span) => span,
386+
_ => span,
387+
};
384388
tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, |lint| match source {
385389
LetSource::GenericLet => {
386390
emit_diag!(lint, "`let`", "`let` is useless", "removing `let`");
@@ -401,6 +405,14 @@ fn irrefutable_let_pattern(tcx: TyCtxt<'_>, id: HirId, span: Span) {
401405
"removing the guard and adding a `let` inside the match arm"
402406
);
403407
}
408+
LetSource::LetElse(..) => {
409+
emit_diag!(
410+
lint,
411+
"`let...else`",
412+
"`else` clause is useless",
413+
"removing the `else` clause"
414+
);
415+
}
404416
LetSource::WhileLet => {
405417
emit_diag!(
406418
lint,
@@ -755,6 +767,7 @@ pub enum LetSource {
755767
GenericLet,
756768
IfLet,
757769
IfLetGuard,
770+
LetElse(Span),
758771
WhileLet,
759772
}
760773

@@ -768,6 +781,12 @@ fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource {
768781
}) if hir_id == pat_id => {
769782
return LetSource::IfLetGuard;
770783
}
784+
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Let(..), span, .. }) => {
785+
let expn_data = span.ctxt().outer_expn_data();
786+
if let ExpnKind::Desugaring(DesugaringKind::LetElse) = expn_data.kind {
787+
return LetSource::LetElse(expn_data.call_site);
788+
}
789+
}
771790
_ => {}
772791
}
773792
let parent_parent = hir.get_parent_node(parent);

src/test/ui/pattern/usefulness/top-level-alternation.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![feature(let_else)]
2+
13
#![deny(unreachable_patterns)]
24

35
fn main() {
@@ -53,4 +55,5 @@ fn main() {
5355
1..=2 => {}, //~ ERROR unreachable pattern
5456
_ => {},
5557
}
58+
let (0 | 0) = 0 else { return }; //~ ERROR unreachable pattern
5659
}
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,74 @@
11
error: unreachable pattern
2-
--> $DIR/top-level-alternation.rs:4:23
2+
--> $DIR/top-level-alternation.rs:6:23
33
|
44
LL | while let 0..=2 | 1 = 0 {}
55
| ^
66
|
77
note: the lint level is defined here
8-
--> $DIR/top-level-alternation.rs:1:9
8+
--> $DIR/top-level-alternation.rs:3:9
99
|
1010
LL | #![deny(unreachable_patterns)]
1111
| ^^^^^^^^^^^^^^^^^^^^
1212

1313
error: unreachable pattern
14-
--> $DIR/top-level-alternation.rs:5:20
14+
--> $DIR/top-level-alternation.rs:7:20
1515
|
1616
LL | if let 0..=2 | 1 = 0 {}
1717
| ^
1818

1919
error: unreachable pattern
20-
--> $DIR/top-level-alternation.rs:9:15
20+
--> $DIR/top-level-alternation.rs:11:15
2121
|
2222
LL | | 0 => {}
2323
| ^
2424

2525
error: unreachable pattern
26-
--> $DIR/top-level-alternation.rs:14:15
26+
--> $DIR/top-level-alternation.rs:16:15
2727
|
2828
LL | | Some(0) => {}
2929
| ^^^^^^^
3030

3131
error: unreachable pattern
32-
--> $DIR/top-level-alternation.rs:19:9
32+
--> $DIR/top-level-alternation.rs:21:9
3333
|
3434
LL | (0, 0) => {}
3535
| ^^^^^^
3636

3737
error: unreachable pattern
38-
--> $DIR/top-level-alternation.rs:39:9
38+
--> $DIR/top-level-alternation.rs:41:9
3939
|
4040
LL | _ => {}
4141
| ^
4242

4343
error: unreachable pattern
44-
--> $DIR/top-level-alternation.rs:43:9
44+
--> $DIR/top-level-alternation.rs:45:9
4545
|
4646
LL | Some(_) => {}
4747
| ^^^^^^^
4848

4949
error: unreachable pattern
50-
--> $DIR/top-level-alternation.rs:44:9
50+
--> $DIR/top-level-alternation.rs:46:9
5151
|
5252
LL | None => {}
5353
| ^^^^
5454

5555
error: unreachable pattern
56-
--> $DIR/top-level-alternation.rs:49:9
56+
--> $DIR/top-level-alternation.rs:51:9
5757
|
5858
LL | None | Some(_) => {}
5959
| ^^^^^^^^^^^^^^
6060

6161
error: unreachable pattern
62-
--> $DIR/top-level-alternation.rs:53:9
62+
--> $DIR/top-level-alternation.rs:55:9
6363
|
6464
LL | 1..=2 => {},
6565
| ^^^^^
6666

67-
error: aborting due to 10 previous errors
67+
error: unreachable pattern
68+
--> $DIR/top-level-alternation.rs:58:14
69+
|
70+
LL | let (0 | 0) = 0 else { return };
71+
| ^
72+
73+
error: aborting due to 11 previous errors
6874

0 commit comments

Comments
 (0)