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:
commit
94ab4078da
8 changed files with 83 additions and 19 deletions
|
@ -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!");
|
||||||
/// }
|
/// }
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue