1
Fork 0

Rollup merge of #79747 - camelid:irrefut-lint-link, r=varkor

Add explanations and suggestions to `irrefutable_let_patterns` lint

Fixes #79716.
This commit is contained in:
Dylan DPC 2021-02-19 02:48:59 +01:00 committed by GitHub
commit 94ab4078da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 83 additions and 19 deletions

View file

@ -1814,14 +1814,12 @@ declare_lint! {
} }
declare_lint! { declare_lint! {
/// The `irrefutable_let_patterns` lint detects detects [irrefutable /// The `irrefutable_let_patterns` lint detects [irrefutable patterns]
/// patterns] in [`if let`] and [`while let`] statements. /// in [`if let`]s, [`while let`]s, and `if let` guards.
///
///
/// ///
/// ### Example /// ### Example
/// ///
/// ```rust /// ```
/// if let _ = 123 { /// if let _ = 123 {
/// println!("always runs!"); /// println!("always runs!");
/// } /// }

View file

@ -366,14 +366,31 @@ fn unreachable_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, catchall: Option<
} }
fn irrefutable_let_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, source: hir::MatchSource) { fn irrefutable_let_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, source: hir::MatchSource) {
tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, |lint| { tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, |lint| match source {
let msg = match source { hir::MatchSource::IfLetDesugar { .. } => {
hir::MatchSource::IfLetDesugar { .. } => "irrefutable `if let` pattern", let mut diag = lint.build("irrefutable `if let` pattern");
hir::MatchSource::WhileLetDesugar => "irrefutable `while let` pattern", diag.note("this pattern will always match, so the `if let` is useless");
hir::MatchSource::IfLetGuardDesugar => "irrefutable `if let` guard", diag.help("consider replacing the `if let` with a `let`");
_ => bug!(), diag.emit()
}; }
lint.build(msg).emit() hir::MatchSource::WhileLetDesugar => {
let mut diag = lint.build("irrefutable `while let` pattern");
diag.note("this pattern will always match, so the loop will never exit");
diag.help("consider instead using a `loop { ... }` with a `let` inside it");
diag.emit()
}
hir::MatchSource::IfLetGuardDesugar => {
let mut diag = lint.build("irrefutable `if let` guard pattern");
diag.note("this pattern will always match, so the guard is useless");
diag.help("consider removing the guard and adding a `let` inside the match arm");
diag.emit()
}
_ => {
bug!(
"expected `if let`, `while let`, or `if let` guard HIR match source, found {:?}",
source,
)
}
}); });
} }
@ -387,7 +404,7 @@ fn check_if_let_guard<'p, 'tcx>(
report_arm_reachability(&cx, &report, hir::MatchSource::IfLetGuardDesugar); report_arm_reachability(&cx, &report, hir::MatchSource::IfLetGuardDesugar);
if report.non_exhaustiveness_witnesses.is_empty() { if report.non_exhaustiveness_witnesses.is_empty() {
// The match is exhaustive, i.e. the if let pattern is irrefutable. // The match is exhaustive, i.e. the `if let` pattern is irrefutable.
irrefutable_let_pattern(cx.tcx, pat.span, pat_id, hir::MatchSource::IfLetGuardDesugar) irrefutable_let_pattern(cx.tcx, pat.span, pat_id, hir::MatchSource::IfLetGuardDesugar)
} }
} }

View file

@ -17,6 +17,8 @@ LL | | }
| |_________^ | |_________^
| |
= note: `#[warn(irrefutable_let_patterns)]` on by default = note: `#[warn(irrefutable_let_patterns)]` on by default
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
error[E0382]: use of moved value: `c` error[E0382]: use of moved value: `c`
--> $DIR/closure-origin-single-variant-diagnostics.rs:25:13 --> $DIR/closure-origin-single-variant-diagnostics.rs:25:13

View file

@ -10,6 +10,8 @@ LL | | });
| |_______- in this macro invocation | |_______- in this macro invocation
| |
= note: `#[warn(irrefutable_let_patterns)]` on by default = note: `#[warn(irrefutable_let_patterns)]` on by default
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: irrefutable `if let` pattern warning: irrefutable `if let` pattern
@ -23,6 +25,8 @@ LL | | println!("irrefutable pattern");
LL | | }); LL | | });
| |_______- in this macro invocation | |_______- in this macro invocation
| |
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: irrefutable `if let` pattern warning: irrefutable `if let` pattern
@ -32,6 +36,9 @@ LL | / if let a = 1 {
LL | | println!("irrefutable pattern"); LL | | println!("irrefutable pattern");
LL | | } LL | | }
| |_____^ | |_____^
|
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
warning: irrefutable `if let` pattern warning: irrefutable `if let` pattern
--> $DIR/if-let.rs:30:5 --> $DIR/if-let.rs:30:5
@ -44,6 +51,9 @@ LL | | } else {
LL | | println!("else in irrefutable `if let`"); LL | | println!("else in irrefutable `if let`");
LL | | } LL | | }
| |_____^ | |_____^
|
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
warning: irrefutable `if let` pattern warning: irrefutable `if let` pattern
--> $DIR/if-let.rs:40:12 --> $DIR/if-let.rs:40:12
@ -53,6 +63,9 @@ LL | } else if let a = 1 {
LL | | println!("irrefutable pattern"); LL | | println!("irrefutable pattern");
LL | | } LL | | }
| |_____^ | |_____^
|
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
warning: irrefutable `if let` pattern warning: irrefutable `if let` pattern
--> $DIR/if-let.rs:46:12 --> $DIR/if-let.rs:46:12
@ -62,6 +75,9 @@ LL | } else if let a = 1 {
LL | | println!("irrefutable pattern"); LL | | println!("irrefutable pattern");
LL | | } LL | | }
| |_____^ | |_____^
|
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
warning: 6 warnings emitted warning: 6 warnings emitted

