Skip to content

Commit 0c94273

Browse files
committed
Auto merge of rust-lang#5596 - ebroto:issue_5212, r=phansch
Fix comparison_chain false positive changelog: comparison_chain: fix false positives when the binary operation is the same. Fixes rust-lang#5212
2 parents 53a9805 + 9217675 commit 0c94273

File tree

2 files changed

+80
-3
lines changed

2 files changed

+80
-3
lines changed

clippy_lints/src/comparison_chain.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ComparisonChain {
8181

8282
// Check that both sets of operands are equal
8383
let mut spanless_eq = SpanlessEq::new(cx);
84-
if (!spanless_eq.eq_expr(lhs1, lhs2) || !spanless_eq.eq_expr(rhs1, rhs2))
85-
&& (!spanless_eq.eq_expr(lhs1, rhs2) || !spanless_eq.eq_expr(rhs1, lhs2))
86-
{
84+
let same_fixed_operands = spanless_eq.eq_expr(lhs1, lhs2) && spanless_eq.eq_expr(rhs1, rhs2);
85+
let same_transposed_operands = spanless_eq.eq_expr(lhs1, rhs2) && spanless_eq.eq_expr(rhs1, lhs2);
86+
87+
if !same_fixed_operands && !same_transposed_operands {
8788
return;
8889
}
8990

91+
// Check that if the operation is the same, either it's not `==` or the operands are transposed
92+
if kind1.node == kind2.node {
93+
if kind1.node == BinOpKind::Eq {
94+
return;
95+
}
96+
if !same_transposed_operands {
97+
return;
98+
}
99+
}
100+
90101
// Check that the type being compared implements `core::cmp::Ord`
91102
let ty = cx.tables.expr_ty(lhs1);
92103
let is_ord = get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[]));

tests/ui/comparison_chain.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,70 @@ fn h<T: Ord>(x: T, y: T, z: T) {
137137
}
138138
}
139139

140+
// The following uses should be ignored
141+
mod issue_5212 {
142+
use super::{a, b, c};
143+
fn foo() -> u8 {
144+
21
145+
}
146+
147+
fn same_operation_equals() {
148+
// operands are fixed
149+
150+
if foo() == 42 {
151+
a()
152+
} else if foo() == 42 {
153+
b()
154+
}
155+
156+
if foo() == 42 {
157+
a()
158+
} else if foo() == 42 {
159+
b()
160+
} else {
161+
c()
162+
}
163+
164+
// operands are transposed
165+
166+
if foo() == 42 {
167+
a()
168+
} else if 42 == foo() {
169+
b()
170+
}
171+
}
172+
173+
fn same_operation_not_equals() {
174+
// operands are fixed
175+
176+
if foo() > 42 {
177+
a()
178+
} else if foo() > 42 {
179+
b()
180+
}
181+
182+
if foo() > 42 {
183+
a()
184+
} else if foo() > 42 {
185+
b()
186+
} else {
187+
c()
188+
}
189+
190+
if foo() < 42 {
191+
a()
192+
} else if foo() < 42 {
193+
b()
194+
}
195+
196+
if foo() < 42 {
197+
a()
198+
} else if foo() < 42 {
199+
b()
200+
} else {
201+
c()
202+
}
203+
}
204+
}
205+
140206
fn main() {}

0 commit comments

Comments
 (0)