about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChristoph Walcher <christoph-wa@gmx.de>2020-08-07 17:55:25 +0200
committerChristoph Walcher <christoph-wa@gmx.de>2020-08-07 18:30:20 +0200
commit87e740921abd4132152f090545fa4c9ed9fa0d6d (patch)
tree7d84798521a50c34946a2ff21970cefb34cbe9cc
parent0abc4833e5dc8ec4da48d5b25e1d0df81cceec4d (diff)
downloadrust-87e740921abd4132152f090545fa4c9ed9fa0d6d.tar.gz
rust-87e740921abd4132152f090545fa4c9ed9fa0d6d.zip
check impl Ord / is_float
-rw-r--r--clippy_lints/src/minmax.rs23
-rw-r--r--tests/ui/min_max.rs18
-rw-r--r--tests/ui/min_max.stderr32
3 files changed, 53 insertions, 20 deletions
diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs
index 1f798fd1120..004dd50a31b 100644
--- a/clippy_lints/src/minmax.rs
+++ b/clippy_lints/src/minmax.rs
@@ -1,5 +1,6 @@
 use crate::consts::{constant_simple, Constant};
-use crate::utils::{match_def_path, paths, span_lint};
+use crate::utils::{match_def_path, match_trait_method, paths, span_lint};
+use if_chain::if_chain;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -84,12 +85,20 @@ fn min_max<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(MinMax, Cons
             }
         },
         ExprKind::MethodCall(ref path, _, ref args, _) => {
-            if path.ident.as_str() == sym!(max).as_str() {
-                fetch_const(cx, args, MinMax::Max)
-            } else if path.ident.as_str() == sym!(min).as_str() {
-                fetch_const(cx, args, MinMax::Min)
-            } else {
-                None
+            if_chain! {
+                if let [obj, _] = args;
+                if cx.typeck_results().expr_ty(obj).is_floating_point() || match_trait_method(cx, expr, &paths::ORD);
+                then {
+                    if path.ident.as_str() == sym!(max).as_str() {
+                        fetch_const(cx, args, MinMax::Max)
+                    } else if path.ident.as_str() == sym!(min).as_str() {
+                        fetch_const(cx, args, MinMax::Min)
+                    } else {
+                        None
+                    }
+                } else {
+                    None
+                }
             }
         },
         _ => None,
diff --git a/tests/ui/min_max.rs b/tests/ui/min_max.rs
index 90ec5676493..f7ed72a11cf 100644
--- a/tests/ui/min_max.rs
+++ b/tests/ui/min_max.rs
@@ -6,6 +6,18 @@ use std::cmp::{max, min};
 
 const LARGE: usize = 3;
 
+struct NotOrd(u64);
+
+impl NotOrd {
+    fn min(self, x: u64) -> NotOrd {
+        NotOrd(x)
+    }
+
+    fn max(self, x: u64) -> NotOrd {
+        NotOrd(x)
+    }
+}
+
 fn main() {
     let x;
     x = 2usize;
@@ -31,11 +43,14 @@ fn main() {
 
     max("Apple", min(s, "Zoo")); // ok
 
+    let f = 3f32;
     x.min(1).max(3);
     x.max(3).min(1);
+    f.max(3f32).min(1f32);
 
     x.max(1).min(3); // ok
     x.min(3).max(1); // ok
+    f.min(3f32).max(1f32); // ok
 
     max(x.min(1), 3);
     min(x.max(1), 3); // ok
@@ -44,4 +59,7 @@ fn main() {
     s.min("Apple").max("Zoo");
 
     s.min("Zoo").max("Apple"); // ok
+
+    let not_ord = NotOrd(1);
+    not_ord.min(1).max(3); // ok
 }
diff --git a/tests/ui/min_max.stderr b/tests/ui/min_max.stderr
index 653946dc025..9f8e26fa406 100644
--- a/tests/ui/min_max.stderr
+++ b/tests/ui/min_max.stderr
@@ -1,5 +1,5 @@
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:12:5
+  --> $DIR/min_max.rs:24:5
    |
 LL |     min(1, max(3, x));
    |     ^^^^^^^^^^^^^^^^^
@@ -7,70 +7,76 @@ LL |     min(1, max(3, x));
    = note: `-D clippy::min-max` implied by `-D warnings`
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:13:5
+  --> $DIR/min_max.rs:25:5
    |
 LL |     min(max(3, x), 1);
    |     ^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:14:5
+  --> $DIR/min_max.rs:26:5
    |
 LL |     max(min(x, 1), 3);
    |     ^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:15:5
+  --> $DIR/min_max.rs:27:5
    |
 LL |     max(3, min(x, 1));
    |     ^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:17:5
+  --> $DIR/min_max.rs:29:5
    |
 LL |     my_max(3, my_min(x, 1));
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:29:5
+  --> $DIR/min_max.rs:41:5
    |
 LL |     min("Apple", max("Zoo", s));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:30:5
+  --> $DIR/min_max.rs:42:5
    |
 LL |     max(min(s, "Apple"), "Zoo");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:34:5
+  --> $DIR/min_max.rs:47:5
    |
 LL |     x.min(1).max(3);
    |     ^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:35:5
+  --> $DIR/min_max.rs:48:5
    |
 LL |     x.max(3).min(1);
    |     ^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:40:5
+  --> $DIR/min_max.rs:49:5
+   |
+LL |     f.max(3f32).min(1f32);
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error: this `min`/`max` combination leads to constant result
+  --> $DIR/min_max.rs:55:5
    |
 LL |     max(x.min(1), 3);
    |     ^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:43:5
+  --> $DIR/min_max.rs:58:5
    |
 LL |     s.max("Zoo").min("Apple");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:44:5
+  --> $DIR/min_max.rs:59:5
    |
 LL |     s.min("Apple").max("Zoo");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 12 previous errors
+error: aborting due to 13 previous errors