View file

@ -1,3 +1,6 @@
#![feature(if_let_guard)]
#![allow(incomplete_features)]
#![deny(irrefutable_let_patterns)] #![deny(irrefutable_let_patterns)]
fn main() { fn main() {
@ -6,4 +9,9 @@ fn main() {
while let _ = 5 { //~ ERROR irrefutable `while let` pattern while let _ = 5 { //~ ERROR irrefutable `while let` pattern
break; break;
} }
match 5 {
_ if let _ = 2 => {} //~ ERROR irrefutable `if let` guard pattern
_ => {}
}
} }

View file

@ -1,22 +1,36 @@
error: irrefutable `if let` pattern error: irrefutable `if let` pattern
--> $DIR/deny-irrefutable-let-patterns.rs:4:5 --> $DIR/deny-irrefutable-let-patterns.rs:7:5
| |
LL | if let _ = 5 {} LL | if let _ = 5 {}
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/deny-irrefutable-let-patterns.rs:1:9 --> $DIR/deny-irrefutable-let-patterns.rs:4:9
| |
LL | #![deny(irrefutable_let_patterns)] LL | #![deny(irrefutable_let_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
error: irrefutable `while let` pattern error: irrefutable `while let` pattern
--> $DIR/deny-irrefutable-let-patterns.rs:6:5 --> $DIR/deny-irrefutable-let-patterns.rs:9:5
| |
LL | / while let _ = 5 { LL | / while let _ = 5 {
LL | | break; LL | | break;
LL | | } LL | | }
| |_____^ | |_____^
|
= note: this pattern will always match, so the loop will never exit
= help: consider instead using a `loop { ... }` with a `let` inside it
error: aborting due to 2 previous errors error: irrefutable `if let` guard pattern
--> $DIR/deny-irrefutable-let-patterns.rs:14:18
|
LL | _ if let _ = 2 => {}
| ^
|
= note: this pattern will always match, so the guard is useless
= help: consider removing the guard and adding a `let` inside the match arm
error: aborting due to 3 previous errors

View file

@ -1,4 +1,4 @@
error: irrefutable `if let` guard error: irrefutable `if let` guard pattern
--> $DIR/warns.rs:7:24 --> $DIR/warns.rs:7:24
| |
LL | Some(x) if let () = x => {} LL | Some(x) if let () = x => {}
@ -9,6 +9,8 @@ note: the lint level is defined here
| |
LL | #[deny(irrefutable_let_patterns)] LL | #[deny(irrefutable_let_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
= note: this pattern will always match, so the guard is useless
= help: consider removing the guard and adding a `let` inside the match arm
error: unreachable pattern error: unreachable pattern
--> $DIR/warns.rs:16:25 --> $DIR/warns.rs:16:25

View file

@ -10,6 +10,8 @@ LL | | });
| |_______- in this macro invocation | |_______- in this macro invocation
| |
= note: `#[warn(irrefutable_let_patterns)]` on by default = note: `#[warn(irrefutable_let_patterns)]` on by default
= note: this pattern will always match, so the loop will never exit
= help: consider instead using a `loop { ... }` with a `let` inside it
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: irrefutable `while let` pattern warning: irrefutable `while let` pattern
@ -23,6 +25,8 @@ LL | | println!("irrefutable pattern");
LL | | }); LL | | });
| |_______- in this macro invocation | |_______- in this macro invocation
| |
= note: this pattern will always match, so the loop will never exit
= help: consider instead using a `loop { ... }` with a `let` inside it
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: irrefutable `while let` pattern warning: irrefutable `while let` pattern
@ -33,6 +37,9 @@ LL | | println!("irrefutable pattern");
LL | | break; LL | | break;
LL | | } LL | | }
| |_____^ | |_____^
|
= note: this pattern will always match, so the loop will never exit
= help: consider instead using a `loop { ... }` with a `let` inside it
warning: 3 warnings emitted warning: 3 warnings emitted