Skip to content

Commit ce66065

Browse files
Not linting irrefutable_let_patterns on let chains
1 parent 9f2ef0f commit ce66065

File tree

5 files changed

+60
-153
lines changed

5 files changed

+60
-153
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,11 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
569569
) {
570570
assert!(self.let_source != LetSource::None);
571571

572+
// for let chains, don't emit IRREFUTABLE_LET_PATTERNS
573+
if chain_refutabilities.len() > 1 {
574+
return;
575+
}
576+
572577
if chain_refutabilities.iter().all(|r| matches!(*r, Some((_, Irrefutable)))) {
573578
// The entire chain is made up of irrefutable `let` statements
574579
report_irrefutable_let_patterns(

src/tools/miri/src/shims/foreign_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
900900
// Fallback to shims in submodules.
901901
_ => {
902902
// Math shims
903-
#[expect(irrefutable_let_patterns)]
903+
#[allow(irrefutable_let_patterns)]
904904
if let res = shims::math::EvalContextExt::emulate_foreign_item_inner(
905905
this, link_name, abi, args, dest,
906906
)? && !matches!(res, EmulateItemResult::NotSupported)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//@ run-pass
2+
//@ edition:2024
3+
4+
#![allow(unused)]
5+
6+
enum Outer {
7+
Middle(Middle),
8+
}
9+
enum Middle {
10+
Inner(Inner),
11+
Other(bool),
12+
}
13+
struct Inner {
14+
id: u32,
15+
}
16+
17+
fn test_1(outer: Outer) {
18+
if let Outer::Middle(middle) = outer
19+
&& let Middle::Inner(internal) = middle
20+
&& let Inner { id } = internal
21+
{
22+
println!("{id}");
23+
}
24+
}
25+
26+
fn test_2() -> usize { 42 }
27+
28+
fn test_3() -> Outer {
29+
Outer::Middle(Middle::Inner(Inner { id: 1 }))
30+
}
31+
32+
fn main() {
33+
if let mx = test_2() && mx < usize::MAX {
34+
println!("{mx}");
35+
} else if let x = test_2() && x > 0 {
36+
println!("{x}");
37+
}
38+
39+
while let Outer::Middle(middle) = test_3()
40+
&& let Middle::Inner(inner) = middle
41+
&& let Inner { id } = inner
42+
&& id > 5
43+
{
44+
println!("{id}");
45+
}
46+
}

tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr

Lines changed: 0 additions & 133 deletions
This file was deleted.

tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.rs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,33 @@
11
//@ revisions: allowed disallowed
2-
//@[allowed] check-pass
2+
//@ run-pass
33
//@ edition: 2024
44

55
#![feature(if_let_guard)]
66
#![cfg_attr(allowed, allow(irrefutable_let_patterns))]
77
#![cfg_attr(disallowed, deny(irrefutable_let_patterns))]
8+
#![allow(unused)]
89

910
use std::ops::Range;
1011

1112
fn main() {
1213
let opt = Some(None..Some(1));
1314

1415
if let first = &opt && let Some(second) = first && let None = second.start {}
15-
//[disallowed]~^ ERROR leading irrefutable pattern in let chain
1616

1717
// No lint as the irrefutable pattern is surrounded by other stuff
1818
if 4 * 2 == 0 && let first = &opt && let Some(second) = first && let None = second.start {}
1919

2020
if let first = &opt && let (a, b) = (1, 2) {}
21-
//[disallowed]~^ ERROR irrefutable `if let` patterns
2221

2322
if let first = &opt && let Some(second) = first && let None = second.start && let v = 0 {}
24-
//[disallowed]~^ ERROR leading irrefutable pattern in let chain
25-
//[disallowed]~^^ ERROR trailing irrefutable pattern in let chain
2623

2724
if let Some(ref first) = opt && let second = first && let _third = second {}
28-
//[disallowed]~^ ERROR trailing irrefutable patterns in let chain
2925

3026
if let Range { start: local_start, end: _ } = (None..Some(1)) && let None = local_start {}
31-
//[disallowed]~^ ERROR leading irrefutable pattern in let chain
3227

3328
if let (a, b, c) = (Some(1), Some(1), Some(1)) && let None = Some(1) {}
34-
//[disallowed]~^ ERROR leading irrefutable pattern in let chain
3529

3630
if let first = &opt && let None = Some(1) {}
37-
//[disallowed]~^ ERROR leading irrefutable pattern in let chain
3831

3932
if let Some(ref first) = opt
4033
&& let Range { start: local_start, end: _ } = first
@@ -43,7 +36,6 @@ fn main() {
4336

4437
match opt {
4538
Some(ref first) if let second = first && let _third = second && let v = 4 + 4 => {},
46-
//[disallowed]~^ ERROR irrefutable `if let` guard patterns
4739
_ => {}
4840
}
4941

@@ -58,23 +50,22 @@ fn main() {
5850
match opt {
5951
Some(ref first) if let Range { start: Some(_), end: local_end } = first
6052
&& let v = local_end && let w = v => {},
61-
//[disallowed]~^ ERROR trailing irrefutable patterns in let chain
6253
_ => {}
6354
}
6455

6556
// No error, despite the prefix being irrefutable: moving out could change the behaviour,
6657
// due to possible side effects of the operation.
67-
while let first = &opt && let Some(second) = first && let None = second.start {}
58+
while let first = &opt && let Some(second) = first && let None = second.start { break; }
6859

69-
while let first = &opt && let (a, b) = (1, 2) {}
70-
//[disallowed]~^ ERROR irrefutable `while let` patterns
60+
while let first = &opt && let (a, b) = (1, 2) { break; }
7161

72-
while let Some(ref first) = opt && let second = first && let _third = second {}
73-
//[disallowed]~^ ERROR trailing irrefutable patterns in let chain
62+
while let Some(ref first) = opt && let second = first && let _third = second { break; }
7463

7564
while let Some(ref first) = opt
7665
&& let Range { start: local_start, end: _ } = first
77-
&& let None = local_start {
66+
&& let None = local_start
67+
{
68+
break;
7869
}
7970

8071
// No error. An extra nesting level would be required for the `else if`.
@@ -86,13 +77,11 @@ fn main() {
8677
if opt == Some(None..None) {
8778
} else if opt.is_some()
8879
&& let x = &opt
89-
//[disallowed]~^ ERROR trailing irrefutable pattern in let chain
9080
{}
9181

9282
if opt == Some(None..None) {
9383
} else {
9484
if let x = opt.clone().map(|_| 1)
95-
//[disallowed]~^ ERROR leading irrefutable pattern in let chain
9685
&& x == Some(1)
9786
{}
9887
}

0 commit comments

Comments
 (0)