Skip to content

Commit 5825ae7

Browse files
committed
Auto merge of #9581 - ebobrow:mul-add-negative, r=Manishearth
`suboptimal_flops` lint for multiply and subtract fixes #9526 changelog: [`suboptimal_flops`] lint for multiply and subtract
2 parents 09e6c23 + 15431b3 commit 5825ae7

7 files changed

+81
-25
lines changed

clippy_lints/src/floating_point_arithmetic.rs

+36-12
Original file line numberDiff line numberDiff line change
@@ -311,14 +311,25 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args:
311311

312312
if let ExprKind::Binary(
313313
Spanned {
314-
node: BinOpKind::Add, ..
314+
node: op @ (BinOpKind::Add | BinOpKind::Sub),
315+
..
315316
},
316317
lhs,
317318
rhs,
318319
) = parent.kind
319320
{
320321
let other_addend = if lhs.hir_id == expr.hir_id { rhs } else { lhs };
321322

323+
// Negate expr if original code has subtraction and expr is on the right side
324+
let maybe_neg_sugg = |expr, hir_id| {
325+
let sugg = Sugg::hir(cx, expr, "..");
326+
if matches!(op, BinOpKind::Sub) && hir_id == rhs.hir_id {
327+
format!("-{sugg}")
328+
} else {
329+
sugg.to_string()
330+
}
331+
};
332+
322333
span_lint_and_sugg(
323334
cx,
324335
SUBOPTIMAL_FLOPS,
@@ -328,8 +339,8 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args:
328339
format!(
329340
"{}.mul_add({}, {})",
330341
Sugg::hir(cx, receiver, "..").maybe_par(),
331-
Sugg::hir(cx, receiver, ".."),
332-
Sugg::hir(cx, other_addend, ".."),
342+
maybe_neg_sugg(receiver, expr.hir_id),
343+
maybe_neg_sugg(other_addend, other_addend.hir_id),
333344
),
334345
Applicability::MachineApplicable,
335346
);
@@ -443,7 +454,8 @@ fn is_float_mul_expr<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(&'
443454
fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) {
444455
if let ExprKind::Binary(
445456
Spanned {
446-
node: BinOpKind::Add, ..
457+
node: op @ (BinOpKind::Add | BinOpKind::Sub),
458+
..
447459
},
448460
lhs,
449461
rhs,
@@ -457,10 +469,27 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) {
457469
}
458470
}
459471

472+
let maybe_neg_sugg = |expr| {
473+
let sugg = Sugg::hir(cx, expr, "..");
474+
if let BinOpKind::Sub = op {
475+
format!("-{sugg}")
476+
} else {
477+
sugg.to_string()
478+
}
479+
};
480+
460481
let (recv, arg1, arg2) = if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, lhs) {
461-
(inner_lhs, inner_rhs, rhs)
482+
(
483+
inner_lhs,
484+
Sugg::hir(cx, inner_rhs, "..").to_string(),
485+
maybe_neg_sugg(rhs),
486+
)
462487
} else if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, rhs) {
463-
(inner_lhs, inner_rhs, lhs)
488+
(
489+
inner_lhs,
490+
maybe_neg_sugg(inner_rhs),
491+
Sugg::hir(cx, lhs, "..").to_string(),
492+
)
464493
} else {
465494
return;
466495
};
@@ -471,12 +500,7 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) {
471500
expr.span,
472501
"multiply and add expressions can be calculated more efficiently and accurately",
473502
"consider using",
474-
format!(
475-
"{}.mul_add({}, {})",
476-
prepare_receiver_sugg(cx, recv),
477-
Sugg::hir(cx, arg1, ".."),
478-
Sugg::hir(cx, arg2, ".."),
479-
),
503+
format!("{}.mul_add({arg1}, {arg2})", prepare_receiver_sugg(cx, recv)),
480504
Applicability::MachineApplicable,
481505
);
482506
}

tests/ui/floating_point_mul_add.fixed

