]> git.lizzy.rs Git - rust.git/commitdiff
check impl Ord / is_float
authorChristoph Walcher <christoph-wa@gmx.de>
Fri, 7 Aug 2020 15:55:25 +0000 (17:55 +0200)
committerChristoph Walcher <christoph-wa@gmx.de>
Fri, 7 Aug 2020 16:30:20 +0000 (18:30 +0200)
clippy_lints/src/minmax.rs
tests/ui/min_max.rs
tests/ui/min_max.stderr

index 1f798fd1120913ef87c979dffdd974e0d927300f..004dd50a31be8716b7af5bc1727051261b2f2b84 100644 (file)
@@ -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,
index 90ec5676493a1d3ace7ed036ef635d56625999c7..f7ed72a11cf684b64f8d584cbaa990ae4aa0fa39 100644 (file)
@@ -6,6 +6,18 @@
 
 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
 }
index 653946dc025f82b5da472e4aed86abce750d1152..9f8e26fa406f0e59c7458ec5b54ca234386abf6d 100644 (file)
@@ -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