@@ -52,10 +52,11 @@ use rustc_data_structures::captures::Captures;
5252use rustc_index:: vec:: Idx ;
5353
5454use rustc_hir:: { HirId , RangeEnd } ;
55+ use rustc_middle:: mir:: interpret:: ConstValue ;
5556use rustc_middle:: mir:: Field ;
5657use rustc_middle:: thir:: { FieldPat , Pat , PatKind , PatRange } ;
5758use rustc_middle:: ty:: layout:: IntegerExt ;
58- use rustc_middle:: ty:: { self , Const , Ty , TyCtxt } ;
59+ use rustc_middle:: ty:: { self , Const , ScalarInt , Ty , TyCtxt } ;
5960use rustc_session:: lint;
6061use rustc_span:: { Span , DUMMY_SP } ;
6162use rustc_target:: abi:: { Integer , Size , VariantIdx } ;
@@ -202,14 +203,18 @@ impl IntRange {
202203 let bias = IntRange :: signed_bias ( tcx, ty) ;
203204 let ( lo, hi) = ( lo ^ bias, hi ^ bias) ;
204205
205- let env = ty:: ParamEnv :: empty ( ) . and ( ty) ;
206- let lo_const = ty:: Const :: from_bits ( tcx, lo, env) ;
207- let hi_const = ty:: Const :: from_bits ( tcx, hi, env) ;
208-
209206 let kind = if lo == hi {
210- PatKind :: Constant { value : lo_const }
207+ let ty = ty:: ParamEnv :: empty ( ) . and ( ty) ;
208+ PatKind :: Constant { value : ty:: Const :: from_bits ( tcx, lo, ty) }
211209 } else {
212- PatKind :: Range ( PatRange { lo : lo_const, hi : hi_const, end : RangeEnd :: Included } )
210+ let param_env_and_ty = ty:: ParamEnv :: empty ( ) . and ( ty) ;
211+ let size = tcx. layout_of ( param_env_and_ty) . unwrap ( ) . size ;
212+ PatKind :: Range ( PatRange {
213+ lo : ScalarInt :: from_uint ( lo, size) ,
214+ hi : ScalarInt :: from_uint ( hi, size) ,
215+ end : RangeEnd :: Included ,
216+ ty,
217+ } )
213218 } ;
214219
215220 Pat { ty, span : DUMMY_SP , kind : Box :: new ( kind) }
@@ -586,7 +591,7 @@ pub(super) enum Constructor<'tcx> {
586591 /// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
587592 IntRange ( IntRange ) ,
588593 /// Ranges of floating-point literal values (`2.0..=5.2`).
589- FloatRange ( & ' tcx ty :: Const < ' tcx > , & ' tcx ty :: Const < ' tcx > , RangeEnd ) ,
594+ FloatRange ( ScalarInt , ScalarInt , RangeEnd ) ,
590595 /// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
591596 Str ( & ' tcx ty:: Const < ' tcx > ) ,
592597 /// Array and slice patterns.
@@ -647,7 +652,11 @@ impl<'tcx> Constructor<'tcx> {
647652 IntRange ( int_range)
648653 } else {
649654 match pat. ty . kind ( ) {
650- ty:: Float ( _) => FloatRange ( value, value, RangeEnd :: Included ) ,
655+ ty:: Float ( _) => {
656+ let value =
657+ value. val . eval ( cx. tcx , cx. param_env ) . try_to_scalar_int ( ) . unwrap ( ) ;
658+ FloatRange ( value, value, RangeEnd :: Included )
659+ }
651660 // In `expand_pattern`, we convert string literals to `&CONST` patterns with
652661 // `CONST` a pattern of type `str`. In truth this contains a constant of type
653662 // `&str`.
@@ -659,13 +668,13 @@ impl<'tcx> Constructor<'tcx> {
659668 }
660669 }
661670 }
662- & PatKind :: Range ( PatRange { lo, hi, end } ) => {
663- let ty = lo . ty ;
671+ & PatKind :: Range ( PatRange { lo, hi, end, ty } ) => {
672+ let size = cx . tcx . layout_of ( cx . param_env . and ( ty ) ) . unwrap ( ) . size ;
664673 if let Some ( int_range) = IntRange :: from_range (
665674 cx. tcx ,
666- lo. eval_bits ( cx . tcx , cx . param_env , lo . ty ) ,
667- hi. eval_bits ( cx . tcx , cx . param_env , hi . ty ) ,
668- ty,
675+ lo. assert_bits ( size ) ,
676+ hi. assert_bits ( size ) ,
677+ pat . ty ,
669678 & end,
670679 ) {
671680 IntRange ( int_range)
@@ -759,6 +768,26 @@ impl<'tcx> Constructor<'tcx> {
759768 FloatRange ( self_from, self_to, self_end) ,
760769 FloatRange ( other_from, other_to, other_end) ,
761770 ) => {
771+ let self_to = ty:: Const :: from_value (
772+ pcx. cx . tcx ,
773+ ConstValue :: Scalar ( ( * self_to) . into ( ) ) ,
774+ pcx. ty ,
775+ ) ;
776+ let other_to = ty:: Const :: from_value (
777+ pcx. cx . tcx ,
778+ ConstValue :: Scalar ( ( * other_to) . into ( ) ) ,
779+ pcx. ty ,
780+ ) ;
781+ let self_from = ty:: Const :: from_value (
782+ pcx. cx . tcx ,
783+ ConstValue :: Scalar ( ( * self_from) . into ( ) ) ,
784+ pcx. ty ,
785+ ) ;
786+ let other_from = ty:: Const :: from_value (
787+ pcx. cx . tcx ,
788+ ConstValue :: Scalar ( ( * other_from) . into ( ) ) ,
789+ pcx. ty ,
790+ ) ;
762791 match (
763792 compare_const_vals ( pcx. cx . tcx , self_to, other_to, pcx. cx . param_env , pcx. ty ) ,
764793 compare_const_vals ( pcx. cx . tcx , self_from, other_from, pcx. cx . param_env , pcx. ty ) ,
@@ -1253,7 +1282,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
12531282 }
12541283 } ,
12551284 & Str ( value) => PatKind :: Constant { value } ,
1256- & FloatRange ( lo, hi, end) => PatKind :: Range ( PatRange { lo, hi, end } ) ,
1285+ & FloatRange ( lo, hi, end) => PatKind :: Range ( PatRange { lo, hi, end, ty : pcx . ty } ) ,
12571286 IntRange ( range) => return range. to_pat ( pcx. cx . tcx , pcx. ty ) ,
12581287 NonExhaustive => PatKind :: Wild ,
12591288 Wildcard => return Pat :: wildcard_from_ty ( pcx. ty ) ,
0 commit comments