@@ -573,6 +573,50 @@ fn check_custom_abs(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
573
573
}
574
574
}
575
575
576
+ fn are_same_base_logs ( cx : & LateContext < ' _ , ' _ > , expr_a : & Expr < ' _ > , expr_b : & Expr < ' _ > ) -> bool {
577
+ if_chain ! {
578
+ if let ExprKind :: MethodCall ( PathSegment { ident: method_name_a, .. } , _, ref args_a) = expr_a. kind;
579
+ if let ExprKind :: MethodCall ( PathSegment { ident: method_name_b, .. } , _, ref args_b) = expr_b. kind;
580
+ then {
581
+ return method_name_a. as_str( ) == method_name_b. as_str( ) &&
582
+ args_a. len( ) == args_b. len( ) &&
583
+ (
584
+ [ "ln" , "log2" , "log10" ] . contains( &&* method_name_a. as_str( ) ) ||
585
+ method_name_a. as_str( ) == "log" && args_a. len( ) == 2 && are_exprs_equal( cx, & args_a[ 1 ] , & args_b[ 1 ] )
586
+ ) ;
587
+ }
588
+ }
589
+
590
+ false
591
+ }
592
+
593
+ fn check_log_division ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > ) {
594
+ // check if expression of the form x.logN() / y.logN()
595
+ if_chain ! {
596
+ if let ExprKind :: Binary (
597
+ Spanned {
598
+ node: BinOpKind :: Div , ..
599
+ } ,
600
+ lhs,
601
+ rhs,
602
+ ) = & expr. kind;
603
+ if are_same_base_logs( cx, lhs, rhs) ;
604
+ if let ExprKind :: MethodCall ( _, _, ref largs) = lhs. kind;
605
+ if let ExprKind :: MethodCall ( _, _, ref rargs) = rhs. kind;
606
+ then {
607
+ span_lint_and_sugg(
608
+ cx,
609
+ SUBOPTIMAL_FLOPS ,
610
+ expr. span,
611
+ "division of logarithms can be calculated more efficiently and accurately" ,
612
+ "consider using" ,
613
+ format!( "{}.log({})" , Sugg :: hir( cx, & largs[ 0 ] , ".." ) , Sugg :: hir( cx, & rargs[ 0 ] , ".." ) , ) ,
614
+ Applicability :: MachineApplicable ,
615
+ ) ;
616
+ }
617
+ }
618
+ }
619
+
576
620
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for FloatingPointArithmetic {
577
621
fn check_expr ( & mut self , cx : & LateContext < ' a , ' tcx > , expr : & ' tcx Expr < ' _ > ) {
578
622
if let ExprKind :: MethodCall ( ref path, _, args) = & expr. kind {
@@ -592,6 +636,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatingPointArithmetic {
592
636
check_expm1 ( cx, expr) ;
593
637
check_mul_add ( cx, expr) ;
594
638
check_custom_abs ( cx, expr) ;
639
+ check_log_division ( cx, expr) ;
595
640
}
596
641
}
597
642
}
0 commit comments