Skip to content

Commit 64d5553

Browse files
authored
fix: unnested_or_patterns FP on structs with only shorthand field pats (#15343)
changelog: [`unnested_or_patterns`]: FP on structs with only shorthand field patterns fixes rust-lang/rust-clippy#15219
2 parents f35c203 + 0d479c1 commit 64d5553

File tree

4 files changed

+80
-30
lines changed

4 files changed

+80
-30
lines changed

clippy_lints/src/unnested_or_patterns.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,11 @@ fn extend_with_struct_pat(
326326
if idx_1 == idx {
327327
// In the case of `k`, we merely require identical field names
328328
// so that we will transform into `ident_k: p1_k | p2_k`.
329-
let pos = fps2.iter().position(|fp2| eq_id(fp1.ident, fp2.ident));
329+
let pos = fps2.iter().position(|fp2| {
330+
// Avoid `Foo { bar } | Foo { bar }` => `Foo { bar | bar }`
331+
!(fp1.is_shorthand && fp2.is_shorthand)
332+
&& eq_id(fp1.ident, fp2.ident)
333+
});
330334
pos_in_2.set(pos);
331335
pos.is_some()
332336
} else {

tests/ui/unnested_or_patterns.fixed

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
)]
1010
#![allow(unreachable_patterns, irrefutable_let_patterns, unused)]
1111

12+
struct S {
13+
x: u8,
14+
y: u8,
15+
}
16+
1217
fn main() {
1318
// Should be ignored by this lint, as nesting requires more characters.
1419
if let &0 | &2 = &0 {}
@@ -45,10 +50,6 @@ fn main() {
4550
//~^ unnested_or_patterns
4651
if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}
4752
//~^ unnested_or_patterns
48-
struct S {
49-
x: u8,
50-
y: u8,
51-
}
5253
if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}
5354
//~^ unnested_or_patterns
5455
if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
@@ -77,3 +78,19 @@ mod issue9952 {
7778
fn or_in_param((x | x | x): i32) {}
7879
//~^ unnested_or_patterns
7980
}
81+
82+
fn issue15219() {
83+
struct Foo {
84+
x: u8,
85+
}
86+
87+
// the original repro
88+
if let Foo { x } | Foo { x } = (Foo { x: 0 }) {}
89+
90+
// also works with more fields
91+
if let S { x, y } | S { x, y } = (S { x: 0, y: 0 }) {}
92+
93+
// `y` not triggering the lint doesn't stop the `x` from getting flagged
94+
if let S { y, x: 0 | 1 } = (S { x: 0, y: 1 }) {}
95+
//~^ unnested_or_patterns
96+
}

tests/ui/unnested_or_patterns.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
)]
1010
#![allow(unreachable_patterns, irrefutable_let_patterns, unused)]
1111

12+
struct S {
13+
x: u8,
14+
y: u8,
15+
}
16+
1217
fn main() {
1318
// Should be ignored by this lint, as nesting requires more characters.
1419
if let &0 | &2 = &0 {}
@@ -45,10 +50,6 @@ fn main() {
4550
//~^ unnested_or_patterns
4651
if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}
4752
//~^ unnested_or_patterns
48-
struct S {
49-
x: u8,
50-
y: u8,
51-
}
5253
if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
5354
//~^ unnested_or_patterns
5455
if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
@@ -77,3 +78,19 @@ mod issue9952 {
7778
fn or_in_param((x | (x | x)): i32) {}
7879
//~^ unnested_or_patterns
7980
}
81+
82+
fn issue15219() {
83+
struct Foo {
84+
x: u8,
85+
}
86+
87+
// the original repro
88+
if let Foo { x } | Foo { x } = (Foo { x: 0 }) {}
89+
90+
// also works with more fields
91+
if let S { x, y } | S { x, y } = (S { x: 0, y: 0 }) {}
92+
93+
// `y` not triggering the lint doesn't stop the `x` from getting flagged
94+
if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
95+
//~^ unnested_or_patterns
96+
}

tests/ui/unnested_or_patterns.stderr

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: unnested or-patterns
2-
--> tests/ui/unnested_or_patterns.rs:16:12
2+
--> tests/ui/unnested_or_patterns.rs:21:12
33
|
44
LL | if let box 0 | box 2 = Box::new(0) {}
55
| ^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL + if let box (0 | 2) = Box::new(0) {}
1313
|
1414

1515
error: unnested or-patterns
16-
--> tests/ui/unnested_or_patterns.rs:18:12
16+
--> tests/ui/unnested_or_patterns.rs:23:12
1717
|
1818
LL | if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {}
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL + if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}
2525
|
2626

