Skip to content

Commit

Permalink
Reduce cognitive complexity
Browse files Browse the repository at this point in the history
  • Loading branch information
krishna-veerareddy committed Dec 20, 2019
1 parent 20319e8 commit dca37f5
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 39 deletions.
63 changes: 36 additions & 27 deletions clippy_lints/src/floating_point_arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,38 @@ fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr) {
}
}

// Expressions are considered equivalent if they are constant and evaluate to the
// same value or if they refer to the same variable.
fn are_exprs_equivalent(cx: &LateContext<'_, '_>, left: &Expr, right: &Expr) -> bool {
// Checks whether the values are constant and equal
if_chain! {
if let Some((left_value, _)) = constant(cx, cx.tables, left);
if let Some((right_value, _)) = constant(cx, cx.tables, right);
if left_value == right_value;
then {
return true;
}
}

// Checks whether the values are the same variable
if_chain! {
if let ExprKind::Path(ref left_qpath) = left.kind;
if let QPath::Resolved(_, ref left_path) = *left_qpath;
if left_path.segments.len() == 1;
if let def::Res::Local(left_local_id) = qpath_res(cx, left_qpath, left.hir_id);
if let ExprKind::Path(ref right_qpath) = right.kind;
if let QPath::Resolved(_, ref right_path) = *right_qpath;
if right_path.segments.len() == 1;
if let def::Res::Local(right_local_id) = qpath_res(cx, right_qpath, right.hir_id);
if left_local_id == right_local_id;
then {
return true;
}
}

false
}

fn check_log_division(cx: &LateContext<'_, '_>, expr: &Expr) {
let log_methods = ["log", "log2", "log10", "ln"];

Expand All @@ -250,32 +282,9 @@ fn check_log_division(cx: &LateContext<'_, '_>, expr: &Expr) {
let left_recv = &left_args[0];
let right_recv = &right_args[0];

if left_method == "log" {
if_chain! {
// Checks whether the bases are constant and equal
if let Some((numerator_base, _)) = constant(cx, cx.tables, &left_args[1]);
if let Some((denominator_base, _)) = constant(cx, cx.tables, &right_args[1]);
if numerator_base == denominator_base;
then { }
else {
if_chain! {
// Checks whether the bases are the same variable
if let ExprKind::Path(ref left_base_qpath) = &left_args[1].kind;
if let QPath::Resolved(_, ref left_base_path) = *left_base_qpath;
if left_base_path.segments.len() == 1;
if let def::Res::Local(left_local_id) = qpath_res(cx, left_base_qpath, expr.hir_id);
if let ExprKind::Path(ref right_base_qpath) = &right_args[1].kind;
if let QPath::Resolved(_, ref right_base_path) = *right_base_qpath;
if right_base_path.segments.len() == 1;
if let def::Res::Local(right_local_id) = qpath_res(cx, right_base_qpath, expr.hir_id);
if left_local_id == right_local_id;
then { }
else {
return;
}
}
}
}
// Return early when bases are not equal
if left_method == "log" && !are_exprs_equivalent(cx, &left_args[1], &right_args[1]) {
return;
}

// Reduce the expression further for bases 2, 10 and e
Expand All @@ -293,7 +302,7 @@ fn check_log_division(cx: &LateContext<'_, '_>, expr: &Expr) {
cx,
FLOATING_POINT_IMPROVEMENTS,
expr.span,
"x.log(b) / y.log(b) can be expressed more succinctly",
"x.log(b) / y.log(b) can be reduced to x.log(y)",
"consider using",
suggestion,
Applicability::MachineApplicable,
Expand Down
24 changes: 12 additions & 12 deletions tests/ui/floating_point_arithmetic.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -192,73 +192,73 @@ error: (e.pow(x) - 1) can be computed more accurately
LL | let _ = x.exp() - 1.0 + 2.0;
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:90:13
|
LL | let _ = x.log2() / y.log2();
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:91:13
|
LL | let _ = x.log10() / y.log10();
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:92:13
|
LL | let _ = x.ln() / y.ln();
| ^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:93:13
|
LL | let _ = x.log(4.0) / y.log(4.0);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:94:13
|
LL | let _ = x.log(b) / y.log(b);
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:96:13
|
LL | let _ = x.log(b) / 2f32.log(b);
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log2()`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:102:13
|
LL | let _ = x.log2() / y.log2();
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:103:13
|
LL | let _ = x.log10() / y.log10();
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:104:13
|
LL | let _ = x.ln() / y.ln();
| ^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:105:13
|
LL | let _ = x.log(4.0) / y.log(4.0);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:106:13
|
LL | let _ = x.log(b) / y.log(b);
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

error: x.log(b) / y.log(b) can be expressed more succinctly
error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_arithmetic.rs:108:13
|
LL | let _ = x.log(b) / 2f64.log(b);
Expand Down

0 comments on commit dca37f5

Please sign in to comment.