11use clippy_utils:: {
22 diagnostics:: { self , span_lint_and_sugg} ,
3- meets_msrv, msrvs, source, ty,
3+ meets_msrv, msrvs, source,
4+ sugg:: Sugg ,
5+ ty,
46} ;
57use rustc_errors:: Applicability ;
68use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
@@ -78,45 +80,41 @@ impl_lint_pass!(InstantSubtraction => [MANUAL_INSTANT_ELAPSED, UNCHECKED_DURATIO
7880
7981impl LateLintPass < ' _ > for InstantSubtraction {
8082 fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & ' _ Expr < ' _ > ) {
81- if let ExprKind :: Binary ( Spanned { node : BinOpKind :: Sub , ..} , lhs, rhs) = expr. kind
82- && check_instant_now_call ( cx, lhs)
83- && let ty_resolved = cx. typeck_results ( ) . expr_ty ( rhs)
84- && let rustc_middle:: ty:: Adt ( def, _) = ty_resolved. kind ( )
85- && clippy_utils:: match_def_path ( cx, def. did ( ) , & clippy_utils:: paths:: INSTANT )
86- && let Some ( sugg) = clippy_utils:: sugg:: Sugg :: hir_opt ( cx, rhs)
83+ if let ExprKind :: Binary (
84+ Spanned {
85+ node : BinOpKind :: Sub , ..
86+ } ,
87+ lhs,
88+ rhs,
89+ ) = expr. kind
8790 {
88- span_lint_and_sugg (
89- cx,
90- MANUAL_INSTANT_ELAPSED ,
91- expr. span ,
92- "manual implementation of `Instant::elapsed`" ,
93- "try" ,
94- format ! ( "{}.elapsed()" , sugg. maybe_par( ) ) ,
95- Applicability :: MachineApplicable ,
96- ) ;
97- }
98-
99- if expr. span . from_expansion ( ) || !meets_msrv ( self . msrv , msrvs:: TRY_FROM ) {
100- return ;
101- }
102-
103- if_chain ! {
104- if let ExprKind :: Binary ( op, lhs, rhs) = expr. kind;
105-
106- if let BinOpKind :: Sub = op. node;
107-
108- // get types of left and right side
109- if is_an_instant( cx, lhs) ;
110- if is_a_duration( cx, rhs) ;
111-
112- then {
113- print_lint_and_sugg( cx, lhs, rhs, expr)
91+ if_chain ! {
92+ if is_instant_now_call( cx, lhs) ;
93+
94+ if is_an_instant( cx, rhs) ;
95+ if let Some ( sugg) = Sugg :: hir_opt( cx, rhs) ;
96+
97+ then {
98+ print_manual_instant_elapsed_sugg( cx, expr, sugg)
99+ } else {
100+ if_chain! {
101+ if !expr. span. from_expansion( ) ;
102+ if meets_msrv( self . msrv, msrvs:: TRY_FROM ) ;
103+
104+ if is_an_instant( cx, lhs) ;
105+ if is_a_duration( cx, rhs) ;
106+
107+ then {
108+ print_unchecked_duration_subtraction_sugg( cx, lhs, rhs, expr)
109+ }
110+ }
111+ }
114112 }
115113 }
116114 }
117115}
118116
119- fn check_instant_now_call ( cx : & LateContext < ' _ > , expr_block : & ' _ Expr < ' _ > ) -> bool {
117+ fn is_instant_now_call ( cx : & LateContext < ' _ > , expr_block : & ' _ Expr < ' _ > ) -> bool {
120118 if let ExprKind :: Call ( fn_expr, [ ] ) = expr_block. kind
121119 && let Some ( fn_id) = clippy_utils:: path_def_id ( cx, fn_expr)
122120 && clippy_utils:: match_def_path ( cx, fn_id, & clippy_utils:: paths:: INSTANT_NOW )
@@ -141,7 +139,24 @@ fn is_a_duration(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
141139 ty:: is_type_diagnostic_item ( cx, expr_ty, sym:: Duration )
142140}
143141
144- fn print_lint_and_sugg ( cx : & LateContext < ' _ > , left_expr : & Expr < ' _ > , right_expr : & Expr < ' _ > , expr : & Expr < ' _ > ) {
142+ fn print_manual_instant_elapsed_sugg ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , sugg : Sugg < ' _ > ) {
143+ span_lint_and_sugg (
144+ cx,
145+ MANUAL_INSTANT_ELAPSED ,
146+ expr. span ,
147+ "manual implementation of `Instant::elapsed`" ,
148+ "try" ,
149+ format ! ( "{}.elapsed()" , sugg. maybe_par( ) ) ,
150+ Applicability :: MachineApplicable ,
151+ ) ;
152+ }
153+
154+ fn print_unchecked_duration_subtraction_sugg (
155+ cx : & LateContext < ' _ > ,
156+ left_expr : & Expr < ' _ > ,
157+ right_expr : & Expr < ' _ > ,
158+ expr : & Expr < ' _ > ,
159+ ) {
145160 let mut applicability = Applicability :: MachineApplicable ;
146161
147162 let left_expr =
0 commit comments