+2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ fn main() {
1919
let d: f64 = 0.0001;
2020

2121
let _ = a.mul_add(b, c);
22+
let _ = a.mul_add(b, -c);
2223
let _ = a.mul_add(b, c);
24+
let _ = a.mul_add(-b, c);
2325
let _ = 2.0f64.mul_add(4.0, a);
2426
let _ = 2.0f64.mul_add(4., a);
2527

tests/ui/floating_point_mul_add.rs

+2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ fn main() {
1919
let d: f64 = 0.0001;
2020

2121
let _ = a * b + c;
22+
let _ = a * b - c;
2223
let _ = c + a * b;
24+
let _ = c - a * b;
2325
let _ = a + 2.0 * 4.0;
2426
let _ = a + 2. * 4.;
2527

tests/ui/floating_point_mul_add.stderr

+21-9
Original file line numberDiff line numberDiff line change
@@ -9,56 +9,68 @@ LL | let _ = a * b + c;
99
error: multiply and add expressions can be calculated more efficiently and accurately
1010
--> $DIR/floating_point_mul_add.rs:22:13
1111
|
12+
LL | let _ = a * b - c;
13+
| ^^^^^^^^^ help: consider using: `a.mul_add(b, -c)`
14+
15+
error: multiply and add expressions can be calculated more efficiently and accurately
16+
--> $DIR/floating_point_mul_add.rs:23:13
17+
|
1218
LL | let _ = c + a * b;
1319
| ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
1420

1521
error: multiply and add expressions can be calculated more efficiently and accurately
16-
--> $DIR/floating_point_mul_add.rs:23:13
22+
--> $DIR/floating_point_mul_add.rs:24:13
23+
|
24+
LL | let _ = c - a * b;
25+
| ^^^^^^^^^ help: consider using: `a.mul_add(-b, c)`
26+
27+
error: multiply and add expressions can be calculated more efficiently and accurately
28+
--> $DIR/floating_point_mul_add.rs:25:13
1729
|
1830
LL | let _ = a + 2.0 * 4.0;
1931
| ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, a)`
2032

2133
error: multiply and add expressions can be calculated more efficiently and accurately
22-
--> $DIR/floating_point_mul_add.rs:24:13
34+
--> $DIR/floating_point_mul_add.rs:26:13
2335
|
2436
LL | let _ = a + 2. * 4.;
2537
| ^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4., a)`
2638

2739
error: multiply and add expressions can be calculated more efficiently and accurately
28-
--> $DIR/floating_point_mul_add.rs:26:13
40+
--> $DIR/floating_point_mul_add.rs:28:13
2941
|
3042
LL | let _ = (a * b) + c;
3143
| ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
3244

3345
error: multiply and add expressions can be calculated more efficiently and accurately
34-
--> $DIR/floating_point_mul_add.rs:27:13
46+
--> $DIR/floating_point_mul_add.rs:29:13
3547
|
3648
LL | let _ = c + (a * b);
3749
| ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
3850

3951
error: multiply and add expressions can be calculated more efficiently and accurately
40-
--> $DIR/floating_point_mul_add.rs:28:13
52+
--> $DIR/floating_point_mul_add.rs:30:13
4153
|
4254
LL | let _ = a * b * c + d;
4355
| ^^^^^^^^^^^^^ help: consider using: `(a * b).mul_add(c, d)`
4456

4557
error: multiply and add expressions can be calculated more efficiently and accurately
46-
--> $DIR/floating_point_mul_add.rs:30:13
58+
--> $DIR/floating_point_mul_add.rs:32:13
4759
|
4860
LL | let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c;
4961
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c))`
5062

5163
error: multiply and add expressions can be calculated more efficiently and accurately
52-
--> $DIR/floating_point_mul_add.rs:31:13
64+
--> $DIR/floating_point_mul_add.rs:33:13
5365
|
5466
LL | let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64;
5567
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1234.567_f64.mul_add(45.67834_f64, 0.0004_f64)`
5668

5769
error: multiply and add expressions can be calculated more efficiently and accurately
58-
--> $DIR/floating_point_mul_add.rs:33:13
70+
--> $DIR/floating_point_mul_add.rs:35:13
5971
|
6072
LL | let _ = (a * a + b).sqrt();
6173
| ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)`
6274

63-
error: aborting due to 10 previous errors
75+
error: aborting due to 12 previous errors
6476

tests/ui/floating_point_powi.fixed

+2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ fn main() {
88

99
let y = 4f32;
1010
let _ = x.mul_add(x, y);
11+
let _ = x.mul_add(x, -y);
1112
let _ = y.mul_add(y, x);
13+
let _ = y.mul_add(-y, x);
1214
let _ = (y as f32).mul_add(y as f32, x);
1315
let _ = x.mul_add(x, y).sqrt();
1416
let _ = y.mul_add(y, x).sqrt();

tests/ui/floating_point_powi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ fn main() {
88

99
let y = 4f32;
1010
let _ = x.powi(2) + y;
11+
let _ = x.powi(2) - y;
1112
let _ = x + y.powi(2);
13+
let _ = x - y.powi(2);
1214
let _ = x + (y as f32).powi(2);
1315
let _ = (x.powi(2) + y).sqrt();
1416
let _ = (x + y.powi(2)).sqrt();

tests/ui/floating_point_powi.stderr

+16-4
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,38 @@ LL | let _ = x.powi(2) + y;
99
error: multiply and add expressions can be calculated more efficiently and accurately
1010
--> $DIR/floating_point_powi.rs:11:13
1111
|
12+
LL | let _ = x.powi(2) - y;
13+
| ^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, -y)`
14+
15+
error: multiply and add expressions can be calculated more efficiently and accurately
16+
--> $DIR/floating_point_powi.rs:12:13
17+
|
1218
LL | let _ = x + y.powi(2);
1319
| ^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)`
1420

1521
error: multiply and add expressions can be calculated more efficiently and accurately
16-
--> $DIR/floating_point_powi.rs:12:13
22+
--> $DIR/floating_point_powi.rs:13:13
23+
|
24+
LL | let _ = x - y.powi(2);
25+
| ^^^^^^^^^^^^^ help: consider using: `y.mul_add(-y, x)`
26+
27+
error: multiply and add expressions can be calculated more efficiently and accurately
28+
--> $DIR/floating_point_powi.rs:14:13
1729
|
1830
LL | let _ = x + (y as f32).powi(2);
1931
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y as f32).mul_add(y as f32, x)`
2032

2133
error: multiply and add expressions can be calculated more efficiently and accurately
22-
--> $DIR/floating_point_powi.rs:13:13
34+
--> $DIR/floating_point_powi.rs:15:13
2335
|
2436
LL | let _ = (x.powi(2) + y).sqrt();
2537
| ^^^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)`
2638

2739
error: multiply and add expressions can be calculated more efficiently and accurately
28-
--> $DIR/floating_point_powi.rs:14:13
40+
--> $DIR/floating_point_powi.rs:16:13
2941
|
3042
LL | let _ = (x + y.powi(2)).sqrt();
3143
| ^^^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)`
3244

33-
error: aborting due to 5 previous errors
45+
error: aborting due to 7 previous errors
3446

0 commit comments

Comments
 (0)