]> git.lizzy.rs Git - rust.git/commitdiff
[comparison_chain] #4827 Check `core::cmp::Ord` is implemented
authorTim Bodeit <tim@bodeit.com>
Sat, 23 Nov 2019 21:35:21 +0000 (22:35 +0100)
committerTim Bodeit <tim@bodeit.com>
Sun, 24 Nov 2019 09:00:06 +0000 (10:00 +0100)
Only emit lint, if `cmp` is actually available on the type being
compared. Don't emit lint in cases where only `PartialOrd` is
implemented.

clippy_lints/src/comparison_chain.rs
tests/ui/comparison_chain.rs
tests/ui/comparison_chain.stderr

index 6968d8f655996134702d047074f56c92bcf96115..087bceaffd98326e9f71565e7f3d548895759e15 100644 (file)
@@ -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};
@@ -84,6 +86,14 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
                 {
                     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;
index b697413b6e031b1f881d9d267d64a0eee53c9fd4..9c2128469de9ded7afeaf9571882f4e3be171383 100644 (file)
@@ -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() {}
index 575181dd7194276279cd103b627a50d1a20d98c5..69db88b03b5b55d30251dad120febb2fecf7be65 100644 (file)
@@ -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