@@ -5,7 +5,7 @@ use clippy_utils::msrvs::{self, Msrv};
55use clippy_utils:: source:: HasSession as _;
66use clippy_utils:: sugg:: Sugg ;
77use clippy_utils:: ty:: is_type_diagnostic_item;
8- use clippy_utils:: { eq_expr_value, peel_blocks, span_contains_comment} ;
8+ use clippy_utils:: { eq_expr_value, peel_blocks, peel_middle_ty_refs , span_contains_comment} ;
99use rustc_errors:: Applicability ;
1010use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
1111use rustc_lint:: { LateContext , LateLintPass } ;
@@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAbsDiff {
6262 && let ExprKind :: Binary ( op, rhs, lhs) = if_expr. cond . kind
6363 && let ( BinOpKind :: Gt | BinOpKind :: Ge , mut a, mut b) | ( BinOpKind :: Lt | BinOpKind :: Le , mut b, mut a) =
6464 ( op. node , rhs, lhs)
65- && let Some ( ty ) = self . are_ty_eligible ( cx, a, b)
65+ && let Some ( ( ty , b_n_refs ) ) = self . are_ty_eligible ( cx, a, b)
6666 && is_sub_expr ( cx, if_expr. then , a, b, ty)
6767 && is_sub_expr ( cx, r#else, b, a, ty)
6868 {
@@ -86,8 +86,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualAbsDiff {
8686 }
8787 } ;
8888 let sugg = format ! (
89- "{}.abs_diff({})" ,
89+ "{}.abs_diff({}{} )" ,
9090 Sugg :: hir( cx, a, ".." ) . maybe_paren( ) ,
91+ "*" . repeat( b_n_refs) ,
9192 Sugg :: hir( cx, b, ".." )
9293 ) ;
9394 diag. span_suggestion ( expr. span , "replace with `abs_diff`" , sugg, applicability) ;
@@ -100,13 +101,15 @@ impl<'tcx> LateLintPass<'tcx> for ManualAbsDiff {
100101impl ManualAbsDiff {
101102 /// Returns a type if `a` and `b` are both of it, and this lint can be applied to that
102103 /// type (currently, any primitive int, or a `Duration`)
103- fn are_ty_eligible < ' tcx > ( & self , cx : & LateContext < ' tcx > , a : & Expr < ' _ > , b : & Expr < ' _ > ) -> Option < Ty < ' tcx > > {
104+ fn are_ty_eligible < ' tcx > ( & self , cx : & LateContext < ' tcx > , a : & Expr < ' _ > , b : & Expr < ' _ > ) -> Option < ( Ty < ' tcx > , usize ) > {
104105 let is_int = |ty : Ty < ' _ > | matches ! ( ty. kind( ) , ty:: Uint ( _) | ty:: Int ( _) ) && self . msrv . meets ( cx, msrvs:: ABS_DIFF ) ;
105106 let is_duration =
106107 |ty| is_type_diagnostic_item ( cx, ty, sym:: Duration ) && self . msrv . meets ( cx, msrvs:: DURATION_ABS_DIFF ) ;
107108
108109 let a_ty = cx. typeck_results ( ) . expr_ty ( a) . peel_refs ( ) ;
109- ( a_ty == cx. typeck_results ( ) . expr_ty ( b) . peel_refs ( ) && ( is_int ( a_ty) || is_duration ( a_ty) ) ) . then_some ( a_ty)
110+ let ( b_ty, b_n_refs) = peel_middle_ty_refs ( cx. typeck_results ( ) . expr_ty ( b) ) ;
111+
112+ ( a_ty == b_ty && ( is_int ( a_ty) || is_duration ( a_ty) ) ) . then_some ( ( a_ty, b_n_refs) )
110113 }
111114}
112115
0 commit comments