@@ -4,7 +4,8 @@ use crate::{
4
4
AtomicOrderingFence , AtomicOrderingLoad , AtomicOrderingStore , ImproperCTypes ,
5
5
InvalidAtomicOrderingDiag , OnlyCastu8ToChar , OverflowingBinHex , OverflowingBinHexSign ,
6
6
OverflowingBinHexSub , OverflowingInt , OverflowingIntHelp , OverflowingLiteral ,
7
- OverflowingUInt , RangeEndpointOutOfRange , UnusedComparisons , VariantSizeDifferencesDiag ,
7
+ OverflowingUInt , RangeEndpointOutOfRange , UnusedComparisons , UseInclusiveRange ,
8
+ VariantSizeDifferencesDiag ,
8
9
} ,
9
10
} ;
10
11
use crate :: { LateContext , LateLintPass , LintContext } ;
@@ -136,6 +137,14 @@ fn lint_overflowing_range_endpoint<'tcx>(
136
137
expr : & ' tcx hir:: Expr < ' tcx > ,
137
138
ty : & str ,
138
139
) -> bool {
140
+ // Look past casts to support cases like `0..256 as u8`
141
+ let ( expr, lit_span) = if let Node :: Expr ( par_expr) = cx. tcx . hir ( ) . get ( cx. tcx . hir ( ) . parent_id ( expr. hir_id ) )
142
+ && let ExprKind :: Cast ( _, _) = par_expr. kind {
143
+ ( par_expr, expr. span )
144
+ } else {
145
+ ( expr, expr. span )
146
+ } ;
147
+
139
148
// We only want to handle exclusive (`..`) ranges,
140
149
// which are represented as `ExprKind::Struct`.
141
150
let par_id = cx. tcx . hir ( ) . parent_id ( expr. hir_id ) ;
@@ -155,7 +164,6 @@ fn lint_overflowing_range_endpoint<'tcx>(
155
164
if !( eps[ 1 ] . expr . hir_id == expr. hir_id && lit_val - 1 == max) {
156
165
return false ;
157
166
} ;
158
- let Ok ( start) = cx. sess ( ) . source_map ( ) . span_to_snippet ( eps[ 0 ] . span ) else { return false } ;
159
167
160
168
use rustc_ast:: { LitIntType , LitKind } ;
161
169
let suffix = match lit. node {
@@ -164,16 +172,28 @@ fn lint_overflowing_range_endpoint<'tcx>(
164
172
LitKind :: Int ( _, LitIntType :: Unsuffixed ) => "" ,
165
173
_ => bug ! ( ) ,
166
174
} ;
167
- cx. emit_spanned_lint (
168
- OVERFLOWING_LITERALS ,
169
- struct_expr. span ,
170
- RangeEndpointOutOfRange {
171
- ty,
172
- suggestion : struct_expr. span ,
175
+
176
+ let sub_sugg = if expr. span . lo ( ) == lit_span. lo ( ) {
177
+ let Ok ( start) = cx. sess ( ) . source_map ( ) . span_to_snippet ( eps[ 0 ] . span ) else { return false } ;
178
+ UseInclusiveRange :: WithoutParen {
179
+ sugg : struct_expr. span . shrink_to_lo ( ) . to ( lit_span. shrink_to_hi ( ) ) ,
173
180
start,
174
181
literal : lit_val - 1 ,
175
182
suffix,
176
- } ,
183
+ }
184
+ } else {
185
+ UseInclusiveRange :: WithParen {
186
+ eq_sugg : expr. span . shrink_to_lo ( ) ,
187
+ lit_sugg : lit_span,
188
+ literal : lit_val - 1 ,
189
+ suffix,
190
+ }
191
+ } ;
192
+
193
+ cx. emit_spanned_lint (
194
+ OVERFLOWING_LITERALS ,
195
+ struct_expr. span ,
196
+ RangeEndpointOutOfRange { ty, sub : sub_sugg } ,
177
197
) ;
178
198
179
199
// We've just emitted a lint, special cased for `(...)..MAX+1` ranges,
0 commit comments