Skip to content

Commit 94ab407

Browse files
authored
Rollup merge of #79747 - camelid:irrefut-lint-link, r=varkor
Add explanations and suggestions to `irrefutable_let_patterns` lint Fixes #79716.
2 parents 0148b97 + 5d2a2a1 commit 94ab407

File tree

8 files changed

+83
-19
lines changed

8 files changed

+83
-19
lines changed

compiler/rustc_lint_defs/src/builtin.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1814,14 +1814,12 @@ declare_lint! {
18141814
}
18151815

18161816
declare_lint! {
1817-
/// The `irrefutable_let_patterns` lint detects detects [irrefutable
1818-
/// patterns] in [`if let`] and [`while let`] statements.
1819-
///
1820-
///
1817+
/// The `irrefutable_let_patterns` lint detects [irrefutable patterns]
1818+
/// in [`if let`]s, [`while let`]s, and `if let` guards.
18211819
///
18221820
/// ### Example
18231821
///
1824-
/// ```rust
1822+
/// ```
18251823
/// if let _ = 123 {
18261824
/// println!("always runs!");
18271825
/// }

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

+26-9
Original file line numberDiff line numberDiff line change
@@ -366,14 +366,31 @@ fn unreachable_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, catchall: Option<
366366
}
367367

368368
fn irrefutable_let_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, source: hir::MatchSource) {
369-
tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, |lint| {
370-
let msg = match source {
371-
hir::MatchSource::IfLetDesugar { .. } => "irrefutable `if let` pattern",
372-
hir::MatchSource::WhileLetDesugar => "irrefutable `while let` pattern",
373-
hir::MatchSource::IfLetGuardDesugar => "irrefutable `if let` guard",
374-
_ => bug!(),
375-
};
376-
lint.build(msg).emit()
369+
tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, |lint| match source {
370+
hir::MatchSource::IfLetDesugar { .. } => {
371+
let mut diag = lint.build("irrefutable `if let` pattern");
372+
diag.note("this pattern will always match, so the `if let` is useless");
373+
diag.help("consider replacing the `if let` with a `let`");
374+
diag.emit()
375+
}
376+
hir::MatchSource::WhileLetDesugar => {
377+
let mut diag = lint.build("irrefutable `while let` pattern");
378+
diag.note("this pattern will always match, so the loop will never exit");
379+
diag.help("consider instead using a `loop { ... }` with a `let` inside it");
380+
diag.emit()
381+
}
382+
hir::MatchSource::IfLetGuardDesugar => {
383+
let mut diag = lint.build("irrefutable `if let` guard pattern");
384+
diag.note("this pattern will always match, so the guard is useless");
385+
diag.help("consider removing the guard and adding a `let` inside the match arm");
386+
diag.emit()
387+
}
388+
_ => {
389+
bug!(
390+
"expected `if let`, `while let`, or `if let` guard HIR match source, found {:?}",
391+
source,
392+
)
393+
}
377394
});
378395
}
379396

@@ -387,7 +404,7 @@ fn check_if_let_guard<'p, 'tcx>(
387404
report_arm_reachability(&cx, &report, hir::MatchSource::IfLetGuardDesugar);
388405

389406
if report.non_exhaustiveness_witnesses.is_empty() {
390-
// The match is exhaustive, i.e. the if let pattern is irrefutable.
407+
// The match is exhaustive, i.e. the `if let` pattern is irrefutable.
391408
irrefutable_let_pattern(cx.tcx, pat.span, pat_id, hir::MatchSource::IfLetGuardDesugar)
392409
}
393410
}

src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ LL | | }
1717
| |_________^
1818
|
1919
= note: `#[warn(irrefutable_let_patterns)]` on by default
20+
= note: this pattern will always match, so the `if let` is useless
21+
= help: consider replacing the `if let` with a `let`
2022

2123
error[E0382]: use of moved value: `c`
2224
--> $DIR/closure-origin-single-variant-diagnostics.rs:25:13

src/test/ui/expr/if/if-let.stderr

+16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ LL | | });
1010
| |_______- in this macro invocation
1111
|
1212
= note: `#[warn(irrefutable_let_patterns)]` on by default
13+
= note: this pattern will always match, so the `if let` is useless
14+
= help: consider replacing the `if let` with a `let`
1315
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
1416

1517
warning: irrefutable `if let` pattern
@@ -23,6 +25,8 @@ LL | | println!("irrefutable pattern");
2325
LL | | });
2426
| |_______- in this macro invocation
2527
|
28+
= note: this pattern will always match, so the `if let` is useless
29+
= help: consider replacing the `if let` with a `let`
2630
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
2731

2832
warning: irrefutable `if let` pattern
@@ -32,6 +36,9 @@ LL | / if let a = 1 {
3236
LL | | println!("irrefutable pattern");
3337
LL | | }
3438
| |_____^
39+
|
40+
= note: this pattern will always match, so the `if let` is useless
41+
= help: consider replacing the `if let` with a `let`
3542

