@@ -54,9 +54,10 @@ use rustc_index::vec::Idx;
5454
5555use rustc_hir:: def_id:: DefId ;
5656use rustc_hir:: { HirId , RangeEnd } ;
57+ use rustc_middle:: mir:: interpret:: ConstValue ;
5758use rustc_middle:: mir:: Field ;
5859use rustc_middle:: ty:: layout:: IntegerExt ;
59- use rustc_middle:: ty:: { self , Const , Ty , TyCtxt } ;
60+ use rustc_middle:: ty:: { self , Const , ScalarInt , Ty , TyCtxt } ;
6061use rustc_session:: lint;
6162use rustc_span:: { Span , DUMMY_SP } ;
6263use rustc_target:: abi:: { Integer , Size , VariantIdx } ;
@@ -203,14 +204,18 @@ impl IntRange {
203204 let bias = IntRange :: signed_bias ( tcx, ty) ;
204205 let ( lo, hi) = ( lo ^ bias, hi ^ bias) ;
205206
206- let env = ty:: ParamEnv :: empty ( ) . and ( ty) ;
207- let lo_const = ty:: Const :: from_bits ( tcx, lo, env) ;
208- let hi_const = ty:: Const :: from_bits ( tcx, hi, env) ;
209-
210207 let kind = if lo == hi {
211- PatKind :: Constant { value : lo_const }
208+ let ty = ty:: ParamEnv :: empty ( ) . and ( ty) ;
209+ PatKind :: Constant { value : ty:: Const :: from_bits ( tcx, lo, ty) }
212210 } else {
213- PatKind :: Range ( PatRange { lo : lo_const, hi : hi_const, end : RangeEnd :: Included } )
211+ let param_env_and_ty = ty:: ParamEnv :: empty ( ) . and ( ty) ;
212+ let size = tcx. layout_of ( param_env_and_ty) . unwrap ( ) . size ;
213+ PatKind :: Range ( PatRange {
214+ lo : ScalarInt :: from_uint ( lo, size) ,
215+ hi : ScalarInt :: from_uint ( hi, size) ,
216+ end : RangeEnd :: Included ,
217+ ty,
218+ } )
214219 } ;
215220
216221 Pat { ty, span : DUMMY_SP , kind : Box :: new ( kind) }
@@ -587,7 +592,7 @@ pub(super) enum Constructor<'tcx> {
587592 /// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
588593 IntRange ( IntRange ) ,
589594 /// Ranges of floating-point literal values (`2.0..=5.2`).
590- FloatRange ( & ' tcx ty :: Const < ' tcx > , & ' tcx ty :: Const < ' tcx > , RangeEnd ) ,
595+ FloatRange ( ScalarInt , ScalarInt , RangeEnd ) ,
591596 /// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
592597 Str ( & ' tcx ty:: Const < ' tcx > ) ,
593598 /// Array and slice patterns.
@@ -650,7 +655,11 @@ impl<'tcx> Constructor<'tcx> {
650655 IntRange ( int_range)
651656 } else {
652657 match pat. ty . kind ( ) {
653- ty:: Float ( _) => FloatRange ( value, value, RangeEnd :: Included ) ,
658+ ty:: Float ( _) => {
659+ let value =
660+ value. val . eval ( cx. tcx , cx. param_env ) . try_to_scalar_int ( ) . unwrap ( ) ;
661+ FloatRange ( value, value, RangeEnd :: Included )
662+ }
654663 // In `expand_pattern`, we convert string literals to `&CONST` patterns with
655664 // `CONST` a pattern of type `str`. In truth this contains a constant of type
656665 // `&str`.
@@ -662,13 +671,13 @@ impl<'tcx> Constructor<'tcx> {
662671 }
663672 }
664673 }
665- & PatKind :: Range ( PatRange { lo, hi, end } ) => {
666- let ty = lo . ty ;
674+ & PatKind :: Range ( PatRange { lo, hi, end, ty } ) => {
675+ let size = cx . tcx . layout_of ( cx . param_env . and ( ty ) ) . unwrap ( ) . size ;
667676 if let Some ( int_range) = IntRange :: from_range (
668677 cx. tcx ,
669- lo. eval_bits ( cx . tcx , cx . param_env , lo . ty ) ,
670- hi. eval_bits ( cx . tcx , cx . param_env , hi . ty ) ,
671- ty,
678+ lo. assert_bits ( size ) ,
679+ hi. assert_bits ( size ) ,
680+ pat . ty ,
672681 & end,
673682 ) {
674683 IntRange ( int_range)
@@ -762,6 +771,26 @@ impl<'tcx> Constructor<'tcx> {
762771 FloatRange ( self_from, self_to, self_end) ,
763772 FloatRange ( other_from, other_to, other_end) ,
764773 ) => {
774+ let self_to = ty:: Const :: from_value (
775+ pcx. cx . tcx ,
776+ ConstValue :: Scalar ( ( * self_to) . into ( ) ) ,
777+ pcx. ty ,
778+ ) ;
779+ let other_to = ty:: Const :: from_value (
780+ pcx. cx . tcx ,
781+ ConstValue :: Scalar ( ( * other_to) . into ( ) ) ,
782+ pcx. ty ,
783+ ) ;
784+ let self_from = ty:: Const :: from_value (
785+ pcx. cx . tcx ,
786+ ConstValue :: Scalar ( ( * self_from) . into ( ) ) ,
787+ pcx. ty ,
788+ ) ;
789+ let other_from = ty:: Const :: from_value (
790+ pcx. cx . tcx ,
791+ ConstValue :: Scalar ( ( * other_from) . into ( ) ) ,
792+ pcx. ty ,
793+ ) ;
765794 match (
766795 compare_const_vals ( pcx. cx . tcx , self_to, other_to, pcx. cx . param_env , pcx. ty ) ,
767796 compare_const_vals ( pcx. cx . tcx , self_from, other_from, pcx. cx . param_env , pcx. ty ) ,
@@ -1256,7 +1285,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
12561285 }
12571286 } ,
12581287 & Str ( value) => PatKind :: Constant { value } ,
1259- & FloatRange ( lo, hi, end) => PatKind :: Range ( PatRange { lo, hi, end } ) ,
1288+ & FloatRange ( lo, hi, end) => PatKind :: Range ( PatRange { lo, hi, end, ty : pcx . ty } ) ,
12601289 IntRange ( range) => return range. to_pat ( pcx. cx . tcx , pcx. ty ) ,
12611290 NonExhaustive => PatKind :: Wild ,
12621291 Wildcard => return Pat :: wildcard_from_ty ( pcx. ty ) ,
0 commit comments