Skip to content

Commit cc637ba

Browse files
committed
Auto merge of #9092 - tamaroning:fix-needless-match, r=llogiq
Fix false positives of needless_match closes: #9084 made needless_match take into account arm in the form of `_ if => ...` changelog: none
2 parents e19a05c + f7a376e commit cc637ba

File tree

4 files changed

+127
-3
lines changed

4 files changed

+127
-3
lines changed

clippy_lints/src/matches/needless_match.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use clippy_utils::{
88
};
99
use rustc_errors::Applicability;
1010
use rustc_hir::LangItem::OptionNone;
11-
use rustc_hir::{Arm, BindingAnnotation, Expr, ExprKind, FnRetTy, Node, Pat, PatKind, Path, QPath};
11+
use rustc_hir::{Arm, BindingAnnotation, Expr, ExprKind, FnRetTy, Guard, Node, Pat, PatKind, Path, QPath};
1212
use rustc_lint::LateContext;
1313
use rustc_span::sym;
1414
use rustc_typeck::hir_ty_to_ty;
@@ -65,8 +65,26 @@ pub(crate) fn check_if_let<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'_>, if_let:
6565
fn check_all_arms(cx: &LateContext<'_>, match_expr: &Expr<'_>, arms: &[Arm<'_>]) -> bool {
6666
for arm in arms {
6767
let arm_expr = peel_blocks_with_stmt(arm.body);
68+
69+
if let Some(guard_expr) = &arm.guard {
70+
match guard_expr {
71+
// gives up if `pat if expr` can have side effects
72+
Guard::If(if_cond) => {
73+
if if_cond.can_have_side_effects() {
74+
return false;
75+
}
76+
},
77+
// gives up `pat if let ...` arm
78+
Guard::IfLet(_) => {
79+
return false;
80+
},
81+
};
82+
}
83+
6884
if let PatKind::Wild = arm.pat.kind {
69-
return eq_expr_value(cx, match_expr, strip_return(arm_expr));
85+
if !eq_expr_value(cx, match_expr, strip_return(arm_expr)) {
86+
return false;
87+
}
7088
} else if !pat_same_as_expr(arm.pat, arm_expr) {
7189
return false;
7290
}

tests/ui/needless_match.fixed

+39
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,43 @@ impl Tr for Result<i32, i32> {
207207
}
208208
}
209209

210+
mod issue9084 {
211+
fn wildcard_if() {
212+
let mut some_bool = true;
213+
let e = Some(1);
214+
215+
// should lint
216+
let _ = e;
217+
218+
// should lint
219+
let _ = e;
220+
221+
// should not lint
222+
let _ = match e {
223+
_ if some_bool => e,
224+
_ => Some(2),
225+
};
226+
227+
// should not lint
228+
let _ = match e {
229+
Some(i) => Some(i + 1),
230+
_ if some_bool => e,
231+
_ => e,
232+
};
233+
234+
// should not lint (guard has side effects)
235+
let _ = match e {
236+
Some(i) => Some(i),
237+
_ if {
238+
some_bool = false;
239+
some_bool
240+
} =>
241+
{
242+
e
243+
},
244+
_ => e,
245+
};
246+
}
247+
}
248+
210249
fn main() {}

tests/ui/needless_match.rs

+46
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,50 @@ impl Tr for Result<i32, i32> {
244244
}
245245
}
246246

247+
mod issue9084 {
248+
fn wildcard_if() {
249+
let mut some_bool = true;
250+
let e = Some(1);
251+
252+
// should lint
253+
let _ = match e {
254+
_ if some_bool => e,
255+
_ => e,
256+
};
257+
258+
// should lint
259+
let _ = match e {
260+
Some(i) => Some(i),
261+
_ if some_bool => e,
262+
_ => e,
263+
};
264+
265+
// should not lint
266+
let _ = match e {
267+
_ if some_bool => e,
268+
_ => Some(2),
269+
};
270+
271+
// should not lint
272+
let _ = match e {
273+
Some(i) => Some(i + 1),
274+
_ if some_bool => e,
275+
_ => e,
276+
};
277+
278+
// should not lint (guard has side effects)
279+
let _ = match e {
280+
Some(i) => Some(i),
281+
_ if {
282+
some_bool = false;
283+
some_bool
284+
} =>
285+
{
286+
e
287+
},
288+
_ => e,
289+
};
290+
}
291+
}
292+
247293
fn main() {}

tests/ui/needless_match.stderr

+22-1
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,26 @@ LL | | Complex::D(E::VariantB(ea, eb), b) => Complex::D(E::VariantB(
109109
LL | | };
110110
| |_________^ help: replace it with: `ce`
111111

112-
error: aborting due to 11 previous errors
112+
error: this match expression is unnecessary
113+
--> $DIR/needless_match.rs:253:17
114+
|
115+
LL | let _ = match e {
116+
| _________________^
117+
LL | | _ if some_bool => e,
118+
LL | | _ => e,
119+
LL | | };
120+
| |_________^ help: replace it with: `e`
121+
122+
error: this match expression is unnecessary
123+
--> $DIR/needless_match.rs:259:17
124+
|
125+
LL | let _ = match e {
126+
| _________________^
127+
LL | | Some(i) => Some(i),
128+
LL | | _ if some_bool => e,
129+
LL | | _ => e,
130+
LL | | };
131+
| |_________^ help: replace it with: `e`
132+
133+
error: aborting due to 13 previous errors
113134

0 commit comments

Comments
 (0)