@@ -5,7 +5,7 @@ use clippy_utils::msrvs::{self, Msrv};
5
5
use clippy_utils:: source:: HasSession as _;
6
6
use clippy_utils:: sugg:: Sugg ;
7
7
use 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} ;
9
9
use rustc_errors:: Applicability ;
10
10
use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
11
11
use rustc_lint:: { LateContext , LateLintPass } ;
@@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAbsDiff {
62
62
&& let ExprKind :: Binary ( op, rhs, lhs) = if_expr. cond . kind
63
63
&& let ( BinOpKind :: Gt | BinOpKind :: Ge , mut a, mut b) | ( BinOpKind :: Lt | BinOpKind :: Le , mut b, mut a) =
64
64
( 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)
66
66
&& is_sub_expr ( cx, if_expr. then , a, b, ty)
67
67
&& is_sub_expr ( cx, r#else, b, a, ty)
68
68
{
@@ -86,8 +86,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualAbsDiff {
86
86
}
87
87
} ;
88
88
let sugg = format ! (
89
- "{}.abs_diff({})" ,
89
+ "{}.abs_diff({}{} )" ,
90
90
Sugg :: hir( cx, a, ".." ) . maybe_paren( ) ,
91
+ "*" . repeat( b_n_refs) ,
91
92
Sugg :: hir( cx, b, ".." )
92
93
) ;
93
94
diag. span_suggestion ( expr. span , "replace with `abs_diff`" , sugg, applicability) ;
@@ -100,13 +101,15 @@ impl<'tcx> LateLintPass<'tcx> for ManualAbsDiff {
100
101
impl ManualAbsDiff {
101
102
/// Returns a type if `a` and `b` are both of it, and this lint can be applied to that
102
103
/// 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 ) > {
104
105
let is_int = |ty : Ty < ' _ > | matches ! ( ty. kind( ) , ty:: Uint ( _) | ty:: Int ( _) ) && self . msrv . meets ( cx, msrvs:: ABS_DIFF ) ;
105
106
let is_duration =
106
107
|ty| is_type_diagnostic_item ( cx, ty, sym:: Duration ) && self . msrv . meets ( cx, msrvs:: DURATION_ABS_DIFF ) ;
107
108
108
109
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) )
110
113
}
111
114
}
112
115
0 commit comments