Skip to content

Commit

Permalink
Remove lint for logarithm division identity
Browse files Browse the repository at this point in the history
  • Loading branch information
krishna-veerareddy committed Feb 24, 2020
1 parent fd2506b commit bc03f46
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 182 deletions.
86 changes: 3 additions & 83 deletions clippy_lints/src/floating_point_arithmetic.rs
Expand Up @@ -4,12 +4,11 @@ use crate::consts::{
};
use crate::utils::*;
use if_chain::if_chain;
use rustc::declare_lint_pass;
use rustc::hir::*;
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc_hir::*;
use rustc_lint::{LateContext, LateLintPass};
use rustc::ty;
use rustc_errors::Applicability;
use rustc_session::declare_tool_lint;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use std::f32::consts as f32_consts;
use std::f64::consts as f64_consts;
use sugg::Sugg;
Expand Down Expand Up @@ -278,84 +277,6 @@ fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr) {
}
}

// Checks whether two expressions evaluate to the same value
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 expressions resolve to 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"];

if_chain! {
if let ExprKind::Binary(op, ref lhs, ref rhs) = expr.kind;
if op.node == BinOpKind::Div;
if cx.tables.expr_ty(lhs).is_floating_point();
if let ExprKind::MethodCall(left_path, _, left_args) = &lhs.kind;
if cx.tables.expr_ty(&left_args[0]).is_floating_point();
if let ExprKind::MethodCall(right_path, _, right_args) = &rhs.kind;
if cx.tables.expr_ty(&right_args[0]).is_floating_point();
let left_method = left_path.ident.name.as_str();
if left_method == right_path.ident.name.as_str();
if log_methods.iter().any(|&method| left_method == method);
then {
let left_recv = &left_args[0];
let right_recv = &right_args[0];

// 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
let suggestion = if let Some(method) = get_specialized_log_method(cx, right_recv) {
format!("{}.{}()", Sugg::hir(cx, left_recv, ".."), method)
} else {
format!(
"{}.log({})",
Sugg::hir(cx, left_recv, ".."),
Sugg::hir(cx, right_recv, "..")
)
};

span_lint_and_sugg(
cx,
FLOATING_POINT_IMPROVEMENTS,
expr.span,
"x.log(b) / y.log(b) can be reduced to x.log(y)",
"consider using",
suggestion,
Applicability::MachineApplicable,
);
}
}
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatingPointArithmetic {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
if let ExprKind::MethodCall(ref path, _, args) = &expr.kind {
Expand All @@ -371,7 +292,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatingPointArithmetic {
}
} else {
check_expm1(cx, expr);
check_log_division(cx, expr);
}
}
}
26 changes: 0 additions & 26 deletions tests/ui/floating_point_log.rs
Expand Up @@ -54,30 +54,4 @@ fn check_ln1p() {
let _ = (1.0 + x - 2.0).ln();
}

fn check_log_division() {
let x = 3f32;
let y = 2f32;
let b = 4f32;

let _ = x.log2() / y.log2();
let _ = x.log10() / y.log10();
let _ = x.ln() / y.ln();
let _ = x.log(4.0) / y.log(4.0);
let _ = x.log(b) / y.log(b);
let _ = x.log(b) / y.log(x);
let _ = x.log(b) / 2f32.log(b);

let x = 3f64;
let y = 2f64;
let b = 4f64;

let _ = x.log2() / y.log2();
let _ = x.log10() / y.log10();
let _ = x.ln() / y.ln();
let _ = x.log(4.0) / y.log(4.0);
let _ = x.log(b) / y.log(b);
let _ = x.log(b) / y.log(x);
let _ = x.log(b) / 2f64.log(b);
}

fn main() {}
74 changes: 1 addition & 73 deletions tests/ui/floating_point_log.stderr
Expand Up @@ -168,77 +168,5 @@ error: ln(1 + x) can be computed more accurately
LL | let _ = (x * 2.0 + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x * 2.0).ln_1p()`

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

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

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

error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_log.rs:65: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 reduced to x.log(y)
--> $DIR/floating_point_log.rs:66:13
|
LL | let _ = x.log(b) / y.log(b);
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

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

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

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

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

error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_log.rs:77: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 reduced to x.log(y)
--> $DIR/floating_point_log.rs:78:13
|
LL | let _ = x.log(b) / y.log(b);
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`

error: x.log(b) / y.log(b) can be reduced to x.log(y)
--> $DIR/floating_point_log.rs:80:13
|
LL | let _ = x.log(b) / 2f64.log(b);
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log2()`

error: aborting due to 40 previous errors
error: aborting due to 28 previous errors

0 comments on commit bc03f46

Please sign in to comment.