11use hir:: { ExprKind , Node , is_range_literal} ;
22use rustc_abi:: { Integer , Size } ;
3+ use rustc_hir:: HirId ;
34use rustc_middle:: ty:: Ty ;
45use rustc_middle:: ty:: layout:: IntegerExt ;
56use rustc_middle:: { bug, ty} ;
7+ use rustc_span:: Span ;
68use { rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir} ;
79
810use crate :: LateContext ;
@@ -21,21 +23,22 @@ fn lint_overflowing_range_endpoint<'tcx>(
2123 lit : & hir:: Lit ,
2224 lit_val : u128 ,
2325 max : u128 ,
24- expr : & ' tcx hir:: Expr < ' tcx > ,
26+ hir_id : HirId ,
27+ lit_span : Span ,
2528 ty : & str ,
2629) -> bool {
2730 // Look past casts to support cases like `0..256 as u8`
28- let ( expr , lit_span ) = if let Node :: Expr ( par_expr) = cx. tcx . parent_hir_node ( expr . hir_id )
31+ let ( hir_id , span ) = if let Node :: Expr ( par_expr) = cx. tcx . parent_hir_node ( hir_id)
2932 && let ExprKind :: Cast ( _, _) = par_expr. kind
3033 {
31- ( par_expr, expr . span )
34+ ( par_expr. hir_id , par_expr . span )
3235 } else {
33- ( expr , expr . span )
36+ ( hir_id , lit_span )
3437 } ;
3538
3639 // We only want to handle exclusive (`..`) ranges,
3740 // which are represented as `ExprKind::Struct`.
38- let Node :: ExprField ( field) = cx. tcx . parent_hir_node ( expr . hir_id ) else { return false } ;
41+ let Node :: ExprField ( field) = cx. tcx . parent_hir_node ( hir_id) else { return false } ;
3942 let Node :: Expr ( struct_expr) = cx. tcx . parent_hir_node ( field. hir_id ) else { return false } ;
4043 if !is_range_literal ( struct_expr) {
4144 return false ;
@@ -45,7 +48,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
4548 // We can suggest using an inclusive range
4649 // (`..=`) instead only if it is the `end` that is
4750 // overflowing and only by 1.
48- if !( end. expr . hir_id == expr . hir_id && lit_val - 1 == max) {
51+ if !( end. expr . hir_id == hir_id && lit_val - 1 == max) {
4952 return false ;
5053 } ;
5154
@@ -57,7 +60,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
5760 _ => bug ! ( ) ,
5861 } ;
5962
60- let sub_sugg = if expr . span . lo ( ) == lit_span. lo ( ) {
63+ let sub_sugg = if span. lo ( ) == lit_span. lo ( ) {
6164 let Ok ( start) = cx. sess ( ) . source_map ( ) . span_to_snippet ( start. span ) else { return false } ;
6265 UseInclusiveRange :: WithoutParen {
6366 sugg : struct_expr. span . shrink_to_lo ( ) . to ( lit_span. shrink_to_hi ( ) ) ,
@@ -67,7 +70,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
6770 }
6871 } else {
6972 UseInclusiveRange :: WithParen {
70- eq_sugg : expr . span . shrink_to_lo ( ) ,
73+ eq_sugg : span. shrink_to_lo ( ) ,
7174 lit_sugg : lit_span,
7275 literal : lit_val - 1 ,
7376 suffix,
@@ -125,7 +128,8 @@ fn get_bin_hex_repr(cx: &LateContext<'_>, lit: &hir::Lit) -> Option<String> {
125128
126129fn report_bin_hex_error (
127130 cx : & LateContext < ' _ > ,
128- expr : & hir:: Expr < ' _ > ,
131+ hir_id : HirId ,
132+ span : Span ,
129133 ty : attr:: IntType ,
130134 size : Size ,
131135 repr_str : String ,
@@ -144,19 +148,19 @@ fn report_bin_hex_error(
144148 } ;
145149 let sign =
146150 if negative { OverflowingBinHexSign :: Negative } else { OverflowingBinHexSign :: Positive } ;
147- let sub = get_type_suggestion ( cx. typeck_results ( ) . node_type ( expr . hir_id ) , val, negative) . map (
151+ let sub = get_type_suggestion ( cx. typeck_results ( ) . node_type ( hir_id) , val, negative) . map (
148152 |suggestion_ty| {
149153 if let Some ( pos) = repr_str. chars ( ) . position ( |c| c == 'i' || c == 'u' ) {
150154 let ( sans_suffix, _) = repr_str. split_at ( pos) ;
151- OverflowingBinHexSub :: Suggestion { span : expr . span , suggestion_ty, sans_suffix }
155+ OverflowingBinHexSub :: Suggestion { span, suggestion_ty, sans_suffix }
152156 } else {
153157 OverflowingBinHexSub :: Help { suggestion_ty }
154158 }
155159 } ,
156160 ) ;
157161 let sign_bit_sub = ( !negative)
158162 . then ( || {
159- let ty:: Int ( int_ty) = cx. typeck_results ( ) . node_type ( expr . hir_id ) . kind ( ) else {
163+ let ty:: Int ( int_ty) = cx. typeck_results ( ) . node_type ( hir_id) . kind ( ) else {
160164 return None ;
161165 } ;
162166
@@ -177,7 +181,7 @@ fn report_bin_hex_error(
177181 } ;
178182
179183 Some ( OverflowingBinHexSignBitSub {
180- span : expr . span ,
184+ span,
181185 lit_no_suffix,
182186 negative_val : actually. clone ( ) ,
183187 int_ty : int_ty. name_str ( ) ,
@@ -186,7 +190,7 @@ fn report_bin_hex_error(
186190 } )
187191 . flatten ( ) ;
188192
189- cx. emit_span_lint ( OVERFLOWING_LITERALS , expr . span , OverflowingBinHex {
193+ cx. emit_span_lint ( OVERFLOWING_LITERALS , span, OverflowingBinHex {
190194 ty : t,
191195 lit : repr_str. clone ( ) ,
192196 dec : val,
@@ -236,23 +240,26 @@ fn literal_to_i128(val: u128, negative: bool) -> Option<i128> {
236240fn lint_int_literal < ' tcx > (
237241 cx : & LateContext < ' tcx > ,
238242 type_limits : & TypeLimits ,
239- e : & ' tcx hir:: Expr < ' tcx > ,
243+ hir_id : HirId ,
244+ span : Span ,
240245 lit : & hir:: Lit ,
241246 t : ty:: IntTy ,
242247 v : u128 ,
248+ negated : bool ,
243249) {
244250 let int_type = t. normalize ( cx. sess ( ) . target . pointer_width ) ;
245251 let ( min, max) = int_ty_range ( int_type) ;
246252 let max = max as u128 ;
247- let negative = type_limits. negated_expr_id == Some ( e . hir_id ) ;
253+ let negative = negated ^ ( type_limits. negated_expr_id == Some ( hir_id) ) ;
248254
249255 // Detect literal value out of range [min, max] inclusive
250256 // avoiding use of -min to prevent overflow/panic
251257 if ( negative && v > max + 1 ) || ( !negative && v > max) {
252258 if let Some ( repr_str) = get_bin_hex_repr ( cx, lit) {
253259 report_bin_hex_error (
254260 cx,
255- e,
261+ hir_id,
262+ span,
256263 attr:: IntType :: SignedInt ( ty:: ast_int_ty ( t) ) ,
257264 Integer :: from_int_ty ( cx, t) . size ( ) ,
258265 repr_str,
@@ -262,18 +269,18 @@ fn lint_int_literal<'tcx>(
262269 return ;
263270 }
264271
265- if lint_overflowing_range_endpoint ( cx, lit, v, max, e , t. name_str ( ) ) {
272+ if lint_overflowing_range_endpoint ( cx, lit, v, max, hir_id , span , t. name_str ( ) ) {
266273 // The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
267274 return ;
268275 }
269276
270- let span = if negative { type_limits. negated_expr_span . unwrap ( ) } else { e . span } ;
277+ let span = if negative { type_limits. negated_expr_span . unwrap ( ) } else { span } ;
271278 let lit = cx
272279 . sess ( )
273280 . source_map ( )
274281 . span_to_snippet ( span)
275282 . unwrap_or_else ( |_| if negative { format ! ( "-{v}" ) } else { v. to_string ( ) } ) ;
276- let help = get_type_suggestion ( cx. typeck_results ( ) . node_type ( e . hir_id ) , v, negative)
283+ let help = get_type_suggestion ( cx. typeck_results ( ) . node_type ( hir_id) , v, negative)
277284 . map ( |suggestion_ty| OverflowingIntHelp { suggestion_ty } ) ;
278285
279286 cx. emit_span_lint ( OVERFLOWING_LITERALS , span, OverflowingInt {
@@ -288,7 +295,8 @@ fn lint_int_literal<'tcx>(
288295
289296fn lint_uint_literal < ' tcx > (
290297 cx : & LateContext < ' tcx > ,
291- e : & ' tcx hir:: Expr < ' tcx > ,
298+ hir_id : HirId ,
299+ span : Span ,
292300 lit : & hir:: Lit ,
293301 t : ty:: UintTy ,
294302) {
@@ -302,7 +310,7 @@ fn lint_uint_literal<'tcx>(
302310 } ;
303311
304312 if lit_val < min || lit_val > max {
305- if let Node :: Expr ( par_e) = cx. tcx . parent_hir_node ( e . hir_id ) {
313+ if let Node :: Expr ( par_e) = cx. tcx . parent_hir_node ( hir_id) {
306314 match par_e. kind {
307315 hir:: ExprKind :: Cast ( ..) => {
308316 if let ty:: Char = cx. typeck_results ( ) . expr_ty ( par_e) . kind ( ) {
@@ -316,14 +324,15 @@ fn lint_uint_literal<'tcx>(
316324 _ => { }
317325 }
318326 }
319- if lint_overflowing_range_endpoint ( cx, lit, lit_val, max, e , t. name_str ( ) ) {
327+ if lint_overflowing_range_endpoint ( cx, lit, lit_val, max, hir_id , span , t. name_str ( ) ) {
320328 // The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
321329 return ;
322330 }
323331 if let Some ( repr_str) = get_bin_hex_repr ( cx, lit) {
324332 report_bin_hex_error (
325333 cx,
326- e,
334+ hir_id,
335+ span,
327336 attr:: IntType :: UnsignedInt ( ty:: ast_uint_ty ( t) ) ,
328337 Integer :: from_uint_ty ( cx, t) . size ( ) ,
329338 repr_str,
@@ -332,7 +341,7 @@ fn lint_uint_literal<'tcx>(
332341 ) ;
333342 return ;
334343 }
335- cx. emit_span_lint ( OVERFLOWING_LITERALS , e . span , OverflowingUInt {
344+ cx. emit_span_lint ( OVERFLOWING_LITERALS , span, OverflowingUInt {
336345 ty : t. name_str ( ) ,
337346 lit : cx
338347 . sess ( )
@@ -348,19 +357,24 @@ fn lint_uint_literal<'tcx>(
348357pub ( crate ) fn lint_literal < ' tcx > (
349358 cx : & LateContext < ' tcx > ,
350359 type_limits : & TypeLimits ,
351- e : & ' tcx hir:: Expr < ' tcx > ,
360+ hir_id : HirId ,
361+ span : Span ,
352362 lit : & hir:: Lit ,
363+ negated : bool ,
353364) {
354- match * cx. typeck_results ( ) . node_type ( e . hir_id ) . kind ( ) {
365+ match * cx. typeck_results ( ) . node_type ( hir_id) . kind ( ) {
355366 ty:: Int ( t) => {
356367 match lit. node {
357368 ast:: LitKind :: Int ( v, ast:: LitIntType :: Signed ( _) | ast:: LitIntType :: Unsuffixed ) => {
358- lint_int_literal ( cx, type_limits, e , lit, t, v. get ( ) )
369+ lint_int_literal ( cx, type_limits, hir_id , span , lit, t, v. get ( ) , negated )
359370 }
360371 _ => bug ! ( ) ,
361372 } ;
362373 }
363- ty:: Uint ( t) => lint_uint_literal ( cx, e, lit, t) ,
374+ ty:: Uint ( t) => {
375+ assert ! ( !negated) ;
376+ lint_uint_literal ( cx, hir_id, span, lit, t)
377+ }
364378 ty:: Float ( t) => {
365379 let ( is_infinite, sym) = match lit. node {
366380 ast:: LitKind :: Float ( v, _) => match t {
@@ -374,7 +388,7 @@ pub(crate) fn lint_literal<'tcx>(
374388 _ => bug ! ( ) ,
375389 } ;
376390 if is_infinite == Ok ( true ) {
377- cx. emit_span_lint ( OVERFLOWING_LITERALS , e . span , OverflowingLiteral {
391+ cx. emit_span_lint ( OVERFLOWING_LITERALS , span, OverflowingLiteral {
378392 ty : t. name_str ( ) ,
379393 lit : cx
380394 . sess ( )
0 commit comments