2727
error: unnested or-patterns
28-
--> tests/ui/unnested_or_patterns.rs:21:12
28+
--> tests/ui/unnested_or_patterns.rs:26:12
2929
|
3030
LL | if let Some(1) | C0 | Some(2) = None {}
3131
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL + if let Some(1 | 2) | C0 = None {}
3737
|
3838

3939
error: unnested or-patterns
40-
--> tests/ui/unnested_or_patterns.rs:23:12
40+
--> tests/ui/unnested_or_patterns.rs:28:12
4141
|
4242
LL | if let &mut 0 | &mut 2 = &mut 0 {}
4343
| ^^^^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL + if let &mut (0 | 2) = &mut 0 {}
4949
|
5050

5151
error: unnested or-patterns
52-
--> tests/ui/unnested_or_patterns.rs:25:12
52+
--> tests/ui/unnested_or_patterns.rs:30:12
5353
|
5454
LL | if let x @ 0 | x @ 2 = 0 {}
5555
| ^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL + if let x @ (0 | 2) = 0 {}
6161
|
6262

6363
error: unnested or-patterns
64-
--> tests/ui/unnested_or_patterns.rs:27:12
64+
--> tests/ui/unnested_or_patterns.rs:32:12
6565
|
6666
LL | if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {}
6767
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL + if let (0, 1 | 2 | 3) = (0, 0) {}
7373
|
7474

7575
error: unnested or-patterns
76-
--> tests/ui/unnested_or_patterns.rs:29:12
76+
--> tests/ui/unnested_or_patterns.rs:34:12
7777
|
7878
LL | if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {}
7979
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -85,7 +85,7 @@ LL + if let (1 | 2 | 3, 0) = (0, 0) {}
8585
|
8686

8787
error: unnested or-patterns
88-
--> tests/ui/unnested_or_patterns.rs:31:12
88+
--> tests/ui/unnested_or_patterns.rs:36:12
8989
|
9090
LL | if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {}
9191
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -97,7 +97,7 @@ LL + if let (x, ..) | (x, 1 | 2) = (0, 1) {}
9797
|
9898

9999
error: unnested or-patterns
100-
--> tests/ui/unnested_or_patterns.rs:33:12
100+
--> tests/ui/unnested_or_patterns.rs:38:12
101101
|
102102
LL | if let [0] | [1] = [0] {}
103103
| ^^^^^^^^^
@@ -109,7 +109,7 @@ LL + if let [0 | 1] = [0] {}
109109
|
110110

111111
error: unnested or-patterns
112-
--> tests/ui/unnested_or_patterns.rs:35:12
112+
--> tests/ui/unnested_or_patterns.rs:40:12
113113
|
114114
LL | if let [x, 0] | [x, 1] = [0, 1] {}
115115
| ^^^^^^^^^^^^^^^
@@ -121,7 +121,7 @@ LL + if let [x, 0 | 1] = [0, 1] {}
121121
|
122122

123123
error: unnested or-patterns
124-
--> tests/ui/unnested_or_patterns.rs:37:12
124+
--> tests/ui/unnested_or_patterns.rs:42:12
125125
|
126126
LL | if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {}
127127
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -133,7 +133,7 @@ LL + if let [x, 0 | 1 | 2] = [0, 1] {}
133133
|
134134

