Skip to content

Commit

Permalink
[comparison_chain] rust-lang#4827 Check core::cmp::Ord is implemented
Browse files Browse the repository at this point in the history
Only emit lint, if `cmp` is actually available on the type being
compared. Don't emit lint in cases where only `PartialOrd` is
implemented.
  • Loading branch information
timbodeit committed Nov 24, 2019
1 parent cc35165 commit fff9a8e
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 2 deletions.
12 changes: 11 additions & 1 deletion clippy_lints/src/comparison_chain.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::utils::{if_sequence, parent_node_is_if_expr, span_help_and_lint, SpanlessEq};
use crate::utils::{
get_trait_def_id, if_sequence, implements_trait, parent_node_is_if_expr, paths, span_help_and_lint, SpanlessEq,
};
use rustc::hir::*;
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};
Expand Down Expand Up @@ -84,6 +86,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ComparisonChain {
{
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, &[]));

if !is_ord {
return;
}
} else {
// We only care about comparison chains
return;
Expand Down
61 changes: 61 additions & 0 deletions tests/ui/comparison_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,65 @@ fn f(x: u8, y: u8, z: u8) {
}
}

#[allow(clippy::float_cmp)]
fn g(x: f64, y: f64, z: f64) {
// Ignored: f64 doesn't implement Ord
if x > y {
a()
} else if x < y {
b()
}

// Ignored: f64 doesn't implement Ord
if x > y {
a()
} else if x < y {
b()
} else {
c()
}

// Ignored: f64 doesn't implement Ord
if x > y {
a()
} else if y > x {
b()
} else {
c()
}

// Ignored: f64 doesn't implement Ord
if x > 1.0 {
a()
} else if x < 1.0 {
b()
} else if x == 1.0 {
c()
}
}

fn h<T: Ord>(x: T, y: T, z: T) {
if x > y {
a()
} else if x < y {
b()
}

if x > y {
a()
} else if x < y {
b()
} else {
c()
}

if x > y {
a()
} else if y > x {
b()
} else {
c()
}
}

fn main() {}
42 changes: 41 additions & 1 deletion tests/ui/comparison_chain.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,45 @@ LL | | }
|
= help: Consider rewriting the `if` chain to use `cmp` and `match`.

error: aborting due to 4 previous errors
error: `if` chain can be rewritten with `match`
--> $DIR/comparison_chain.rs:117:5
|
LL | / if x > y {
LL | | a()
LL | | } else if x < y {
LL | | b()
LL | | }
| |_____^
|
= help: Consider rewriting the `if` chain to use `cmp` and `match`.

error: `if` chain can be rewritten with `match`
--> $DIR/comparison_chain.rs:123:5
|
LL | / if x > y {
LL | | a()
LL | | } else if x < y {
LL | | b()
LL | | } else {
LL | | c()
LL | | }
| |_____^
|
= help: Consider rewriting the `if` chain to use `cmp` and `match`.

error: `if` chain can be rewritten with `match`
--> $DIR/comparison_chain.rs:131:5
|
LL | / if x > y {
LL | | a()
LL | | } else if y > x {
LL | | b()
LL | | } else {
LL | | c()
LL | | }
| |_____^
|
= help: Consider rewriting the `if` chain to use `cmp` and `match`.

error: aborting due to 7 previous errors

0 comments on commit fff9a8e

Please sign in to comment.