3643
warning: irrefutable `if let` pattern
3744
--> $DIR/if-let.rs:30:5
@@ -44,6 +51,9 @@ LL | | } else {
4451
LL | | println!("else in irrefutable `if let`");
4552
LL | | }
4653
| |_____^
54+
|
55+
= note: this pattern will always match, so the `if let` is useless
56+
= help: consider replacing the `if let` with a `let`
4757

4858
warning: irrefutable `if let` pattern
4959
--> $DIR/if-let.rs:40:12
@@ -53,6 +63,9 @@ LL | } else if let a = 1 {
5363
LL | | println!("irrefutable pattern");
5464
LL | | }
5565
| |_____^
66+
|
67+
= note: this pattern will always match, so the `if let` is useless
68+
= help: consider replacing the `if let` with a `let`
5669

5770
warning: irrefutable `if let` pattern
5871
--> $DIR/if-let.rs:46:12
@@ -62,6 +75,9 @@ LL | } else if let a = 1 {
6275
LL | | println!("irrefutable pattern");
6376
LL | | }
6477
| |_____^
78+
|
79+
= note: this pattern will always match, so the `if let` is useless
80+
= help: consider replacing the `if let` with a `let`
6581

6682
warning: 6 warnings emitted
6783

src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#![feature(if_let_guard)]
2+
#![allow(incomplete_features)]
3+
14
#![deny(irrefutable_let_patterns)]
25

36
fn main() {
@@ -6,4 +9,9 @@ fn main() {
69
while let _ = 5 { //~ ERROR irrefutable `while let` pattern
710
break;
811
}
12+
13+
match 5 {
14+
_ if let _ = 2 => {} //~ ERROR irrefutable `if let` guard pattern
15+
_ => {}
16+
}
917
}
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,36 @@
11
error: irrefutable `if let` pattern
2-
--> $DIR/deny-irrefutable-let-patterns.rs:4:5
2+
--> $DIR/deny-irrefutable-let-patterns.rs:7:5
33
|
44
LL | if let _ = 5 {}
55
| ^^^^^^^^^^^^^^^
66
|
77
note: the lint level is defined here
8-
--> $DIR/deny-irrefutable-let-patterns.rs:1:9
8+
--> $DIR/deny-irrefutable-let-patterns.rs:4:9
99
|
1010
LL | #![deny(irrefutable_let_patterns)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^
12+
= note: this pattern will always match, so the `if let` is useless
13+
= help: consider replacing the `if let` with a `let`
1214

1315
error: irrefutable `while let` pattern
14-
--> $DIR/deny-irrefutable-let-patterns.rs:6:5
16+
--> $DIR/deny-irrefutable-let-patterns.rs:9:5
1517
|
1618
LL | / while let _ = 5 {
1719
LL | | break;
1820
LL | | }
1921
| |_____^
22+
|
23+
= note: this pattern will always match, so the loop will never exit
24+
= help: consider instead using a `loop { ... }` with a `let` inside it
25+
26+
error: irrefutable `if let` guard pattern
27+
--> $DIR/deny-irrefutable-let-patterns.rs:14:18
28+
|
29+
LL | _ if let _ = 2 => {}
30+
| ^
31+
|
32+
= note: this pattern will always match, so the guard is useless
33+
= help: consider removing the guard and adding a `let` inside the match arm
2034

21-
error: aborting due to 2 previous errors
35+
error: aborting due to 3 previous errors
2236

src/test/ui/rfc-2294-if-let-guard/warns.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: irrefutable `if let` guard
1+
error: irrefutable `if let` guard pattern
22
--> $DIR/warns.rs:7:24
33
|
44
LL | Some(x) if let () = x => {}
@@ -9,6 +9,8 @@ note: the lint level is defined here
99
|
1010
LL | #[deny(irrefutable_let_patterns)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^
12+
= note: this pattern will always match, so the guard is useless
13+
= help: consider removing the guard and adding a `let` inside the match arm
1214

1315
error: unreachable pattern
1416
--> $DIR/warns.rs:16:25

src/test/ui/while-let.stderr

+7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ LL | | });
1010
| |_______- in this macro invocation
1111
|
1212
= note: `#[warn(irrefutable_let_patterns)]` on by default
13+
= note: this pattern will always match, so the loop will never exit
14+
= help: consider instead using a `loop { ... }` with a `let` inside it
1315
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
1416

1517
warning: irrefutable `while let` pattern
@@ -23,6 +25,8 @@ LL | | println!("irrefutable pattern");
2325
LL | | });
2426
| |_______- in this macro invocation
2527
|
28+
= note: this pattern will always match, so the loop will never exit
29+
= help: consider instead using a `loop { ... }` with a `let` inside it
2630
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
2731

2832
warning: irrefutable `while let` pattern
@@ -33,6 +37,9 @@ LL | | println!("irrefutable pattern");
3337
LL | | break;
3438
LL | | }
3539
| |_____^
40+
|
41+
= note: this pattern will always match, so the loop will never exit
42+
= help: consider instead using a `loop { ... }` with a `let` inside it
3643

3744
warning: 3 warnings emitted
3845

0 commit comments

Comments
 (0)