@@ -107,7 +107,9 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
107107 } ) = higher:: If :: hir ( expr)
108108 && let ExprKind :: Binary ( ref cond_op, cond_left, cond_right) = cond. kind
109109 {
110- check_manual_check ( cx, cond_op, cond_left, cond_right, if_block, else_block, & self . msrv ) ;
110+ check_manual_check (
111+ cx, expr, cond_op, cond_left, cond_right, if_block, else_block, & self . msrv ,
112+ ) ;
111113 }
112114 }
113115
@@ -117,6 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
117119#[ allow( clippy:: too_many_arguments) ]
118120fn check_manual_check < ' tcx > (
119121 cx : & LateContext < ' tcx > ,
122+ expr : & Expr < ' tcx > ,
120123 condition : & BinOp ,
121124 left_hand : & Expr < ' tcx > ,
122125 right_hand : & Expr < ' tcx > ,
@@ -127,12 +130,40 @@ fn check_manual_check<'tcx>(
127130 let ty = cx. typeck_results ( ) . expr_ty ( left_hand) ;
128131 if ty. is_numeric ( ) && !ty. is_signed ( ) {
129132 match condition. node {
130- BinOpKind :: Gt | BinOpKind :: Ge => {
131- check_gt ( cx, condition. span , left_hand, right_hand, if_block, else_block, msrv) ;
132- } ,
133- BinOpKind :: Lt | BinOpKind :: Le => {
134- check_gt ( cx, condition. span , right_hand, left_hand, if_block, else_block, msrv) ;
135- } ,
133+ BinOpKind :: Gt | BinOpKind :: Ge => check_gt (
134+ cx,
135+ condition. span ,
136+ expr. span ,
137+ left_hand,
138+ right_hand,
139+ if_block,
140+ else_block,
141+ msrv,
142+ matches ! (
143+ clippy_utils:: get_parent_expr( cx, expr) ,
144+ Some ( Expr {
145+ kind: ExprKind :: If ( ..) ,
146+ ..
147+ } )
148+ ) ,
149+ ) ,
150+ BinOpKind :: Lt | BinOpKind :: Le => check_gt (
151+ cx,
152+ condition. span ,
153+ expr. span ,
154+ right_hand,
155+ left_hand,
156+ if_block,
157+ else_block,
158+ msrv,
159+ matches ! (
160+ clippy_utils:: get_parent_expr( cx, expr) ,
161+ Some ( Expr {
162+ kind: ExprKind :: If ( ..) ,
163+ ..
164+ } )
165+ ) ,
166+ ) ,
136167 _ => { } ,
137168 }
138169 }
@@ -142,16 +173,28 @@ fn check_manual_check<'tcx>(
142173fn check_gt (
143174 cx : & LateContext < ' _ > ,
144175 condition_span : Span ,
176+ expr_span : Span ,
145177 big_var : & Expr < ' _ > ,
146178 little_var : & Expr < ' _ > ,
147179 if_block : & Expr < ' _ > ,
148180 else_block : & Expr < ' _ > ,
149181 msrv : & Msrv ,
182+ is_composited : bool ,
150183) {
151184 if let Some ( big_var) = Var :: new ( big_var)
152185 && let Some ( little_var) = Var :: new ( little_var)
153186 {
154- check_subtraction ( cx, condition_span, big_var, little_var, if_block, else_block, msrv) ;
187+ check_subtraction (
188+ cx,
189+ condition_span,
190+ expr_span,
191+ big_var,
192+ little_var,
193+ if_block,
194+ else_block,
195+ msrv,
196+ is_composited,
197+ ) ;
155198 }
156199}
157200
@@ -173,11 +216,13 @@ impl Var {
173216fn check_subtraction (
174217 cx : & LateContext < ' _ > ,
175218 condition_span : Span ,
219+ expr_span : Span ,
176220 big_var : Var ,
177221 little_var : Var ,
178222 if_block : & Expr < ' _ > ,
179223 else_block : & Expr < ' _ > ,
180224 msrv : & Msrv ,
225+ is_composited : bool ,
181226) {
182227 let if_block = peel_blocks ( if_block) ;
183228 let else_block = peel_blocks ( else_block) ;
@@ -189,7 +234,17 @@ fn check_subtraction(
189234 }
190235 // If the subtraction is done in the `else` block, then we need to also revert the two
191236 // variables as it means that the check was reverted too.
192- check_subtraction ( cx, condition_span, little_var, big_var, else_block, if_block, msrv) ;
237+ check_subtraction (
238+ cx,
239+ condition_span,
240+ expr_span,
241+ little_var,
242+ big_var,
243+ else_block,
244+ if_block,
245+ msrv,
246+ is_composited,
247+ ) ;
193248 return ;
194249 }
195250 if is_integer_literal ( else_block, 0 )
@@ -205,13 +260,18 @@ fn check_subtraction(
205260 && let Some ( little_var_snippet) = snippet_opt ( cx, little_var. span )
206261 && ( !is_in_const_context ( cx) || msrv. meets ( msrvs:: SATURATING_SUB_CONST ) )
207262 {
263+ let sugg = format ! (
264+ "{}{big_var_snippet}.saturating_sub({little_var_snippet}){}" ,
265+ if is_composited { "{ " } else { "" } ,
266+ if is_composited { " }" } else { "" }
267+ ) ;
208268 span_lint_and_sugg (
209269 cx,
210270 IMPLICIT_SATURATING_SUB ,
211- else_block . span ,
271+ expr_span ,
212272 "manual arithmetic check found" ,
213273 "replace it with" ,
214- format ! ( "{big_var_snippet}.saturating_sub({little_var_snippet})" ) ,
274+ sugg ,
215275 Applicability :: MachineApplicable ,
216276 ) ;
217277 }
0 commit comments