Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit afa2741

Browse files
committed
redundant_pattern_matching
1 parent 371120b commit afa2741

7 files changed

+319
-26
lines changed

clippy_lints/src/matches/redundant_pattern_match.rs

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,9 @@ fn find_sugg_for_if_let<'tcx>(
186186
}
187187

188188
pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) {
189+
//eprintln!("{:#?}", expr);
189190
if arms.len() == 2 {
190191
let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind);
191-
192192
let found_good_method = match node_pair {
193193
(
194194
PatKind::TupleStruct(ref path_left, patterns_left, _),
@@ -252,6 +252,68 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op
252252
None
253253
}
254254
},
255+
(PatKind::TupleStruct(ref path_left, patterns, _), PatKind::Wild) if patterns.len() == 1 => {
256+
if let PatKind::Wild = patterns[0].kind {
257+
let ident = match path_left {
258+
QPath::Resolved(_, path) => {
259+
let name = path.segments[0].ident;
260+
Some(name)
261+
},
262+
_ => None,
263+
};
264+
if let Some(name) = ident {
265+
match name.as_str() {
266+
"Ok" => find_good_method_for_matches_macro(
267+
cx,
268+
arms,
269+
path_left,
270+
Item::Lang(ResultOk),
271+
"is_ok()",
272+
"is_err()",
273+
),
274+
"Some" => find_good_method_for_matches_macro(
275+
cx,
276+
arms,
277+
path_left,
278+
Item::Lang(OptionSome),
279+
"is_some()",
280+
"is_none()",
281+
),
282+
_ => None,
283+
}
284+
} else {
285+
None
286+
}
287+
} else {
288+
None
289+
}
290+
},
291+
(PatKind::Path(ref path_left), PatKind::Wild) => {
292+
let ident = match path_left {
293+
QPath::Resolved(_, path) => {
294+
let name = path.segments[0].ident;
295+
Some(name)
296+
},
297+
_ => None,
298+
};
299+
300+
if let Some(name) = ident {
301+
match name.as_str() {
302+
"None" => find_good_method_for_matches_macro(
303+
cx,
304+
arms,
305+
path_left,
306+
Item::Lang(OptionNone),
307+
"is_none()",
308+
"is_some()",
309+
),
310+
_ => None,
311+
}
312+
} else {
313+
None
314+
}
315+
316+
}
255317
_ => None,
256318
};
257319

@@ -345,3 +407,30 @@ fn find_good_method_for_match<'a>(
345407
_ => None,
346408
}
347409
}
410+
411+
#[expect(clippy::too_many_arguments)]
412+
fn find_good_method_for_matches_macro<'a>(
413+
cx: &LateContext<'_>,
414+
arms: &[Arm<'_>],
415+
path_left: &QPath<'_>,
416+
expected_item_left: Item,
417+
should_be_left: &'a str,
418+
should_be_right: &'a str,
419+
) -> Option<&'a str> {
420+
let first_pat = arms[0].pat;
421+
422+
let body_node_pair = if is_pat_variant(cx, first_pat, path_left, expected_item_left) {
423+
(&arms[0].body.kind, &arms[1].body.kind)
424+
} else {
425+
return None;
426+
};
427+
428+
match body_node_pair {
429+
(ExprKind::Lit(lit_left), ExprKind::Lit(lit_right)) => match (&lit_left.node, &lit_right.node) {
430+
(LitKind::Bool(true), LitKind::Bool(false)) => Some(should_be_left),
431+
(LitKind::Bool(false), LitKind::Bool(true)) => Some(should_be_right),
432+
_ => None,
433+
},
434+
_ => None,
435+
}
436+
}