135135
error: unnested or-patterns
136-
--> tests/ui/unnested_or_patterns.rs:39:12
136+
--> tests/ui/unnested_or_patterns.rs:44:12
137137
|
138138
LL | if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {}
139139
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -145,7 +145,7 @@ LL + if let [x, ..] | [x, 1 | 2] = [0, 1] {}
145145
|
146146

147147
error: unnested or-patterns
148-
--> tests/ui/unnested_or_patterns.rs:42:12
148+
--> tests/ui/unnested_or_patterns.rs:47:12
149149
|
150150
LL | if let TS(0, x) | TS(1, x) = TS(0, 0) {}
151151
| ^^^^^^^^^^^^^^^^^^^
@@ -157,7 +157,7 @@ LL + if let TS(0 | 1, x) = TS(0, 0) {}
157157
|
158158

159159
error: unnested or-patterns
160-
--> tests/ui/unnested_or_patterns.rs:44:12
160+
--> tests/ui/unnested_or_patterns.rs:49:12
161161
|
162162
LL | if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {}
163163
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -169,7 +169,7 @@ LL + if let TS(1 | 2 | 3, 0) = TS(0, 0) {}
169169
|
170170

171171
error: unnested or-patterns
172-
--> tests/ui/unnested_or_patterns.rs:46:12
172+
--> tests/ui/unnested_or_patterns.rs:51:12
173173
|
174174
LL | if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}
175175
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -181,7 +181,7 @@ LL + if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}
181181
|
182182

183183
error: unnested or-patterns
184-
--> tests/ui/unnested_or_patterns.rs:52:12
184+
--> tests/ui/unnested_or_patterns.rs:53:12
185185
|
186186
LL | if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
187187
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -193,7 +193,7 @@ LL + if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}
193193
|
194194

195195
error: unnested or-patterns
196-
--> tests/ui/unnested_or_patterns.rs:64:12
196+
--> tests/ui/unnested_or_patterns.rs:65:12
197197
|
198198
LL | if let [1] | [53] = [0] {}
199199
| ^^^^^^^^^^
@@ -205,7 +205,7 @@ LL + if let [1 | 53] = [0] {}
205205
|
206206

207207
error: unnested or-patterns
208-
--> tests/ui/unnested_or_patterns.rs:70:13
208+
--> tests/ui/unnested_or_patterns.rs:71:13
209209
|
210210
LL | let (0 | (1 | _)) = 0;
211211
| ^^^^^^^^^^^^^
@@ -217,7 +217,7 @@ LL + let (0 | 1 | _) = 0;
217217
|
218218

219219
error: unnested or-patterns
220-
--> tests/ui/unnested_or_patterns.rs:73:16
220+
--> tests/ui/unnested_or_patterns.rs:74:16
221221
|
222222
LL | if let (0 | (1 | _)) = 0 {}
223223
| ^^^^^^^^^^^^^
@@ -229,7 +229,7 @@ LL + if let (0 | 1 | _) = 0 {}
229229
|
230230

231231
error: unnested or-patterns
232-
--> tests/ui/unnested_or_patterns.rs:77:20
232+
--> tests/ui/unnested_or_patterns.rs:78:20
233233
|
234234
LL | fn or_in_param((x | (x | x)): i32) {}
235235
| ^^^^^^^^^^^^^
@@ -240,5 +240,17 @@ LL - fn or_in_param((x | (x | x)): i32) {}
240240
LL + fn or_in_param((x | x | x): i32) {}
241241
|
242242

243-
error: aborting due to 20 previous errors
243+
error: unnested or-patterns
244+
--> tests/ui/unnested_or_patterns.rs:94:12
245+
|
246+
LL | if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
247+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
248+
|
249+
help: nest the patterns
250+
|
251+
LL - if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
252+
LL + if let S { y, x: 0 | 1 } = (S { x: 0, y: 1 }) {}
253+
|
254+
255+
error: aborting due to 21 previous errors
244256

0 commit comments

Comments
 (0)