@@ -129,10 +129,20 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
129129 hi : mir:: ConstantKind < ' tcx > ,
130130 end : RangeEnd ,
131131 span : Span ,
132+ lo_expr : Option < & hir:: Expr < ' tcx > > ,
133+ hi_expr : Option < & hir:: Expr < ' tcx > > ,
132134 ) -> PatKind < ' tcx > {
133135 assert_eq ! ( lo. ty( ) , ty) ;
134136 assert_eq ! ( hi. ty( ) , ty) ;
135137 let cmp = compare_const_vals ( self . tcx , lo, hi, self . param_env ) ;
138+ let max = || {
139+ self . tcx
140+ . layout_of ( self . param_env . with_reveal_all_normalized ( self . tcx ) . and ( ty) )
141+ . ok ( )
142+ . unwrap ( )
143+ . size
144+ . unsigned_int_max ( )
145+ } ;
136146 match ( end, cmp) {
137147 // `x..y` where `x < y`.
138148 // Non-empty because the range includes at least `x`.
@@ -141,7 +151,27 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
141151 }
142152 // `x..y` where `x >= y`. The range is empty => error.
143153 ( RangeEnd :: Excluded , _) => {
144- self . tcx . sess . emit_err ( LowerRangeBoundMustBeLessThanUpper { span } ) ;
154+ let mut lower_overflow = false ;
155+ let mut higher_overflow = false ;
156+ if let Some ( hir:: Expr { kind : hir:: ExprKind :: Lit ( lit) , .. } ) = lo_expr
157+ && let rustc_ast:: ast:: LitKind :: Int ( val, _) = lit. node
158+ {
159+ if lo. eval_bits ( self . tcx , self . param_env , ty) != val {
160+ lower_overflow = true ;
161+ self . tcx . sess . emit_err ( LiteralOutOfRange { span : lit. span , ty, max : max ( ) } ) ;
162+ }
163+ }
164+ if let Some ( hir:: Expr { kind : hir:: ExprKind :: Lit ( lit) , .. } ) = hi_expr
165+ && let rustc_ast:: ast:: LitKind :: Int ( val, _) = lit. node
166+ {
167+ if hi. eval_bits ( self . tcx , self . param_env , ty) != val {
168+ higher_overflow = true ;
169+ self . tcx . sess . emit_err ( LiteralOutOfRange { span : lit. span , ty, max : max ( ) } ) ;
170+ }
171+ }
172+ if !lower_overflow && !higher_overflow {
173+ self . tcx . sess . emit_err ( LowerRangeBoundMustBeLessThanUpper { span } ) ;
174+ }
145175 PatKind :: Wild
146176 }
147177 // `x..=y` where `x == y`.
@@ -152,10 +182,34 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
152182 }
153183 // `x..=y` where `x > y` hence the range is empty => error.
154184 ( RangeEnd :: Included , _) => {
155- self . tcx . sess . emit_err ( LowerRangeBoundMustBeLessThanOrEqualToUpper {
156- span,
157- teach : if self . tcx . sess . teach ( & error_code ! ( E0030 ) ) { Some ( ( ) ) } else { None } ,
158- } ) ;
185+ let mut lower_overflow = false ;
186+ let mut higher_overflow = false ;
187+ if let Some ( hir:: Expr { kind : hir:: ExprKind :: Lit ( lit) , .. } ) = lo_expr
188+ && let rustc_ast:: ast:: LitKind :: Int ( val, _) = lit. node
189+ {
190+ if lo. eval_bits ( self . tcx , self . param_env , ty) != val {
191+ lower_overflow = true ;
192+ self . tcx . sess . emit_err ( LiteralOutOfRange { span : lit. span , ty, max : max ( ) } ) ;
193+ }
194+ }
195+ if let Some ( hir:: Expr { kind : hir:: ExprKind :: Lit ( lit) , .. } ) = hi_expr
196+ && let rustc_ast:: ast:: LitKind :: Int ( val, _) = lit. node
197+ {
198+ if hi. eval_bits ( self . tcx , self . param_env , ty) != val {
199+ higher_overflow = true ;
200+ self . tcx . sess . emit_err ( LiteralOutOfRange { span : lit. span , ty, max : max ( ) } ) ;
201+ }
202+ }
203+ if !lower_overflow && !higher_overflow {
204+ self . tcx . sess . emit_err ( LowerRangeBoundMustBeLessThanOrEqualToUpper {
205+ span,
206+ teach : if self . tcx . sess . teach ( & error_code ! ( E0030 ) ) {
207+ Some ( ( ) )
208+ } else {
209+ None
210+ } ,
211+ } ) ;
212+ }
159213 PatKind :: Wild
160214 }
161215 }
@@ -201,7 +255,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
201255
202256 let ( lp, hp) = ( lo. as_ref ( ) . map ( |( x, _) | x) , hi. as_ref ( ) . map ( |( x, _) | x) ) ;
203257 let mut kind = match self . normalize_range_pattern_ends ( ty, lp, hp) {
204- Some ( ( lc, hc) ) => self . lower_pattern_range ( ty, lc, hc, end, lo_span) ,
258+ Some ( ( lc, hc) ) => {
259+ self . lower_pattern_range ( ty, lc, hc, end, lo_span, lo_expr, hi_expr)
260+ }
205261 None => {
206262 let msg = & format ! (
207263 "found bad range pattern `{:?}` outside of error recovery" ,
0 commit comments