about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChengxu Bian <cbian564@gmail.com>2025-06-25 08:28:29 -0400
committerChengxu Bian <cbian564@gmail.com>2025-06-25 08:28:29 -0400
commit1eb2920318ca139fbc1a1b10f071775f7a49da4a (patch)
tree7d73dabf0a71b13d8d75b9eecde36f714a045934
parent71ff9a09d103e63a29d813b5ae54905f8a25774e (diff)
downloadrust-1eb2920318ca139fbc1a1b10f071775f7a49da4a.tar.gz
rust-1eb2920318ca139fbc1a1b10f071775f7a49da4a.zip
add more test cases and clauses
-rw-r--r--clippy_lints/src/floating_point_arithmetic.rs45
-rw-r--r--tests/ui/floating_point_mul_add.fixed16
-rw-r--r--tests/ui/floating_point_mul_add.rs14
-rw-r--r--tests/ui/floating_point_mul_add.stderr18
4 files changed, 78 insertions, 15 deletions
diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs
index 6b03a5a8f85..39b8e8c54fa 100644
--- a/clippy_lints/src/floating_point_arithmetic.rs
+++ b/clippy_lints/src/floating_point_arithmetic.rs
@@ -462,22 +462,51 @@ fn has_ambiguous_float_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
         ExprKind::Path(qpath) => {
             if let Res::Local(hir_id) = cx.qpath_res(qpath, expr.hir_id) {
                 if let Node::LetStmt(local) = cx.tcx.parent_hir_node(hir_id) {
-                    // If the local has no type annotation and the initializer is an unsuffixed float literal,
-                    // then the type is ambiguous
+                    // If the local has no type annotation, check if the initializer has ambiguous float literals
                     if local.ty.is_none() {
                         if let Some(init) = local.init {
-                            if let ExprKind::Lit(lit) = &init.kind {
-                                if let ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) = lit.node {
-                                    return true;
-                                }
-                            }
+                            return has_ambiguous_float_literal_in_expr(cx, init);
                         }
                     }
                 }
             }
             false
         },
-        ExprKind::Binary(_, lhs, rhs) => has_ambiguous_float_type(cx, lhs) || has_ambiguous_float_type(cx, rhs),
+        _ => false, // only check path
+    }
+}
+
+// Recursively check if an expression contains any unsuffixed float literals
+fn has_ambiguous_float_literal_in_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    match &expr.kind {
+        ExprKind::Lit(lit) => {
+            if let ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) = lit.node {
+                return true;
+            }
+            false
+        },
+        ExprKind::Binary(_, lhs, rhs) => {
+            has_ambiguous_float_literal_in_expr(cx, lhs) || has_ambiguous_float_literal_in_expr(cx, rhs)
+        },
+        ExprKind::Unary(_, expr) => has_ambiguous_float_literal_in_expr(cx, expr),
+        ExprKind::If(_, then, else_) => {
+            has_ambiguous_float_literal_in_expr(cx, then)
+                || else_
+                    .as_ref()
+                    .map_or(false, |else_expr| has_ambiguous_float_literal_in_expr(cx, else_expr))
+        },
+        ExprKind::Block(block, _) => block
+            .expr
+            .as_ref()
+            .map_or(false, |expr| has_ambiguous_float_literal_in_expr(cx, expr)),
+        ExprKind::MethodCall(_, receiver, args, _) => {
+            has_ambiguous_float_literal_in_expr(cx, receiver)
+                || args.iter().any(|arg| has_ambiguous_float_literal_in_expr(cx, arg))
+        },
+        ExprKind::Call(func, args) => {
+            has_ambiguous_float_literal_in_expr(cx, func)
+                || args.iter().any(|arg| has_ambiguous_float_literal_in_expr(cx, arg))
+        },
         _ => false,
     }
 }
diff --git a/tests/ui/floating_point_mul_add.fixed b/tests/ui/floating_point_mul_add.fixed
index 3f647730f01..b07f3a6cc69 100644
--- a/tests/ui/floating_point_mul_add.fixed
+++ b/tests/ui/floating_point_mul_add.fixed
@@ -70,10 +70,24 @@ fn _issue11831() {
     let _ = a + b * c;
 }
 
-fn _issue12331() {
+fn _issue14897() {
     let x = 1.0;
     let _ = x * 2.0 + 0.5; // should not suggest mul_add
     let _ = 0.5 + x * 2.0; // should not suggest mul_add
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+    let _ = 1.2 + x * 1.2; // should not suggest mul_add
+
+    let x = -1.0;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = { 4.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = if 1 > 2 { 1.0 } else { 2.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = 2.4 + 1.2;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
 
     let _ = 2.0f64.mul_add(x, 0.5);
     //~^ suboptimal_flops
diff --git a/tests/ui/floating_point_mul_add.rs b/tests/ui/floating_point_mul_add.rs
index 44b29a42743..8af9c51f271 100644
--- a/tests/ui/floating_point_mul_add.rs
+++ b/tests/ui/floating_point_mul_add.rs
@@ -74,6 +74,20 @@ fn _issue14897() {
     let x = 1.0;
     let _ = x * 2.0 + 0.5; // should not suggest mul_add
     let _ = 0.5 + x * 2.0; // should not suggest mul_add
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+    let _ = 1.2 + x * 1.2; // should not suggest mul_add
+
+    let x = -1.0;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = { 4.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = if 1 > 2 { 1.0 } else { 2.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = 2.4 + 1.2;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
 
     let _ = 0.5 + 2.0 * x;
     //~^ suboptimal_flops
diff --git a/tests/ui/floating_point_mul_add.stderr b/tests/ui/floating_point_mul_add.stderr
index 58d6e61bea3..80d08c7de73 100644
--- a/tests/ui/floating_point_mul_add.stderr
+++ b/tests/ui/floating_point_mul_add.stderr
@@ -80,34 +80,40 @@ LL |     let _ = a - (b * u as f64);
    |             ^^^^^^^^^^^^^^^^^^ help: consider using: `b.mul_add(-(u as f64), a)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:78:13
+  --> tests/ui/floating_point_mul_add.rs:85:13
+   |
+LL |     let _ = 0.5 + x * 1.2; // should not suggest mul_add
+   |             ^^^^^^^^^^^^^ help: consider using: `x.mul_add(1.2, 0.5)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> tests/ui/floating_point_mul_add.rs:96:13
    |
 LL |     let _ = 0.5 + 2.0 * x;
    |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(x, 0.5)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:80:13
+  --> tests/ui/floating_point_mul_add.rs:98:13
    |
 LL |     let _ = 2.0 * x + 0.5;
    |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(x, 0.5)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:83:13
+  --> tests/ui/floating_point_mul_add.rs:101:13
    |
 LL |     let _ = x + 2.0 * 4.0;
    |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, x)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:87:13
+  --> tests/ui/floating_point_mul_add.rs:105:13
    |
 LL |     let _ = y * 2.0 + 0.5;
    |             ^^^^^^^^^^^^^ help: consider using: `y.mul_add(2.0, 0.5)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:89:13
+  --> tests/ui/floating_point_mul_add.rs:107:13
    |
 LL |     let _ = 1.0 * 2.0 + 0.5;
    |             ^^^^^^^^^^^^^^^ help: consider using: `1.0f64.mul_add(2.0, 0.5)`
 
-error: aborting due to 18 previous errors
+error: aborting due to 19 previous errors