@@ -3,7 +3,7 @@ use clippy_config::Conf;
33use clippy_utils:: diagnostics:: { span_lint_and_sugg, span_lint_and_then} ;
44use clippy_utils:: source:: snippet_opt;
55use clippy_utils:: {
6- higher, in_constant , is_integer_literal, path_to_local, peel_blocks, peel_blocks_with_stmt, SpanlessEq ,
6+ higher, is_in_const_context , is_integer_literal, path_to_local, peel_blocks, peel_blocks_with_stmt, SpanlessEq ,
77} ;
88use rustc_ast:: ast:: LitKind ;
99use rustc_data_structures:: packed:: Pu128 ;
@@ -94,9 +94,6 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
9494 if expr. span . from_expansion ( ) {
9595 return ;
9696 }
97- if in_constant ( cx, expr. hir_id ) && !self . msrv . meets ( msrvs:: SATURATING_SUB_CONST ) {
98- return ;
99- }
10097 if let Some ( higher:: If { cond, then, r#else : None } ) = higher:: If :: hir ( expr)
10198
10299 // Check if the conditional expression is a binary operation
@@ -110,13 +107,16 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
110107 } ) = higher:: If :: hir ( expr)
111108 && let ExprKind :: Binary ( ref cond_op, cond_left, cond_right) = cond. kind
112109 {
113- check_manual_check ( cx, expr, cond_op, cond_left, cond_right, if_block, else_block) ;
110+ check_manual_check (
111+ cx, expr, cond_op, cond_left, cond_right, if_block, else_block, & self . msrv ,
112+ ) ;
114113 }
115114 }
116115
117116 extract_msrv_attr ! ( LateContext ) ;
118117}
119118
119+ #[ allow( clippy:: too_many_arguments) ]
120120fn check_manual_check < ' tcx > (
121121 cx : & LateContext < ' tcx > ,
122122 expr : & Expr < ' tcx > ,
@@ -125,6 +125,7 @@ fn check_manual_check<'tcx>(
125125 right_hand : & Expr < ' tcx > ,
126126 if_block : & Expr < ' tcx > ,
127127 else_block : & Expr < ' tcx > ,
128+ msrv : & Msrv ,
128129) {
129130 let ty = cx. typeck_results ( ) . expr_ty ( left_hand) ;
130131 if ty. is_numeric ( ) && !ty. is_signed ( ) {
@@ -137,6 +138,7 @@ fn check_manual_check<'tcx>(
137138 right_hand,
138139 if_block,
139140 else_block,
141+ msrv,
140142 ) ,
141143 BinOpKind :: Lt | BinOpKind :: Le => check_gt (
142144 cx,
@@ -146,12 +148,14 @@ fn check_manual_check<'tcx>(
146148 left_hand,
147149 if_block,
148150 else_block,
151+ msrv,
149152 ) ,
150153 _ => { } ,
151154 }
152155 }
153156}
154157
158+ #[ allow( clippy:: too_many_arguments) ]
155159fn check_gt (
156160 cx : & LateContext < ' _ > ,
157161 condition_span : Span ,
@@ -160,11 +164,21 @@ fn check_gt(
160164 little_var : & Expr < ' _ > ,
161165 if_block : & Expr < ' _ > ,
162166 else_block : & Expr < ' _ > ,
167+ msrv : & Msrv ,
163168) {
164169 if let Some ( big_var) = Var :: new ( big_var)
165170 && let Some ( little_var) = Var :: new ( little_var)
166171 {
167- check_subtraction ( cx, condition_span, expr_span, big_var, little_var, if_block, else_block) ;
172+ check_subtraction (
173+ cx,
174+ condition_span,
175+ expr_span,
176+ big_var,
177+ little_var,
178+ if_block,
179+ else_block,
180+ msrv,
181+ ) ;
168182 }
169183}
170184
@@ -182,6 +196,7 @@ impl Var {
182196 }
183197}
184198
199+ #[ allow( clippy:: too_many_arguments) ]
185200fn check_subtraction (
186201 cx : & LateContext < ' _ > ,
187202 condition_span : Span ,
@@ -190,6 +205,7 @@ fn check_subtraction(
190205 little_var : Var ,
191206 if_block : & Expr < ' _ > ,
192207 else_block : & Expr < ' _ > ,
208+ msrv : & Msrv ,
193209) {
194210 let if_block = peel_blocks ( if_block) ;
195211 let else_block = peel_blocks ( else_block) ;
@@ -201,7 +217,16 @@ fn check_subtraction(
201217 }
202218 // If the subtraction is done in the `else` block, then we need to also revert the two
203219 // variables as it means that the check was reverted too.
204- check_subtraction ( cx, condition_span, expr_span, little_var, big_var, else_block, if_block) ;
220+ check_subtraction (
221+ cx,
222+ condition_span,
223+ expr_span,
224+ little_var,
225+ big_var,
226+ else_block,
227+ if_block,
228+ msrv,
229+ ) ;
205230 return ;
206231 }
207232 if is_integer_literal ( else_block, 0 )
@@ -215,6 +240,7 @@ fn check_subtraction(
215240 // if `snippet_opt` fails, it won't try the next conditions.
216241 if let Some ( big_var_snippet) = snippet_opt ( cx, big_var. span )
217242 && let Some ( little_var_snippet) = snippet_opt ( cx, little_var. span )
243+ && ( !is_in_const_context ( cx) || msrv. meets ( msrvs:: SATURATING_SUB_CONST ) )
218244 {
219245 span_lint_and_sugg (
220246 cx,
0 commit comments