@@ -129,10 +129,20 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
129
129
hi : mir:: ConstantKind < ' tcx > ,
130
130
end : RangeEnd ,
131
131
span : Span ,
132
+ lo_expr : Option < & hir:: Expr < ' tcx > > ,
133
+ hi_expr : Option < & hir:: Expr < ' tcx > > ,
132
134
) -> PatKind < ' tcx > {
133
135
assert_eq ! ( lo. ty( ) , ty) ;
134
136
assert_eq ! ( hi. ty( ) , ty) ;
135
137
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
+ } ;
136
146
match ( end, cmp) {
137
147
// `x..y` where `x < y`.
138
148
// Non-empty because the range includes at least `x`.
@@ -141,7 +151,27 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
141
151
}
142
152
// `x..y` where `x >= y`. The range is empty => error.
143
153
( 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
+ }
145
175
PatKind :: Wild
146
176
}
147
177
// `x..=y` where `x == y`.
@@ -152,10 +182,34 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
152
182
}
153
183
// `x..=y` where `x > y` hence the range is empty => error.
154
184
( 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
+ }
159
213
PatKind :: Wild
160
214
}
161
215
}
@@ -201,7 +255,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
201
255
202
256
let ( lp, hp) = ( lo. as_ref ( ) . map ( |( x, _) | x) , hi. as_ref ( ) . map ( |( x, _) | x) ) ;
203
257
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
+ }
205
261
None => {
206
262
let msg = & format ! (
207
263
"found bad range pattern `{:?}` outside of error recovery" ,
0 commit comments