@@ -8,7 +8,6 @@ use rustc_hir::{BinOpKind, Expr, ExprKind};
88use rustc_lint:: { LateContext , LateLintPass } ;
99use rustc_middle:: ty:: Ty ;
1010use rustc_session:: impl_lint_pass;
11- use rustc_span:: source_map:: Spanned ;
1211use rustc_span:: sym;
1312
1413declare_clippy_lint ! {
@@ -84,43 +83,38 @@ impl_lint_pass!(UncheckedTimeSubtraction => [MANUAL_INSTANT_ELAPSED, UNCHECKED_T
8483
8584impl LateLintPass < ' _ > for UncheckedTimeSubtraction {
8685 fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & ' _ Expr < ' _ > ) {
87- if let ExprKind :: Binary (
88- Spanned {
89- node : BinOpKind :: Sub , ..
86+ let ( lhs, rhs) = match expr. kind {
87+ ExprKind :: Binary ( op, lhs, rhs) if matches ! ( op. node, BinOpKind :: Sub , ) => ( lhs, rhs) ,
88+ ExprKind :: MethodCall ( fn_name, lhs, [ rhs] , _) if cx. ty_based_def ( expr) . is_diag_item ( cx, sym:: sub) => {
89+ ( lhs, rhs)
9090 } ,
91- lhs,
92- rhs,
93- ) = expr. kind
94- {
95- let typeck = cx. typeck_results ( ) ;
96- let lhs_ty = typeck. expr_ty ( lhs) ;
97- let rhs_ty = typeck. expr_ty ( rhs) ;
91+ _ => return ,
92+ } ;
93+ let typeck = cx. typeck_results ( ) ;
94+ let lhs_ty = typeck. expr_ty ( lhs) ;
95+ let rhs_ty = typeck. expr_ty ( rhs) ;
9896
99- if lhs_ty. is_diag_item ( cx, sym:: Instant ) {
100- // Instant::now() - instant
101- if is_instant_now_call ( cx, lhs)
102- && rhs_ty. is_diag_item ( cx, sym:: Instant )
103- && let Some ( sugg) = Sugg :: hir_opt ( cx, rhs)
104- {
105- print_manual_instant_elapsed_sugg ( cx, expr, sugg) ;
106- }
107- // instant - duration
108- else if rhs_ty. is_diag_item ( cx, sym:: Duration )
109- && !expr. span . from_expansion ( )
110- && self . msrv . meets ( cx, msrvs:: TRY_FROM )
111- {
112- print_unchecked_duration_subtraction_sugg ( cx, lhs, rhs, expr) ;
113- }
97+ if lhs_ty. is_diag_item ( cx, sym:: Instant ) {
98+ // Instant::now() - instant
99+ if is_instant_now_call ( cx, lhs) && rhs_ty. is_diag_item ( cx, sym:: Instant ) {
100+ print_manual_instant_elapsed_sugg ( cx, expr, rhs) ;
114101 }
115- // duration - duration
116- else if lhs_ty. is_diag_item ( cx, sym:: Duration )
117- && rhs_ty. is_diag_item ( cx, sym:: Duration )
102+ // instant - duration
103+ else if rhs_ty. is_diag_item ( cx, sym:: Duration )
118104 && !expr. span . from_expansion ( )
119105 && self . msrv . meets ( cx, msrvs:: TRY_FROM )
120106 {
121107 print_unchecked_duration_subtraction_sugg ( cx, lhs, rhs, expr) ;
122108 }
123109 }
110+ // duration - duration
111+ else if lhs_ty. is_diag_item ( cx, sym:: Duration )
112+ && rhs_ty. is_diag_item ( cx, sym:: Duration )
113+ && !expr. span . from_expansion ( )
114+ && self . msrv . meets ( cx, msrvs:: TRY_FROM )
115+ {
116+ print_unchecked_duration_subtraction_sugg ( cx, lhs, rhs, expr) ;
117+ }
124118 }
125119}
126120
@@ -153,15 +147,17 @@ fn is_time_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
153147 ty. is_diag_item ( cx, sym:: Duration ) || ty. is_diag_item ( cx, sym:: Instant )
154148}
155149
156- fn print_manual_instant_elapsed_sugg ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , sugg : Sugg < ' _ > ) {
150+ fn print_manual_instant_elapsed_sugg ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , rhs : & Expr < ' _ > ) {
151+ let mut applicability = Applicability :: MachineApplicable ;
152+ let sugg = Sugg :: hir_with_context ( cx, rhs, expr. span . ctxt ( ) , "<instant>" , & mut applicability) ;
157153 span_lint_and_sugg (
158154 cx,
159155 MANUAL_INSTANT_ELAPSED ,
160156 expr. span ,
161157 "manual implementation of `Instant::elapsed`" ,
162158 "try" ,
163159 format ! ( "{}.elapsed()" , sugg. maybe_paren( ) ) ,
164- Applicability :: MachineApplicable ,
160+ applicability ,
165161 ) ;
166162}
167163
@@ -181,8 +177,9 @@ fn print_unchecked_duration_subtraction_sugg(
181177 // avoid suggestions
182178 if !is_chained_time_subtraction ( cx, left_expr) {
183179 let mut applicability = Applicability :: MachineApplicable ;
184- let left_sugg = Sugg :: hir_with_applicability ( cx, left_expr, "<left>" , & mut applicability) ;
185- let right_sugg = Sugg :: hir_with_applicability ( cx, right_expr, "<right>" , & mut applicability) ;
180+ let left_sugg = Sugg :: hir_with_context ( cx, left_expr, expr. span . ctxt ( ) , "<left>" , & mut applicability) ;
181+ let right_sugg =
182+ Sugg :: hir_with_context ( cx, right_expr, expr. span . ctxt ( ) , "<right>" , & mut applicability) ;
186183
187184 diag. span_suggestion (
188185 expr. span ,
0 commit comments