Skip to content

Commit c8a640c

Browse files
committed
Lint logbase for log2 and log10
1 parent 48b6124 commit c8a640c

File tree

4 files changed

+40
-4
lines changed

4 files changed

+40
-4
lines changed

clippy_lints/src/floating_point_arithmetic.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,18 @@ fn check_custom_abs(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
573573
}
574574
}
575575

576+
fn are_same_base_logs(expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool {
577+
if_chain! {
578+
if let ExprKind::MethodCall(PathSegment { ident: method_name_a, .. }, _, _) = expr_a.kind;
579+
if let ExprKind::MethodCall(PathSegment { ident: method_name_b, .. }, _, _) = expr_b.kind;
580+
then {
581+
return method_name_a.as_str() == method_name_b.as_str() && ["ln", "log2", "log10"].contains(&&*method_name_a.as_str());
582+
}
583+
}
584+
585+
false
586+
}
587+
576588
fn check_logbase(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
577589
// check if expression of the form x.logN() / y.logN()
578590
if_chain! {
@@ -583,9 +595,9 @@ fn check_logbase(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
583595
lhs,
584596
rhs,
585597
) = &expr.kind;
586-
if let ExprKind::MethodCall(PathSegment { ident: lmethod_name, .. }, _, ref largs) = lhs.kind;
587-
if let ExprKind::MethodCall(PathSegment { ident: rmethod_name, .. }, _, ref rargs) = rhs.kind;
588-
if rmethod_name.as_str() == lmethod_name.as_str();
598+
if are_same_base_logs(lhs, rhs);
599+
if let ExprKind::MethodCall(_, _, ref largs) = lhs.kind;
600+
if let ExprKind::MethodCall(_, _, ref rargs) = rhs.kind;
589601
then {
590602
span_lint_and_sugg(
591603
cx,

tests/ui/floating_point_logbase.fixed

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,10 @@ fn main() {
55
let x = 3f32;
66
let y = 5f32;
77
let _ = x.log(y);
8+
let _ = x.log(y);
9+
let _ = x.log(y);
10+
// Cases where the lint shouldn't be applied
11+
let _ = x.ln() / y.powf(3.2);
12+
let _ = x.powf(3.2) / y.powf(3.2);
13+
let _ = x.powf(3.2) / y.ln();
814
}

tests/ui/floating_point_logbase.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,10 @@ fn main() {
55
let x = 3f32;
66
let y = 5f32;
77
let _ = x.ln() / y.ln();
8+
let _ = x.log2() / y.log2();
9+
let _ = x.log10() / y.log10();
10+
// Cases where the lint shouldn't be applied
11+
let _ = x.ln() / y.powf(3.2);
12+
let _ = x.powf(3.2) / y.powf(3.2);
13+
let _ = x.powf(3.2) / y.ln();
814
}

tests/ui/floating_point_logbase.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,17 @@ LL | let _ = x.ln() / y.ln();
66
|
77
= note: `-D clippy::suboptimal-flops` implied by `-D warnings`
88

9-
error: aborting due to previous error
9+
error: division of logarithms can be calculated more efficiently and accurately
10+
--> $DIR/floating_point_logbase.rs:8:13
11+
|
12+
LL | let _ = x.log2() / y.log2();
13+
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
14+
15+
error: division of logarithms can be calculated more efficiently and accurately
16+
--> $DIR/floating_point_logbase.rs:9:13
17+
|
18+
LL | let _ = x.log10() / y.log10();
19+
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
20+
21+
error: aborting due to 3 previous errors
1022

0 commit comments

Comments
 (0)