Skip to content

Commit bc3a80e

Browse files
committed
make sure they have the same type
1 parent 7ece69d commit bc3a80e

File tree

3 files changed

+38
-15
lines changed

3 files changed

+38
-15
lines changed

clippy_lints/src/matches/redundant_guard.rs

+10-15
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,9 @@ pub(super) fn check(cx: &LateContext<'_>, arms: &[Arm<'_>]) {
4747
arm.guard,
4848
&mut app,
4949
);
50-
51-
continue;
5250
}
53-
5451
// `Some(x) if let Some(2) = x`
55-
if let Guard::IfLet(let_expr) = guard
52+
else if let Guard::IfLet(let_expr) = guard
5653
&& let pat = let_expr.pat
5754
&& let Some((pat_binding, field_name)) = get_pat_binding(cx, let_expr.init, outer_arm)
5855
{
@@ -66,16 +63,20 @@ pub(super) fn check(cx: &LateContext<'_>, arms: &[Arm<'_>]) {
6663
None,
6764
&mut app,
6865
);
69-
70-
continue;
7166
}
72-
7367
// `Some(x) if x == Some(2)`
74-
if let Guard::If(if_expr) = guard
68+
else if let Guard::If(if_expr) = guard
7569
&& let ExprKind::Binary(bin_op, local, pat) = if_expr.kind
7670
&& matches!(bin_op.node, BinOpKind::Eq)
7771
&& let Some((pat_binding, field_name)) = get_pat_binding(cx, local, outer_arm)
7872
&& expr_can_be_pat(cx, pat)
73+
// Ensure they have the same type. If they don't, we'd need deref coercion which isn't
74+
// possible (currently) in a pattern. In some cases, you can use something like
75+
// `as_deref` or similar but in general, we shouldn't lint this as it'd create an
76+
// extraordinary amount of FPs.
77+
//
78+
// This isn't necessary in the other two checks, as they must be a pattern already.
79+
&& cx.typeck_results().expr_ty(local) == cx.typeck_results().expr_ty(pat)
7980
{
8081
emit_redundant_guard(
8182
cx,
@@ -87,8 +88,6 @@ pub(super) fn check(cx: &LateContext<'_>, arms: &[Arm<'_>]) {
8788
None,
8889
&mut app,
8990
);
90-
91-
continue;
9291
}
9392
}
9493
}
@@ -217,17 +216,13 @@ fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
217216

218217
true
219218
},
220-
ExprKind::Struct(_, fields, rest) => {
219+
ExprKind::Struct(_, fields, None) => {
221220
for field in fields {
222221
if !helper(cx, field.expr) {
223222
return ControlFlow::Break(());
224223
}
225224
}
226225

227-
if rest.is_some() {
228-
return ControlFlow::Break(());
229-
}
230-
231226
true
232227
},
233228
ExprKind::Path(qpath) => {

tests/ui/redundant_guard.fixed

+14
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ fn main() {
5656
B { e: Some(A(2)) } => ..,
5757
_ => todo!(),
5858
};
59+
// Do not lint, since we cannot represent this as a pattern (at least, without a conversion)
60+
let v = Some(vec![1u8, 2, 3]);
61+
match v {
62+
Some(x) if x == [1] => {},
63+
_ => {},
64+
}
5965

6066
external! {
6167
let x = Some(Some(1));
@@ -73,3 +79,11 @@ fn main() {
7379
};
7480
}
7581
}
82+
83+
// Do not lint
84+
fn f(s: Option<std::ffi::OsString>) {
85+
match s {
86+
Some(x) if x == "a" => {},
87+
_ => {},
88+
}
89+
}

tests/ui/redundant_guard.rs

+14
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ fn main() {
5656
B { e } if matches!(e, Some(A(2))) => ..,
5757
_ => todo!(),
5858
};
59+
// Do not lint, since we cannot represent this as a pattern (at least, without a conversion)
60+
let v = Some(vec![1u8, 2, 3]);
61+
match v {
62+
Some(x) if x == [1] => {},
63+
_ => {},
64+
}
5965

6066
external! {
6167
let x = Some(Some(1));
@@ -73,3 +79,11 @@ fn main() {
7379
};
7480
}
7581
}
82+
83+
// Do not lint
84+
fn f(s: Option<std::ffi::OsString>) {
85+
match s {
86+
Some(x) if x == "a" => {},
87+
_ => {},
88+
}
89+
}

0 commit comments

Comments
 (0)