@@ -4,7 +4,8 @@ use crate::{
44 AtomicOrderingFence , AtomicOrderingLoad , AtomicOrderingStore , ImproperCTypes ,
55 InvalidAtomicOrderingDiag , OnlyCastu8ToChar , OverflowingBinHex , OverflowingBinHexSign ,
66 OverflowingBinHexSub , OverflowingInt , OverflowingIntHelp , OverflowingLiteral ,
7- OverflowingUInt , RangeEndpointOutOfRange , UnusedComparisons , VariantSizeDifferencesDiag ,
7+ OverflowingUInt , RangeEndpointOutOfRange , UnusedComparisons , UseInclusiveRange ,
8+ VariantSizeDifferencesDiag ,
89 } ,
910} ;
1011use crate :: { LateContext , LateLintPass , LintContext } ;
@@ -136,6 +137,14 @@ fn lint_overflowing_range_endpoint<'tcx>(
136137 expr : & ' tcx hir:: Expr < ' tcx > ,
137138 ty : & str ,
138139) -> 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+
139148 // We only want to handle exclusive (`..`) ranges,
140149 // which are represented as `ExprKind::Struct`.
141150 let par_id = cx. tcx . hir ( ) . parent_id ( expr. hir_id ) ;
@@ -155,7 +164,6 @@ fn lint_overflowing_range_endpoint<'tcx>(
155164 if !( eps[ 1 ] . expr . hir_id == expr. hir_id && lit_val - 1 == max) {
156165 return false ;
157166 } ;
158- let Ok ( start) = cx. sess ( ) . source_map ( ) . span_to_snippet ( eps[ 0 ] . span ) else { return false } ;
159167
160168 use rustc_ast:: { LitIntType , LitKind } ;
161169 let suffix = match lit. node {
@@ -164,16 +172,28 @@ fn lint_overflowing_range_endpoint<'tcx>(
164172 LitKind :: Int ( _, LitIntType :: Unsuffixed ) => "" ,
165173 _ => bug ! ( ) ,
166174 } ;
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 ( ) ) ,
173180 start,
174181 literal : lit_val - 1 ,
175182 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 } ,
177197 ) ;
178198
179199 // We've just emitted a lint, special cased for `(...)..MAX+1` ranges,
0 commit comments