Skip to content

Commit 9a77544

Browse files
committed
Lint logbase for log2 and log10
1 parent 2be203f commit 9a77544

File tree

4 files changed

+40
-4
lines changed

4 files changed

+40
-4
lines changed

clippy_lints/src/floating_point_arithmetic.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,18 @@ fn check_custom_abs(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
575575
}
576576
}
577577

578+
fn are_same_base_logs(expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool {
579+
if_chain! {
580+
if let ExprKind::MethodCall(PathSegment { ident: method_name_a, .. }, _, _) = expr_a.kind;
581+
if let ExprKind::MethodCall(PathSegment { ident: method_name_b, .. }, _, _) = expr_b.kind;
582+
then {
583+
return method_name_a.as_str() == method_name_b.as_str() && ["ln", "log2", "log10"].contains(&&*method_name_a.as_str());
584+
}
585+
}
586+
587+
false
588+
}
589+
578590
fn check_logbase(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
579591
// check if expression of the form x.logN() / y.logN()
580592
if_chain! {
@@ -585,9 +597,9 @@ fn check_logbase(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
585597
lhs,
586598
rhs,
587599
) = &expr.kind;
588-
if let ExprKind::MethodCall(PathSegment { ident: lmethod_name, .. }, _, ref largs) = lhs.kind;
589-
if let ExprKind::MethodCall(PathSegment { ident: rmethod_name, .. }, _, ref rargs) = rhs.kind;
590-
if rmethod_name.as_str() == lmethod_name.as_str();
600+
if are_same_base_logs(lhs, rhs);
601+
if let ExprKind::MethodCall(_, _, ref largs) = lhs.kind;
602+
if let ExprKind::MethodCall(_, _, ref rargs) = rhs.kind;
591603
then {
592604
span_lint_and_sugg(
593605
cx,

tests/ui/floating_point_logbase.fixed

+6
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

+6
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

+13-1
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)