Skip to content

Commit

Permalink
Auto merge of #5596 - ebroto:issue_5212, r=phansch
Browse files Browse the repository at this point in the history
Fix comparison_chain false positive

changelog: comparison_chain: fix false positives when the binary operation is the same.

Fixes #5212
  • Loading branch information
bors committed May 16, 2020
2 parents 53a9805 + 9217675 commit 0c94273
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 3 deletions.
17 changes: 14 additions & 3 deletions clippy_lints/src/comparison_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ComparisonChain {

// Check that both sets of operands are equal
let mut spanless_eq = SpanlessEq::new(cx);
if (!spanless_eq.eq_expr(lhs1, lhs2) || !spanless_eq.eq_expr(rhs1, rhs2))
&& (!spanless_eq.eq_expr(lhs1, rhs2) || !spanless_eq.eq_expr(rhs1, lhs2))
{
let same_fixed_operands = spanless_eq.eq_expr(lhs1, lhs2) && spanless_eq.eq_expr(rhs1, rhs2);
let same_transposed_operands = spanless_eq.eq_expr(lhs1, rhs2) && spanless_eq.eq_expr(rhs1, lhs2);

if !same_fixed_operands && !same_transposed_operands {
return;
}

// Check that if the operation is the same, either it's not `==` or the operands are transposed
if kind1.node == kind2.node {
if kind1.node == BinOpKind::Eq {
return;
}
if !same_transposed_operands {
return;
}
}

// Check that the type being compared implements `core::cmp::Ord`
let ty = cx.tables.expr_ty(lhs1);
let is_ord = get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[]));
Expand Down
66 changes: 66 additions & 0 deletions tests/ui/comparison_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,70 @@ fn h<T: Ord>(x: T, y: T, z: T) {
}
}

// The following uses should be ignored
mod issue_5212 {
use super::{a, b, c};
fn foo() -> u8 {
21
}

fn same_operation_equals() {
// operands are fixed

if foo() == 42 {
a()
} else if foo() == 42 {
b()
}

if foo() == 42 {
a()
} else if foo() == 42 {
b()
} else {
c()
}

// operands are transposed

if foo() == 42 {
a()
} else if 42 == foo() {
b()
}
}

fn same_operation_not_equals() {
// operands are fixed

if foo() > 42 {
a()
} else if foo() > 42 {
b()
}

if foo() > 42 {
a()
} else if foo() > 42 {
b()
} else {
c()
}

if foo() < 42 {
a()
} else if foo() < 42 {
b()
}

if foo() < 42 {
a()
} else if foo() < 42 {
b()
} else {
c()
}
}
}

fn main() {}

0 comments on commit 0c94273

Please sign in to comment.