1
1
use hir:: { ExprKind , Node , is_range_literal} ;
2
2
use rustc_abi:: { Integer , Size } ;
3
+ use rustc_hir:: HirId ;
3
4
use rustc_middle:: ty:: Ty ;
4
5
use rustc_middle:: ty:: layout:: IntegerExt ;
5
6
use rustc_middle:: { bug, ty} ;
7
+ use rustc_span:: Span ;
6
8
use { rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir} ;
7
9
8
10
use crate :: LateContext ;
@@ -21,21 +23,22 @@ fn lint_overflowing_range_endpoint<'tcx>(
21
23
lit : & hir:: Lit ,
22
24
lit_val : u128 ,
23
25
max : u128 ,
24
- expr : & ' tcx hir:: Expr < ' tcx > ,
26
+ hir_id : HirId ,
27
+ lit_span : Span ,
25
28
ty : & str ,
26
29
) -> bool {
27
30
// 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)
29
32
&& let ExprKind :: Cast ( _, _) = par_expr. kind
30
33
{
31
- ( par_expr, expr . span )
34
+ ( par_expr. hir_id , par_expr . span )
32
35
} else {
33
- ( expr , expr . span )
36
+ ( hir_id , lit_span )
34
37
} ;
35
38
36
39
// We only want to handle exclusive (`..`) ranges,
37
40
// 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 } ;
39
42
let Node :: Expr ( struct_expr) = cx. tcx . parent_hir_node ( field. hir_id ) else { return false } ;
40
43
if !is_range_literal ( struct_expr) {
41
44
return false ;
@@ -45,7 +48,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
45
48
// We can suggest using an inclusive range
46
49
// (`..=`) instead only if it is the `end` that is
47
50
// 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) {
49
52
return false ;
50
53
} ;
51
54
@@ -57,7 +60,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
57
60
_ => bug ! ( ) ,
58
61
} ;
59
62
60
- let sub_sugg = if expr . span . lo ( ) == lit_span. lo ( ) {
63
+ let sub_sugg = if span. lo ( ) == lit_span. lo ( ) {
61
64
let Ok ( start) = cx. sess ( ) . source_map ( ) . span_to_snippet ( start. span ) else { return false } ;
62
65
UseInclusiveRange :: WithoutParen {
63
66
sugg : struct_expr. span . shrink_to_lo ( ) . to ( lit_span. shrink_to_hi ( ) ) ,
@@ -67,7 +70,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
67
70
}
68
71
} else {
69
72
UseInclusiveRange :: WithParen {
70
- eq_sugg : expr . span . shrink_to_lo ( ) ,
73
+ eq_sugg : span. shrink_to_lo ( ) ,
71
74
lit_sugg : lit_span,
72
75
literal : lit_val - 1 ,
73
76
suffix,
@@ -125,7 +128,8 @@ fn get_bin_hex_repr(cx: &LateContext<'_>, lit: &hir::Lit) -> Option<String> {
125
128
126
129
fn report_bin_hex_error (
127
130
cx : & LateContext < ' _ > ,
128
- expr : & hir:: Expr < ' _ > ,
131
+ hir_id : HirId ,
132
+ span : Span ,
129
133
ty : attr:: IntType ,
130
134
size : Size ,
131
135
repr_str : String ,
@@ -144,19 +148,19 @@ fn report_bin_hex_error(
144
148
} ;
145
149
let sign =
146
150
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 (
148
152
|suggestion_ty| {
149
153
if let Some ( pos) = repr_str. chars ( ) . position ( |c| c == 'i' || c == 'u' ) {
150
154
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 }
152
156
} else {
153
157
OverflowingBinHexSub :: Help { suggestion_ty }
154
158
}
155
159
} ,
156
160
) ;
157
161
let sign_bit_sub = ( !negative)
158
162
. 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 {
160
164
return None ;
161
165
} ;
162
166
@@ -177,7 +181,7 @@ fn report_bin_hex_error(
177
181
} ;
178
182
179
183
Some ( OverflowingBinHexSignBitSub {
180
- span : expr . span ,
184
+ span,
181
185
lit_no_suffix,
182
186
negative_val : actually. clone ( ) ,
183
187
int_ty : int_ty. name_str ( ) ,
@@ -186,7 +190,7 @@ fn report_bin_hex_error(
186
190
} )
187
191
. flatten ( ) ;
188
192
189
- cx. emit_span_lint ( OVERFLOWING_LITERALS , expr . span , OverflowingBinHex {
193
+ cx. emit_span_lint ( OVERFLOWING_LITERALS , span, OverflowingBinHex {
190
194
ty : t,
191
195
lit : repr_str. clone ( ) ,
192
196
dec : val,
@@ -236,23 +240,25 @@ fn literal_to_i128(val: u128, negative: bool) -> Option<i128> {
236
240
fn lint_int_literal < ' tcx > (
237
241
cx : & LateContext < ' tcx > ,
238
242
type_limits : & TypeLimits ,
239
- e : & ' tcx hir:: Expr < ' tcx > ,
243
+ hir_id : HirId ,
244
+ span : Span ,
240
245
lit : & hir:: Lit ,
241
246
t : ty:: IntTy ,
242
247
v : u128 ,
243
248
) {
244
249
let int_type = t. normalize ( cx. sess ( ) . target . pointer_width ) ;
245
250
let ( min, max) = int_ty_range ( int_type) ;
246
251
let max = max as u128 ;
247
- let negative = type_limits. negated_expr_id == Some ( e . hir_id ) ;
252
+ let negative = type_limits. negated_expr_id == Some ( hir_id) ;
248
253
249
254
// Detect literal value out of range [min, max] inclusive
250
255
// avoiding use of -min to prevent overflow/panic
251
256
if ( negative && v > max + 1 ) || ( !negative && v > max) {
252
257
if let Some ( repr_str) = get_bin_hex_repr ( cx, lit) {
253
258
report_bin_hex_error (
254
259
cx,
255
- e,
260
+ hir_id,
261
+ span,
256
262
attr:: IntType :: SignedInt ( ty:: ast_int_ty ( t) ) ,
257
263
Integer :: from_int_ty ( cx, t) . size ( ) ,
258
264
repr_str,
@@ -262,18 +268,18 @@ fn lint_int_literal<'tcx>(
262
268
return ;
263
269
}
264
270
265
- if lint_overflowing_range_endpoint ( cx, lit, v, max, e , t. name_str ( ) ) {
271
+ if lint_overflowing_range_endpoint ( cx, lit, v, max, hir_id , span , t. name_str ( ) ) {
266
272
// The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
267
273
return ;
268
274
}
269
275
270
- let span = if negative { type_limits. negated_expr_span . unwrap ( ) } else { e . span } ;
276
+ let span = if negative { type_limits. negated_expr_span . unwrap ( ) } else { span } ;
271
277
let lit = cx
272
278
. sess ( )
273
279
. source_map ( )
274
280
. span_to_snippet ( span)
275
281
. 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)
282
+ let help = get_type_suggestion ( cx. typeck_results ( ) . node_type ( hir_id) , v, negative)
277
283
. map ( |suggestion_ty| OverflowingIntHelp { suggestion_ty } ) ;
278
284
279
285
cx. emit_span_lint ( OVERFLOWING_LITERALS , span, OverflowingInt {
@@ -288,7 +294,8 @@ fn lint_int_literal<'tcx>(
288
294
289
295
fn lint_uint_literal < ' tcx > (
290
296
cx : & LateContext < ' tcx > ,
291
- e : & ' tcx hir:: Expr < ' tcx > ,
297
+ hir_id : HirId ,
298
+ span : Span ,
292
299
lit : & hir:: Lit ,
293
300
t : ty:: UintTy ,
294
301
) {
@@ -302,7 +309,7 @@ fn lint_uint_literal<'tcx>(
302
309
} ;
303
310
304
311
if lit_val < min || lit_val > max {
305
- if let Node :: Expr ( par_e) = cx. tcx . parent_hir_node ( e . hir_id ) {
312
+ if let Node :: Expr ( par_e) = cx. tcx . parent_hir_node ( hir_id) {
306
313
match par_e. kind {
307
314
hir:: ExprKind :: Cast ( ..) => {
308
315
if let ty:: Char = cx. typeck_results ( ) . expr_ty ( par_e) . kind ( ) {
@@ -316,14 +323,15 @@ fn lint_uint_literal<'tcx>(
316
323
_ => { }
317
324
}
318
325
}
319
- if lint_overflowing_range_endpoint ( cx, lit, lit_val, max, e , t. name_str ( ) ) {
326
+ if lint_overflowing_range_endpoint ( cx, lit, lit_val, max, hir_id , span , t. name_str ( ) ) {
320
327
// The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
321
328
return ;
322
329
}
323
330
if let Some ( repr_str) = get_bin_hex_repr ( cx, lit) {
324
331
report_bin_hex_error (
325
332
cx,
326
- e,
333
+ hir_id,
334
+ span,
327
335
attr:: IntType :: UnsignedInt ( ty:: ast_uint_ty ( t) ) ,
328
336
Integer :: from_uint_ty ( cx, t) . size ( ) ,
329
337
repr_str,
@@ -332,7 +340,7 @@ fn lint_uint_literal<'tcx>(
332
340
) ;
333
341
return ;
334
342
}
335
- cx. emit_span_lint ( OVERFLOWING_LITERALS , e . span , OverflowingUInt {
343
+ cx. emit_span_lint ( OVERFLOWING_LITERALS , span, OverflowingUInt {
336
344
ty : t. name_str ( ) ,
337
345
lit : cx
338
346
. sess ( )
@@ -348,19 +356,20 @@ fn lint_uint_literal<'tcx>(
348
356
pub ( crate ) fn lint_literal < ' tcx > (
349
357
cx : & LateContext < ' tcx > ,
350
358
type_limits : & TypeLimits ,
351
- e : & ' tcx hir:: Expr < ' tcx > ,
359
+ hir_id : HirId ,
360
+ span : Span ,
352
361
lit : & hir:: Lit ,
353
362
) {
354
- match * cx. typeck_results ( ) . node_type ( e . hir_id ) . kind ( ) {
363
+ match * cx. typeck_results ( ) . node_type ( hir_id) . kind ( ) {
355
364
ty:: Int ( t) => {
356
365
match lit. node {
357
366
ast:: LitKind :: Int ( v, ast:: LitIntType :: Signed ( _) | ast:: LitIntType :: Unsuffixed ) => {
358
- lint_int_literal ( cx, type_limits, e , lit, t, v. get ( ) )
367
+ lint_int_literal ( cx, type_limits, hir_id , span , lit, t, v. get ( ) )
359
368
}
360
369
_ => bug ! ( ) ,
361
370
} ;
362
371
}
363
- ty:: Uint ( t) => lint_uint_literal ( cx, e , lit, t) ,
372
+ ty:: Uint ( t) => lint_uint_literal ( cx, hir_id , span , lit, t) ,
364
373
ty:: Float ( t) => {
365
374
let ( is_infinite, sym) = match lit. node {
366
375
ast:: LitKind :: Float ( v, _) => match t {
@@ -374,7 +383,7 @@ pub(crate) fn lint_literal<'tcx>(
374
383
_ => bug ! ( ) ,
375
384
} ;
376
385
if is_infinite == Ok ( true ) {
377
- cx. emit_span_lint ( OVERFLOWING_LITERALS , e . span , OverflowingLiteral {
386
+ cx. emit_span_lint ( OVERFLOWING_LITERALS , span, OverflowingLiteral {
378
387
ty : t. name_str ( ) ,
379
388
lit : cx
380
389
. sess ( )
0 commit comments