From 4f31ff893d4dd6125a445e3bda85c0fae623578c Mon Sep 17 00:00:00 2001 From: Hegui Dai Date: Sun, 2 Nov 2025 10:50:43 +0800 Subject: [PATCH] Not linting irrefutable_let_patterns on let chains inline rest of the check try fix ci errors inline in check_let --- compiler/rustc_mir_build/src/errors.rs | 46 ------ .../src/thir/pattern/check_match.rs | 91 ++---------- .../src/check_alignment.rs | 2 +- src/tools/miri/src/shims/foreign_items.rs | 2 +- tests/ui/binding/irrefutable-in-let-chains.rs | 120 ++++++++++++++++ .../binding/irrefutable-in-let-chains.stderr | 57 ++++++++ tests/ui/rfcs/rfc-2294-if-let-guard/warns.rs | 2 - .../rfcs/rfc-2294-if-let-guard/warns.stderr | 26 +--- .../irrefutable-lets.disallowed.stderr | 133 ------------------ .../irrefutable-lets.rs | 24 +--- 10 files changed, 196 insertions(+), 307 deletions(-) create mode 100644 tests/ui/binding/irrefutable-in-let-chains.rs create mode 100644 tests/ui/binding/irrefutable-in-let-chains.stderr delete mode 100644 tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 58ea9ec5aa22f..5a93c7cbdc7a9 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -874,52 +874,6 @@ pub(crate) struct UpperRangeBoundCannotBeMin { pub(crate) span: Span, } -#[derive(LintDiagnostic)] -#[diag( - "leading irrefutable {$count -> - [one] pattern - *[other] patterns -} in let chain" -)] -#[note( - "{$count -> - [one] this pattern - *[other] these patterns -} will always match" -)] -#[help( - "consider moving {$count -> - [one] it - *[other] them -} outside of the construct" -)] -pub(crate) struct LeadingIrrefutableLetPatterns { - pub(crate) count: usize, -} - -#[derive(LintDiagnostic)] -#[diag( - "trailing irrefutable {$count -> - [one] pattern - *[other] patterns -} in let chain" -)] -#[note( - "{$count -> - [one] this pattern - *[other] these patterns -} will always match" -)] -#[help( - "consider moving {$count -> - [one] it - *[other] them -} into the body" -)] -pub(crate) struct TrailingIrrefutableLetPatterns { - pub(crate) count: usize, -} - #[derive(LintDiagnostic)] #[diag("pattern binding `{$name}` is named the same as one of the variants of the type `{$ty_path}`", code = E0170)] pub(crate) struct BindingsWithVariantName { diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index e5b94ab763a19..9231b425c4c37 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -167,9 +167,9 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> { { let mut chain_refutabilities = Vec::new(); let Ok(()) = self.visit_land(ex, &mut chain_refutabilities) else { return }; - // If at least one of the operands is a `let ... = ...`. - if chain_refutabilities.iter().any(|x| x.is_some()) { - self.check_let_chain(chain_refutabilities, ex.span); + // Lint only single irrefutable let binding. + if let [Some((_, Irrefutable))] = chain_refutabilities[..] { + self.lint_single_let(ex.span); } return; } @@ -430,18 +430,9 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { assert!(self.let_source != LetSource::None); let scrut = scrutinee.map(|id| &self.thir[id]); if let LetSource::PlainLet = self.let_source { - self.check_binding_is_irrefutable(pat, "local binding", scrut, Some(span)) - } else { - let Ok(refutability) = self.is_let_irrefutable(pat, scrut) else { return }; - if matches!(refutability, Irrefutable) { - report_irrefutable_let_patterns( - self.tcx, - self.hir_source, - self.let_source, - 1, - span, - ); - } + self.check_binding_is_irrefutable(pat, "local binding", scrut, Some(span)); + } else if let Ok(Irrefutable) = self.is_let_irrefutable(pat, scrut) { + self.lint_single_let(span); } } @@ -549,74 +540,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { } #[instrument(level = "trace", skip(self))] - fn check_let_chain( - &mut self, - chain_refutabilities: Vec>, - whole_chain_span: Span, - ) { - assert!(self.let_source != LetSource::None); - - if chain_refutabilities.iter().all(|r| matches!(*r, Some((_, Irrefutable)))) { - // The entire chain is made up of irrefutable `let` statements - report_irrefutable_let_patterns( - self.tcx, - self.hir_source, - self.let_source, - chain_refutabilities.len(), - whole_chain_span, - ); - return; - } - - if let Some(until) = - chain_refutabilities.iter().position(|r| !matches!(*r, Some((_, Irrefutable)))) - && until > 0 - { - // The chain has a non-zero prefix of irrefutable `let` statements. - - // Check if the let source is while, for there is no alternative place to put a prefix, - // and we shouldn't lint. - // For let guards inside a match, prefixes might use bindings of the match pattern, - // so can't always be moved out. - // For `else if let`, an extra indentation level would be required to move the bindings. - // FIXME: Add checking whether the bindings are actually used in the prefix, - // and lint if they are not. - if !matches!( - self.let_source, - LetSource::WhileLet | LetSource::IfLetGuard | LetSource::ElseIfLet - ) { - // Emit the lint - let prefix = &chain_refutabilities[..until]; - let span_start = prefix[0].unwrap().0; - let span_end = prefix.last().unwrap().unwrap().0; - let span = span_start.to(span_end); - let count = prefix.len(); - self.tcx.emit_node_span_lint( - IRREFUTABLE_LET_PATTERNS, - self.hir_source, - span, - LeadingIrrefutableLetPatterns { count }, - ); - } - } - - if let Some(from) = - chain_refutabilities.iter().rposition(|r| !matches!(*r, Some((_, Irrefutable)))) - && from != (chain_refutabilities.len() - 1) - { - // The chain has a non-empty suffix of irrefutable `let` statements - let suffix = &chain_refutabilities[from + 1..]; - let span_start = suffix[0].unwrap().0; - let span_end = suffix.last().unwrap().unwrap().0; - let span = span_start.to(span_end); - let count = suffix.len(); - self.tcx.emit_node_span_lint( - IRREFUTABLE_LET_PATTERNS, - self.hir_source, - span, - TrailingIrrefutableLetPatterns { count }, - ); - } + fn lint_single_let(&mut self, let_span: Span) { + report_irrefutable_let_patterns(self.tcx, self.hir_source, self.let_source, 1, let_span); } fn analyze_binding( diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index e06883dd0fd10..5085905aa42b6 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -82,7 +82,7 @@ fn insert_alignment_check<'tcx>( // If this target does not have reliable alignment, further limit the mask by anding it with // the mask for the highest reliable alignment. - #[allow(irrefutable_let_patterns)] + #[cfg_attr(bootstrap, expect(irrefutable_let_patterns))] if let max_align = tcx.sess.target.max_reliable_alignment() && max_align < Align::MAX { diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 4c25caf56446a..12a170e6a849a 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -851,7 +851,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Fallback to shims in submodules. _ => { // Math shims - #[expect(irrefutable_let_patterns)] + #[cfg_attr(bootstrap, expect(irrefutable_let_patterns))] if let res = shims::math::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, )? && !matches!(res, EmulateItemResult::NotSupported) diff --git a/tests/ui/binding/irrefutable-in-let-chains.rs b/tests/ui/binding/irrefutable-in-let-chains.rs new file mode 100644 index 0000000000000..4bfeec184e905 --- /dev/null +++ b/tests/ui/binding/irrefutable-in-let-chains.rs @@ -0,0 +1,120 @@ +// https://github.com/rust-lang/rust/issues/139369 +// Test that the lint `irrefutable_let_patterns` now +// only checks single let binding. +//@ edition: 2024 +//@ check-pass + +use std::ops::Range; + +fn main() { + let opt = Some(None..Some(1)); + + // test `if let` + if let first = &opt {} + //~^ WARN irrefutable `if let` pattern + + if let first = &opt && let Some(second) = first {} + + if let first = &opt && let (a, b) = (1, 2) {} + + if let first = &opt && let None = Some(1) {} + + if 4 * 2 == 0 && let first = &opt {} + + if let first = &opt + && let Some(second) = first + && let None = second.start + && let v = 0 + {} + + if let Range { start: local_start, end: _ } = (None..Some(1)) {} + //~^ WARN irrefutable `if let` pattern + + if let Range { start: local_start, end: _ } = (None..Some(1)) + && let None = local_start + {} + + if let (a, b, c) = (Some(1), Some(1), Some(1)) {} + //~^ WARN irrefutable `if let` pattern + + if let (a, b, c) = (Some(1), Some(1), Some(1)) && let None = Some(1) {} + + if let Some(ref first) = opt + && let Range { start: local_start, end: _ } = first + && let None = local_start + {} + + // test `else if let` + if opt == Some(None..None) { + } else if let x = opt.clone().map(|_| 1) { + //~^ WARN irrefutable `if let` pattern + } + + if opt == Some(None..None) { + } else if let x = opt.clone().map(|_| 1) + && x == Some(1) + {} + + if opt == Some(None..None) { + } else if opt.is_some() && let x = &opt + {} + + if opt == Some(None..None) { + } else { + if let x = opt.clone().map(|_| 1) && x == Some(1) + {} + } + + // test `if let guard` + match opt { + Some(ref first) if let second = first => {} + //~^ WARN irrefutable `if let` guard pattern + _ => {} + } + + match opt { + Some(ref first) + if let second = first + && let _third = second + && let v = 4 + 4 => {} + _ => {} + } + + match opt { + Some(ref first) + if let Range { start: local_start, end: _ } = first + && let None = local_start => {} + _ => {} + } + + match opt { + Some(ref first) + if let Range { start: Some(_), end: local_end } = first + && let v = local_end + && let w = v => {} + _ => {} + } + + // test `while let` + while let first = &opt {} + //~^ WARN irrefutable `while let` pattern + + while let first = &opt + && let (a, b) = (1, 2) + {} + + while let first = &opt + && let Some(second) = first + && let None = second.start + {} + + while let Some(ref first) = opt + && let second = first + && let _third = second + {} + + while let Some(ref first) = opt + && let Range { start: local_start, end: _ } = first + && let None = local_start + {} +} diff --git a/tests/ui/binding/irrefutable-in-let-chains.stderr b/tests/ui/binding/irrefutable-in-let-chains.stderr new file mode 100644 index 0000000000000..4ff3c8b048ff6 --- /dev/null +++ b/tests/ui/binding/irrefutable-in-let-chains.stderr @@ -0,0 +1,57 @@ +warning: irrefutable `if let` pattern + --> $DIR/irrefutable-in-let-chains.rs:13:8 + | +LL | if let first = &opt {} + | ^^^^^^^^^^^^^^^^ + | + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` + = note: `#[warn(irrefutable_let_patterns)]` on by default + +warning: irrefutable `if let` pattern + --> $DIR/irrefutable-in-let-chains.rs:30:8 + | +LL | if let Range { start: local_start, end: _ } = (None..Some(1)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 + --> $DIR/irrefutable-in-let-chains.rs:37:8 + | +LL | if let (a, b, c) = (Some(1), Some(1), Some(1)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 + --> $DIR/irrefutable-in-let-chains.rs:49:15 + | +LL | } else if let x = opt.clone().map(|_| 1) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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` guard pattern + --> $DIR/irrefutable-in-let-chains.rs:70:28 + | +LL | Some(ref first) if let second = first => {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: this pattern will always match, so the guard is useless + = help: consider removing the guard and adding a `let` inside the match arm + +warning: irrefutable `while let` pattern + --> $DIR/irrefutable-in-let-chains.rs:99:11 + | +LL | while let first = &opt {} + | ^^^^^^^^^^^^^^^^ + | + = note: this pattern will always match, so the loop will never exit + = help: consider instead using a `loop { ... }` with a `let` inside it + +warning: 6 warnings emitted + diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/warns.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/warns.rs index da21c95dd2568..f37f848d289c4 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/warns.rs +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/warns.rs @@ -1,5 +1,4 @@ #[deny(irrefutable_let_patterns)] - fn irrefutable_let_guard() { match Some(()) { Some(x) if let () = x => {} @@ -21,7 +20,6 @@ fn trailing_irrefutable_pattern_binding() { fn trailing_irrefutable_in_let_chain() { match Some(5) { Some(x) if let Some(y) = Some(x) && let z = 0 => {} - //~^ ERROR trailing irrefutable pattern in let chain _ => {} } } diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr index f85bac0ddf5b1..871d0b72b1395 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr @@ -1,5 +1,5 @@ error: irrefutable `if let` guard pattern - --> $DIR/warns.rs:5:20 + --> $DIR/warns.rs:4:20 | LL | Some(x) if let () = x => {} | ^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | #[deny(irrefutable_let_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: irrefutable `if let` guard pattern - --> $DIR/warns.rs:14:14 + --> $DIR/warns.rs:13:14 | LL | o if let x = 0 => {} | ^^^^^^^^^ @@ -21,27 +21,13 @@ LL | o if let x = 0 => {} = note: this pattern will always match, so the guard is useless = help: consider removing the guard and adding a `let` inside the match arm note: the lint level is defined here - --> $DIR/warns.rs:11:8 - | -LL | #[deny(irrefutable_let_patterns)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error: trailing irrefutable pattern in let chain - --> $DIR/warns.rs:23:45 - | -LL | Some(x) if let Some(y) = Some(x) && let z = 0 => {} - | ^^^^^^^^^ - | - = note: this pattern will always match - = help: consider moving it into the body -note: the lint level is defined here - --> $DIR/warns.rs:20:8 + --> $DIR/warns.rs:10:8 | LL | #[deny(irrefutable_let_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/warns.rs:32:25 + --> $DIR/warns.rs:30:25 | LL | x if let None | None = x => {} | ---- ^^^^ no value can reach this @@ -49,10 +35,10 @@ LL | x if let None | None = x => {} | matches all the relevant values | note: the lint level is defined here - --> $DIR/warns.rs:29:8 + --> $DIR/warns.rs:27:8 | LL | #[deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr deleted file mode 100644 index 053a483882789..0000000000000 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr +++ /dev/null @@ -1,133 +0,0 @@ -error: leading irrefutable pattern in let chain - --> $DIR/irrefutable-lets.rs:13:8 - | -LL | if let first = &opt && let Some(second) = first && let None = second.start {} - | ^^^^^^^^^^^^^^^^ - | - = note: this pattern will always match - = help: consider moving it outside of the construct -note: the lint level is defined here - --> $DIR/irrefutable-lets.rs:6:30 - | -LL | #![cfg_attr(disallowed, deny(irrefutable_let_patterns))] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error: irrefutable `if let` patterns - --> $DIR/irrefutable-lets.rs:19:8 - | -LL | if let first = &opt && let (a, b) = (1, 2) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: these patterns will always match, so the `if let` is useless - = help: consider replacing the `if let` with a `let` - -error: leading irrefutable pattern in let chain - --> $DIR/irrefutable-lets.rs:22:8 - | -LL | if let first = &opt && let Some(second) = first && let None = second.start && let v = 0 {} - | ^^^^^^^^^^^^^^^^ - | - = note: this pattern will always match - = help: consider moving it outside of the construct - -error: trailing irrefutable pattern in let chain - --> $DIR/irrefutable-lets.rs:22:83 - | -LL | if let first = &opt && let Some(second) = first && let None = second.start && let v = 0 {} - | ^^^^^^^^^ - | - = note: this pattern will always match - = help: consider moving it into the body - -error: trailing irrefutable patterns in let chain - --> $DIR/irrefutable-lets.rs:26:37 - | -LL | if let Some(ref first) = opt && let second = first && let _third = second {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: these patterns will always match - = help: consider moving them into the body - -error: leading irrefutable pattern in let chain - --> $DIR/irrefutable-lets.rs:29:8 - | -LL | if let Range { start: local_start, end: _ } = (None..Some(1)) && let None = local_start {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this pattern will always match - = help: consider moving it outside of the construct - -error: leading irrefutable pattern in let chain - --> $DIR/irrefutable-lets.rs:32:8 - | -LL | if let (a, b, c) = (Some(1), Some(1), Some(1)) && let None = Some(1) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this pattern will always match - = help: consider moving it outside of the construct - -error: leading irrefutable pattern in let chain - --> $DIR/irrefutable-lets.rs:35:8 - | -LL | if let first = &opt && let None = Some(1) {} - | ^^^^^^^^^^^^^^^^ - | - = note: this pattern will always match - = help: consider moving it outside of the construct - -error: irrefutable `if let` guard patterns - --> $DIR/irrefutable-lets.rs:44:28 - | -LL | Some(ref first) if let second = first && let _third = second && let v = 4 + 4 => {}, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: these patterns will always match, so the guard is useless - = help: consider removing the guard and adding a `let` inside the match arm - -error: trailing irrefutable patterns in let chain - --> $DIR/irrefutable-lets.rs:59:16 - | -LL | && let v = local_end && let w = v => {}, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: these patterns will always match - = help: consider moving them into the body - -error: irrefutable `while let` patterns - --> $DIR/irrefutable-lets.rs:68:11 - | -LL | while let first = &opt && let (a, b) = (1, 2) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: these patterns will always match, so the loop will never exit - = help: consider instead using a `loop { ... }` with a `let` inside it - -error: trailing irrefutable patterns in let chain - --> $DIR/irrefutable-lets.rs:71:40 - | -LL | while let Some(ref first) = opt && let second = first && let _third = second {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: these patterns will always match - = help: consider moving them into the body - -error: trailing irrefutable pattern in let chain - --> $DIR/irrefutable-lets.rs:87:12 - | -LL | && let x = &opt - | ^^^^^^^^^^^^ - | - = note: this pattern will always match - = help: consider moving it into the body - -error: leading irrefutable pattern in let chain - --> $DIR/irrefutable-lets.rs:93:12 - | -LL | if let x = opt.clone().map(|_| 1) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this pattern will always match - = help: consider moving it outside of the construct - -error: aborting due to 14 previous errors - diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.rs index a5088a8d37503..79876a1a618f2 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.rs +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.rs @@ -1,39 +1,27 @@ -//@ revisions: allowed disallowed -//@[allowed] check-pass +//@ check-pass //@ edition: 2024 -#![cfg_attr(allowed, allow(irrefutable_let_patterns))] -#![cfg_attr(disallowed, deny(irrefutable_let_patterns))] - use std::ops::Range; fn main() { let opt = Some(None..Some(1)); if let first = &opt && let Some(second) = first && let None = second.start {} - //[disallowed]~^ ERROR leading irrefutable pattern in let chain // No lint as the irrefutable pattern is surrounded by other stuff if 4 * 2 == 0 && let first = &opt && let Some(second) = first && let None = second.start {} if let first = &opt && let (a, b) = (1, 2) {} - //[disallowed]~^ ERROR irrefutable `if let` patterns if let first = &opt && let Some(second) = first && let None = second.start && let v = 0 {} - //[disallowed]~^ ERROR leading irrefutable pattern in let chain - //[disallowed]~^^ ERROR trailing irrefutable pattern in let chain if let Some(ref first) = opt && let second = first && let _third = second {} - //[disallowed]~^ ERROR trailing irrefutable patterns in let chain if let Range { start: local_start, end: _ } = (None..Some(1)) && let None = local_start {} - //[disallowed]~^ ERROR leading irrefutable pattern in let chain if let (a, b, c) = (Some(1), Some(1), Some(1)) && let None = Some(1) {} - //[disallowed]~^ ERROR leading irrefutable pattern in let chain if let first = &opt && let None = Some(1) {} - //[disallowed]~^ ERROR leading irrefutable pattern in let chain if let Some(ref first) = opt && let Range { start: local_start, end: _ } = first @@ -42,7 +30,6 @@ fn main() { match opt { Some(ref first) if let second = first && let _third = second && let v = 4 + 4 => {}, - //[disallowed]~^ ERROR irrefutable `if let` guard patterns _ => {} } @@ -57,7 +44,6 @@ fn main() { match opt { Some(ref first) if let Range { start: Some(_), end: local_end } = first && let v = local_end && let w = v => {}, - //[disallowed]~^ ERROR trailing irrefutable patterns in let chain _ => {} } @@ -66,15 +52,13 @@ fn main() { while let first = &opt && let Some(second) = first && let None = second.start {} while let first = &opt && let (a, b) = (1, 2) {} - //[disallowed]~^ ERROR irrefutable `while let` patterns while let Some(ref first) = opt && let second = first && let _third = second {} - //[disallowed]~^ ERROR trailing irrefutable patterns in let chain while let Some(ref first) = opt && let Range { start: local_start, end: _ } = first - && let None = local_start { - } + && let None = local_start + {} // No error. An extra nesting level would be required for the `else if`. if opt == Some(None..None) { @@ -85,13 +69,11 @@ fn main() { if opt == Some(None..None) { } else if opt.is_some() && let x = &opt - //[disallowed]~^ ERROR trailing irrefutable pattern in let chain {} if opt == Some(None..None) { } else { if let x = opt.clone().map(|_| 1) - //[disallowed]~^ ERROR leading irrefutable pattern in let chain && x == Some(1) {} }