fix: unnested_or_patterns FP on structs with only shorthand field pats

This commit is contained in:
Ada Alakbarova
2025-07-25 08:50:20 +02:00
parent 877967959a
commit 0d479c19e8
4 changed files with 80 additions and 30 deletions
+5 -1
View File
@@ -326,7 +326,11 @@ fn extend_with_struct_pat(
if idx_1 == idx {
// In the case of `k`, we merely require identical field names
// so that we will transform into `ident_k: p1_k | p2_k`.
let pos = fps2.iter().position(|fp2| eq_id(fp1.ident, fp2.ident));
let pos = fps2.iter().position(|fp2| {
// Avoid `Foo { bar } | Foo { bar }` => `Foo { bar | bar }`
!(fp1.is_shorthand && fp2.is_shorthand)
&& eq_id(fp1.ident, fp2.ident)
});
pos_in_2.set(pos);
pos.is_some()
} else {
+21 -4
View File
@@ -9,6 +9,11 @@
)]
#![allow(unreachable_patterns, irrefutable_let_patterns, unused)]
struct S {
x: u8,
y: u8,
}
fn main() {
// Should be ignored by this lint, as nesting requires more characters.
if let &0 | &2 = &0 {}
@@ -45,10 +50,6 @@ fn main() {
//~^ unnested_or_patterns
if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}
//~^ unnested_or_patterns
struct S {
x: u8,
y: u8,
}
if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}
//~^ unnested_or_patterns
if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
@@ -77,3 +78,19 @@ mod issue9952 {
fn or_in_param((x | x | x): i32) {}
//~^ unnested_or_patterns
}
fn issue15219() {
struct Foo {
x: u8,
}
// the original repro
if let Foo { x } | Foo { x } = (Foo { x: 0 }) {}
// also works with more fields
if let S { x, y } | S { x, y } = (S { x: 0, y: 0 }) {}
// `y` not triggering the lint doesn't stop the `x` from getting flagged
if let S { y, x: 0 | 1 } = (S { x: 0, y: 1 }) {}
//~^ unnested_or_patterns
}
+21 -4
View File
@@ -9,6 +9,11 @@
)]
#![allow(unreachable_patterns, irrefutable_let_patterns, unused)]
struct S {
x: u8,
y: u8,
}
fn main() {
// Should be ignored by this lint, as nesting requires more characters.
if let &0 | &2 = &0 {}
@@ -45,10 +50,6 @@ fn main() {
//~^ unnested_or_patterns
if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}
//~^ unnested_or_patterns
struct S {
x: u8,
y: u8,
}
if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
//~^ unnested_or_patterns
if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
@@ -77,3 +78,19 @@ fn or_in_local() {
fn or_in_param((x | (x | x)): i32) {}
//~^ unnested_or_patterns
}
fn issue15219() {
struct Foo {
x: u8,
}
// the original repro
if let Foo { x } | Foo { x } = (Foo { x: 0 }) {}
// also works with more fields
if let S { x, y } | S { x, y } = (S { x: 0, y: 0 }) {}
// `y` not triggering the lint doesn't stop the `x` from getting flagged
if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
//~^ unnested_or_patterns
}
+33 -21
View File
@@ -1,5 +1,5 @@
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:16:12
--> tests/ui/unnested_or_patterns.rs:21:12
|
LL | if let box 0 | box 2 = Box::new(0) {}
| ^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL + if let box (0 | 2) = Box::new(0) {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:18:12
--> tests/ui/unnested_or_patterns.rs:23:12
|
LL | if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL + if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:21:12
--> tests/ui/unnested_or_patterns.rs:26:12
|
LL | if let Some(1) | C0 | Some(2) = None {}
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL + if let Some(1 | 2) | C0 = None {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:23:12
--> tests/ui/unnested_or_patterns.rs:28:12
|
LL | if let &mut 0 | &mut 2 = &mut 0 {}
| ^^^^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL + if let &mut (0 | 2) = &mut 0 {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:25:12
--> tests/ui/unnested_or_patterns.rs:30:12
|
LL | if let x @ 0 | x @ 2 = 0 {}
| ^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL + if let x @ (0 | 2) = 0 {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:27:12
--> tests/ui/unnested_or_patterns.rs:32:12
|
LL | if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL + if let (0, 1 | 2 | 3) = (0, 0) {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:29:12
--> tests/ui/unnested_or_patterns.rs:34:12
|
LL | if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -85,7 +85,7 @@ LL + if let (1 | 2 | 3, 0) = (0, 0) {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:31:12
--> tests/ui/unnested_or_patterns.rs:36:12
|
LL | if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -97,7 +97,7 @@ LL + if let (x, ..) | (x, 1 | 2) = (0, 1) {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:33:12
--> tests/ui/unnested_or_patterns.rs:38:12
|
LL | if let [0] | [1] = [0] {}
| ^^^^^^^^^
@@ -109,7 +109,7 @@ LL + if let [0 | 1] = [0] {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:35:12
--> tests/ui/unnested_or_patterns.rs:40:12
|
LL | if let [x, 0] | [x, 1] = [0, 1] {}
| ^^^^^^^^^^^^^^^
@@ -121,7 +121,7 @@ LL + if let [x, 0 | 1] = [0, 1] {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:37:12
--> tests/ui/unnested_or_patterns.rs:42:12
|
LL | if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -133,7 +133,7 @@ LL + if let [x, 0 | 1 | 2] = [0, 1] {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:39:12
--> tests/ui/unnested_or_patterns.rs:44:12
|
LL | if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -145,7 +145,7 @@ LL + if let [x, ..] | [x, 1 | 2] = [0, 1] {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:42:12
--> tests/ui/unnested_or_patterns.rs:47:12
|
LL | if let TS(0, x) | TS(1, x) = TS(0, 0) {}
| ^^^^^^^^^^^^^^^^^^^
@@ -157,7 +157,7 @@ LL + if let TS(0 | 1, x) = TS(0, 0) {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:44:12
--> tests/ui/unnested_or_patterns.rs:49:12
|
LL | if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -169,7 +169,7 @@ LL + if let TS(1 | 2 | 3, 0) = TS(0, 0) {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:46:12
--> tests/ui/unnested_or_patterns.rs:51:12
|
LL | if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -181,7 +181,7 @@ LL + if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:52:12
--> tests/ui/unnested_or_patterns.rs:53:12
|
LL | if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -193,7 +193,7 @@ LL + if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:64:12
--> tests/ui/unnested_or_patterns.rs:65:12
|
LL | if let [1] | [53] = [0] {}
| ^^^^^^^^^^
@@ -205,7 +205,7 @@ LL + if let [1 | 53] = [0] {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:70:13
--> tests/ui/unnested_or_patterns.rs:71:13
|
LL | let (0 | (1 | _)) = 0;
| ^^^^^^^^^^^^^
@@ -217,7 +217,7 @@ LL + let (0 | 1 | _) = 0;
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:73:16
--> tests/ui/unnested_or_patterns.rs:74:16
|
LL | if let (0 | (1 | _)) = 0 {}
| ^^^^^^^^^^^^^
@@ -229,7 +229,7 @@ LL + if let (0 | 1 | _) = 0 {}
|
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:77:20
--> tests/ui/unnested_or_patterns.rs:78:20
|
LL | fn or_in_param((x | (x | x)): i32) {}
| ^^^^^^^^^^^^^
@@ -240,5 +240,17 @@ LL - fn or_in_param((x | (x | x)): i32) {}
LL + fn or_in_param((x | x | x): i32) {}
|
error: aborting due to 20 previous errors
error: unnested or-patterns
--> tests/ui/unnested_or_patterns.rs:94:12
|
LL | if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: nest the patterns
|
LL - if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
LL + if let S { y, x: 0 | 1 } = (S { x: 0, y: 1 }) {}
|
error: aborting due to 21 previous errors