tests/ui/redundant_pattern_matching_option.fixed

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ fn main() {
4646
let _ = if opt.is_some() { true } else { false };
4747

4848
issue6067();
49+
issue10726();
4950

5051
let _ = if gen_opt().is_some() {
5152
1
@@ -88,3 +89,21 @@ fn issue7921() {
8889
if (&None::<()>).is_none() {}
8990
if (&None::<()>).is_none() {}
9091
}
92+
93+
fn issue10726() {
94+
Some(42).is_some();
95+
96+
Some(42).is_none();
97+
98+
Some(42).is_none();
99+
100+
Some(42).is_some();
101+
102+
None::<()>.is_none();
103+
104+
None::<()>.is_none();
105+
106+
None::<()>.is_none();
107+
108+
None::<()>.is_some();
109+
}

tests/ui/redundant_pattern_matching_option.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ fn main() {
5555
let _ = if let Some(_) = opt { true } else { false };
5656

5757
issue6067();
58+
issue10726();
5859

5960
let _ = if let Some(_) = gen_opt() {
6061
1
@@ -103,3 +104,45 @@ fn issue7921() {
103104
if let None = *(&None::<()>) {}
104105
if let None = *&None::<()> {}
105106
}
107+
108+
fn issue10726() {
109+
match Some(42) {
110+
Some(_) => true,
111+
_ => false,
112+
};
113+
114+
match Some(42) {
115+
Some(_) => false,
116+
_ => true,
117+
};
118+
119+
match Some(42) {
120+
None => true,
121+
_ => false,
122+
};
123+
124+
match Some(42) {
125+
None => false,
126+
_ => true,
127+
};
128+
129+
match None::<()> {
130+
Some(_) => false,
131+
_ => true,
132+
};
133+
134+
match None::<()> {
135+
Some(_) => false,
136+
_ => true,
137+
};
138+
139+
match None::<()> {
140+
None => true,
141+
_ => false,
142+
};
143+
144+
match None::<()> {
145+
None => false,
146+
_ => true,
147+
};
148+
}

tests/ui/redundant_pattern_matching_option.stderr

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,49 +77,49 @@ LL | let _ = if let Some(_) = opt { true } else { false };
7777
| -------^^^^^^^------ help: try this: `if opt.is_some()`
7878

7979
error: redundant pattern matching, consider using `is_some()`
80-
--> $DIR/redundant_pattern_matching_option.rs:59:20
80+
--> $DIR/redundant_pattern_matching_option.rs:60:20
8181
|
8282
LL | let _ = if let Some(_) = gen_opt() {
8383
| -------^^^^^^^------------ help: try this: `if gen_opt().is_some()`
8484

8585
error: redundant pattern matching, consider using `is_none()`
86-
--> $DIR/redundant_pattern_matching_option.rs:61:19
86+
--> $DIR/redundant_pattern_matching_option.rs:62:19
8787
|
8888
LL | } else if let None = gen_opt() {
8989
| -------^^^^------------ help: try this: `if gen_opt().is_none()`
9090

9191
error: redundant pattern matching, consider using `is_some()`
92-
--> $DIR/redundant_pattern_matching_option.rs:67:12
92+
--> $DIR/redundant_pattern_matching_option.rs:68:12
9393
|
9494
LL | if let Some(..) = gen_opt() {}
9595
| -------^^^^^^^^------------ help: try this: `if gen_opt().is_some()`
9696

9797
error: redundant pattern matching, consider using `is_some()`
98-
--> $DIR/redundant_pattern_matching_option.rs:82:12
98+
--> $DIR/redundant_pattern_matching_option.rs:83:12
9999
|
100100
LL | if let Some(_) = Some(42) {}
101101
| -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
102102

103103
error: redundant pattern matching, consider using `is_none()`
104-
--> $DIR/redundant_pattern_matching_option.rs:84:12
104+
--> $DIR/redundant_pattern_matching_option.rs:85:12
105105
|
106106
LL | if let None = None::<()> {}
107107
| -------^^^^------------- help: try this: `if None::<()>.is_none()`
108108

109109
error: redundant pattern matching, consider using `is_some()`
110-
--> $DIR/redundant_pattern_matching_option.rs:86:15
110+
--> $DIR/redundant_pattern_matching_option.rs:87:15
111111
|
112112
LL | while let Some(_) = Some(42) {}
113113
| ----------^^^^^^^----------- help: try this: `while Some(42).is_some()`
114114

115115
error: redundant pattern matching, consider using `is_none()`
116-
--> $DIR/redundant_pattern_matching_option.rs:88:15
116+
--> $DIR/redundant_pattern_matching_option.rs:89:15
117117
|
118118
LL | while let None = None::<()> {}
119119
| ----------^^^^------------- help: try this: `while None::<()>.is_none()`
120120

121121
error: redundant pattern matching, consider using `is_some()`
122-
--> $DIR/redundant_pattern_matching_option.rs:90:5
122+
--> $DIR/redundant_pattern_matching_option.rs:91:5
123123
|
124124
LL | / match Some(42) {
125125
LL | | Some(_) => true,
@@ -128,7 +128,7 @@ LL | | };
128128
| |_____^ help: try this: `Some(42).is_some()`
129129

130130
error: redundant pattern matching, consider using `is_none()`
131-
--> $DIR/redundant_pattern_matching_option.rs:95:5
131+
--> $DIR/redundant_pattern_matching_option.rs:96:5
132132
|
133133
LL | / match None::<()> {
134134
LL | | Some(_) => false,
@@ -137,16 +137,88 @@ LL | | };
137137
| |_____^ help: try this: `None::<()>.is_none()`
138138

139139
error: redundant pattern matching, consider using `is_none()`
140-
--> $DIR/redundant_pattern_matching_option.rs:103:12
140+
--> $DIR/redundant_pattern_matching_option.rs:104:12
141141
|
142142
LL | if let None = *(&None::<()>) {}
143143
| -------^^^^----------------- help: try this: `if (&None::<()>).is_none()`
144144

145145
error: redundant pattern matching, consider using `is_none()`
146-
--> $DIR/redundant_pattern_matching_option.rs:104:12
146+
--> $DIR/redundant_pattern_matching_option.rs:105:12
147147
|
148148
LL | if let None = *&None::<()> {}
149149
| -------^^^^--------------- help: try this: `if (&None::<()>).is_none()`
150150

151-
error: aborting due to 22 previous errors
151+
error: redundant pattern matching, consider using `is_some()`
152+
--> $DIR/redundant_pattern_matching_option.rs:109:5
153+
|
154+
LL | / match Some(42) {
155+
LL | | Some(_) => true,
156+
LL | | _ => false,
157+
LL | | };
158+
| |_____^ help: try this: `Some(42).is_some()`
159+
160+
error: redundant pattern matching, consider using `is_none()`
161+
--> $DIR/redundant_pattern_matching_option.rs:114:5
162+
|
163+
LL | / match Some(42) {
164+
LL | | Some(_) => false,
165+
LL | | _ => true,
166+
LL | | };
167+
| |_____^ help: try this: `Some(42).is_none()`
168+
169+
error: redundant pattern matching, consider using `is_none()`
170+
--> $DIR/redundant_pattern_matching_option.rs:119:5
171+
|
172+
LL | / match Some(42) {
173+
LL | | None => true,
174+
LL | | _ => false,
175+
LL | | };
176+
| |_____^ help: try this: `Some(42).is_none()`
177+
178+
error: redundant pattern matching, consider using `is_some()`
179+
--> $DIR/redundant_pattern_matching_option.rs:124:5
180+
|
181+
LL | / match Some(42) {
182+
LL | | None => false,
183+
LL | | _ => true,
184+
LL | | };
185+
| |_____^ help: try this: `Some(42).is_some()`
186+
187+
error: redundant pattern matching, consider using `is_none()`
188+
--> $DIR/redundant_pattern_matching_option.rs:129:5
189+
|
190+
LL | / match None::<()> {
191+
LL | | Some(_) => false,
192+
LL | | _ => true,
193+
LL | | };
194+
| |_____^ help: try this: `None::<()>.is_none()`
195+
196+
error: redundant pattern matching, consider using `is_none()`
197+
--> $DIR/redundant_pattern_matching_option.rs:134:5
198+
|
199+
LL | / match None::<()> {
200+
LL | | Some(_) => false,
201+
LL | | _ => true,
202+
LL | | };
203+
| |_____^ help: try this: `None::<()>.is_none()`
204+
205+
error: redundant pattern matching, consider using `is_none()`
206+
--> $DIR/redundant_pattern_matching_option.rs:139:5
207+
|
208+
LL | / match None::<()> {
209+
LL | | None => true,
210+
LL | | _ => false,
211+
LL | | };
212+
| |_____^ help: try this: `None::<()>.is_none()`
213+
214+
error: redundant pattern matching, consider using `is_some()`
215+
--> $DIR/redundant_pattern_matching_option.rs:144:5
216+
|
217+
LL | / match None::<()> {
218+
LL | | None => false,
219+
LL | | _ => true,
220+
LL | | };
221+
| |_____^ help: try this: `None::<()>.is_some()`
222+
223+
error: aborting due to 30 previous errors
152224

tests/ui/redundant_pattern_matching_result.fixed

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ fn main() {
4343
issue5504();
4444
issue6067();
4545
issue6065();
46+
issue10726();
4647

4748
let _ = if gen_res().is_ok() {
4849
1
@@ -107,3 +108,13 @@ const fn issue6067() {
107108

108109
Err::<i32, i32>(42).is_err();
109110
}
111+
112+
fn issue10726() {
113+
Ok::<i32, i32>(42).is_ok();
114+
115+
Ok::<i32, i32>(42).is_err();
116+
117+
Err::<i32, i32>(42).is_err();
118+
119+
Err::<i32, i32>(42).is_ok();
120+
}

0 commit comments

Comments
 (0)