Reclassify powi(2) lint under suboptimal_flops

This commit is contained in:
Thiago Arrais 2020-06-22 14:16:27 -03:00
parent 6dc066fdb9
commit 6be9491eac
4 changed files with 75 additions and 46 deletions

View File

@ -294,37 +294,56 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
}
fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
// Check argument
if let Some((value, _)) = constant(cx, cx.tables(), &args[1]) {
// TODO: need more specific check. this is too wide. remember also to include tests
if let Some(parent) = get_parent_expr(cx, expr) {
if let Some(grandparent) = get_parent_expr(cx, parent) {
if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, _, args, _) = grandparent.kind {
if method_name.as_str() == "sqrt" && detect_hypot(cx, args).is_some() {
return;
if value == Int(2) {
if let Some(parent) = get_parent_expr(cx, expr) {
if let Some(grandparent) = get_parent_expr(cx, parent) {
if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, _, args, _) = grandparent.kind {
if method_name.as_str() == "sqrt" && detect_hypot(cx, args).is_some() {
return;
}
}
}
if let ExprKind::Binary(
Spanned {
node: BinOpKind::Add, ..
},
ref lhs,
ref rhs,
) = parent.kind
{
let other_addend = if lhs.hir_id == expr.hir_id { rhs } else { lhs };
span_lint_and_sugg(
cx,
SUBOPTIMAL_FLOPS,
parent.span,
"square can be computed more efficiently",
"consider using",
format!(
"{}.mul_add({}, {})",
Sugg::hir(cx, &args[0], ".."),
Sugg::hir(cx, &args[0], ".."),
Sugg::hir(cx, &other_addend, ".."),
),
Applicability::MachineApplicable,
);
return;
}
}
}
let (lint, help, suggestion) = match value {
Int(2) => (
IMPRECISE_FLOPS,
"square can be computed more accurately",
span_lint_and_sugg(
cx,
SUBOPTIMAL_FLOPS,
expr.span,
"square can be computed more efficiently",
"consider using",
format!("{} * {}", Sugg::hir(cx, &args[0], ".."), Sugg::hir(cx, &args[0], "..")),
),
_ => return,
};
span_lint_and_sugg(
cx,
lint,
expr.span,
help,
"consider using",
suggestion,
Applicability::MachineApplicable,
);
Applicability::MachineApplicable,
);
}
}
}

View File

@ -1,5 +1,5 @@
// run-rustfix
#![warn(clippy::imprecise_flops)]
#![warn(clippy::suboptimal_flops)]
fn main() {
let one = 1;
@ -8,10 +8,12 @@ fn main() {
let _ = x * x;
let y = 4f32;
let _ = (x * x + y).sqrt();
let _ = (x + y * y).sqrt();
let _ = x.mul_add(x, y);
let _ = y.mul_add(y, x);
let _ = x.mul_add(x, y).sqrt();
let _ = y.mul_add(y, x).sqrt();
// Cases where the lint shouldn't be applied
let _ = x.powi(3);
let _ = x.powi(one + 1);
let _ = x.hypot(y);
let _ = (x.powi(2) + y.powi(2)).sqrt();
}

View File

@ -1,5 +1,5 @@
// run-rustfix
#![warn(clippy::imprecise_flops)]
#![warn(clippy::suboptimal_flops)]
fn main() {
let one = 1;
@ -8,6 +8,8 @@ fn main() {
let _ = x.powi(1 + 1);
let y = 4f32;
let _ = x.powi(2) + y;
let _ = x + y.powi(2);
let _ = (x.powi(2) + y).sqrt();
let _ = (x + y.powi(2)).sqrt();
// Cases where the lint shouldn't be applied

View File

@ -1,34 +1,40 @@
error: square can be computed more accurately
error: square can be computed more efficiently
--> $DIR/floating_point_powi.rs:7:13
|
LL | let _ = x.powi(2);
| ^^^^^^^^^ help: consider using: `x * x`
|
= note: `-D clippy::imprecise-flops` implied by `-D warnings`
= note: `-D clippy::suboptimal-flops` implied by `-D warnings`
error: square can be computed more accurately
error: square can be computed more efficiently
--> $DIR/floating_point_powi.rs:8:13
|
LL | let _ = x.powi(1 + 1);
| ^^^^^^^^^^^^^ help: consider using: `x * x`
error: square can be computed more accurately
--> $DIR/floating_point_powi.rs:11:14
error: square can be computed more efficiently
--> $DIR/floating_point_powi.rs:11:13
|
LL | let _ = x.powi(2) + y;
| ^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)`
error: square can be computed more efficiently
--> $DIR/floating_point_powi.rs:12:13
|
LL | let _ = x + y.powi(2);
| ^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)`
error: square can be computed more efficiently
--> $DIR/floating_point_powi.rs:13:13
|
LL | let _ = (x.powi(2) + y).sqrt();
| ^^^^^^^^^ help: consider using: `x * x`
| ^^^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)`
error: square can be computed more accurately
--> $DIR/floating_point_powi.rs:12:18
error: square can be computed more efficiently
--> $DIR/floating_point_powi.rs:14:13
|
LL | let _ = (x + y.powi(2)).sqrt();
| ^^^^^^^^^ help: consider using: `y * y`
| ^^^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)`
error: hypotenuse can be computed more accurately
--> $DIR/floating_point_powi.rs:16:13
|
LL | let _ = (x.powi(2) + y.powi(2)).sqrt();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.hypot(y)`
error: aborting due to 5 previous errors
error: aborting due to 6 previous errors