Skip to content

Commit 9762984

Browse files
committed
fix: unnested_or_patterns suggests wrongly in let
1 parent 18061e2 commit 9762984

File tree

4 files changed

+88
-12
lines changed

4 files changed

+88
-12
lines changed

clippy_lints/src/unnested_or_patterns.rs

+25-11
Original file line numberDiff line numberDiff line change
@@ -64,34 +64,45 @@ impl_lint_pass!(UnnestedOrPatterns => [UNNESTED_OR_PATTERNS]);
6464
impl EarlyLintPass for UnnestedOrPatterns {
6565
fn check_arm(&mut self, cx: &EarlyContext<'_>, a: &ast::Arm) {
6666
if self.msrv.meets(msrvs::OR_PATTERNS) {
67-
lint_unnested_or_patterns(cx, &a.pat);
67+
lint_unnested_or_patterns(cx, &a.pat, PatternSource::Arm);
6868
}
6969
}
7070

7171
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
7272
if self.msrv.meets(msrvs::OR_PATTERNS) {
7373
if let ast::ExprKind::Let(pat, _, _, _) = &e.kind {
74-
lint_unnested_or_patterns(cx, pat);
74+
lint_unnested_or_patterns(cx, pat, PatternSource::Expr);
7575
}
7676
}
7777
}
7878

7979
fn check_param(&mut self, cx: &EarlyContext<'_>, p: &ast::Param) {
8080
if self.msrv.meets(msrvs::OR_PATTERNS) {
81-
lint_unnested_or_patterns(cx, &p.pat);
81+
lint_unnested_or_patterns(cx, &p.pat, PatternSource::Param);
8282
}
8383
}
8484

8585
fn check_local(&mut self, cx: &EarlyContext<'_>, l: &ast::Local) {
8686
if self.msrv.meets(msrvs::OR_PATTERNS) {
87-
lint_unnested_or_patterns(cx, &l.pat);
87+
lint_unnested_or_patterns(cx, &l.pat, PatternSource::Local);
8888
}
8989
}
9090

9191
extract_msrv_attr!();
9292
}
9393

94-
fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) {
94+
enum PatternSource {
95+
/// The pattern is part of a match arm
96+
Arm,
97+
/// The pattern is part of a if/while let
98+
Expr,
99+
/// The pattern is part of a function parameter
100+
Param,
101+
/// The pattern is part of a let binding
102+
Local,
103+
}
104+
105+
fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat, source: PatternSource) {
95106
if let Ident(.., None) | Expr(_) | Wild | Path(..) | Range(..) | Rest | MacCall(_) = pat.kind {
96107
// This is a leaf pattern, so cloning is unprofitable.
97108
return;
@@ -109,12 +120,15 @@ fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) {
109120

110121
span_lint_and_then(cx, UNNESTED_OR_PATTERNS, pat.span, "unnested or-patterns", |db| {
111122
insert_necessary_parens(&mut pat);
112-
db.span_suggestion_verbose(
113-
pat.span,
114-
"nest the patterns",
115-
pprust::pat_to_string(&pat),
116-
Applicability::MachineApplicable,
117-
);
123+
124+
// Insert additional parens if it is an or-pattern and the source is a local or parameter. This is
125+
// inserted after `pat_to_string` because doing it before will break the spans
126+
let new_pat = if matches!(pat.kind, Or(_)) && matches!(source, PatternSource::Local | PatternSource::Param) {
127+
format!("({})", pprust::pat_to_string(&pat))
128+
} else {
129+
pprust::pat_to_string(&pat)
130+
};
131+
db.span_suggestion_verbose(pat.span, "nest the patterns", new_pat, Applicability::MachineApplicable);
118132
});
119133
}
120134

tests/ui/unnested_or_patterns.fixed

+13
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,16 @@ fn msrv_1_53() {
6464
if let [1 | 53] = [0] {}
6565
//~^ unnested_or_patterns
6666
}
67+
68+
mod issue9952 {
69+
fn or_in_local() {
70+
let (0 | 1 | _) = 0;
71+
//~^ unnested_or_patterns
72+
73+
if let 0 | 1 | _ = 0 {}
74+
//~^ unnested_or_patterns
75+
}
76+
77+
fn or_in_param((x | x | x): i32) {}
78+
//~^ unnested_or_patterns
79+
}

tests/ui/unnested_or_patterns.rs

+13
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,16 @@ fn msrv_1_53() {
6464
if let [1] | [53] = [0] {}
6565
//~^ unnested_or_patterns
6666
}
67+
68+
mod issue9952 {
69+
fn or_in_local() {
70+
let (0 | (1 | _)) = 0;
71+
//~^ unnested_or_patterns
72+
73+
if let (0 | (1 | _)) = 0 {}
74+
//~^ unnested_or_patterns
75+
}
76+
77+
fn or_in_param((x | (x | x)): i32) {}
78+
//~^ unnested_or_patterns
79+
}

tests/ui/unnested_or_patterns.stderr

+37-1
Original file line numberDiff line numberDiff line change
@@ -204,5 +204,41 @@ LL - if let [1] | [53] = [0] {}
204204
LL + if let [1 | 53] = [0] {}
205205
|
206206

207-
error: aborting due to 17 previous errors
207+
error: unnested or-patterns
208+
--> tests/ui/unnested_or_patterns.rs:70:13
209+
|
210+
LL | let (0 | (1 | _)) = 0;
211+
| ^^^^^^^^^^^^^
212+
|
213+
help: nest the patterns
214+
|
215+
LL - let (0 | (1 | _)) = 0;
216+
LL + let (0 | 1 | _) = 0;
217+
|
218+
219+
error: unnested or-patterns
220+
--> tests/ui/unnested_or_patterns.rs:73:16
221+
|
222+
LL | if let (0 | (1 | _)) = 0 {}
223+
| ^^^^^^^^^^^^^
224+
|
225+
help: nest the patterns
226+
|
227+
LL - if let (0 | (1 | _)) = 0 {}
228+
LL + if let 0 | 1 | _ = 0 {}
229+
|
230+
231+
error: unnested or-patterns
232+
--> tests/ui/unnested_or_patterns.rs:77:20
233+
|
234+
LL | fn or_in_param((x | (x | x)): i32) {}
235+
| ^^^^^^^^^^^^^
236+
|
237+
help: nest the patterns
238+
|
239+
LL - fn or_in_param((x | (x | x)): i32) {}
240+
LL + fn or_in_param((x | x | x): i32) {}
241+
|
242+
243+
error: aborting due to 20 previous errors
208244

0 commit comments

Comments
 (0)