@@ -416,7 +416,7 @@ pub enum Constructor<'tcx> {
416416 /// Literal values.
417417 ConstantValue ( & ' tcx ty:: Const < ' tcx > ) ,
418418 /// Ranges of literal values (`2...5` and `2..5`).
419- ConstantRange ( & ' tcx ty :: Const < ' tcx > , & ' tcx ty :: Const < ' tcx > , RangeEnd ) ,
419+ ConstantRange ( u128 , u128 , Ty < ' tcx > , RangeEnd ) ,
420420 /// Array patterns of length n.
421421 Slice ( u64 ) ,
422422}
@@ -588,7 +588,12 @@ impl<'tcx> Witness<'tcx> {
588588 _ => {
589589 match * ctor {
590590 ConstantValue ( value) => PatternKind :: Constant { value } ,
591- ConstantRange ( lo, hi, end) => PatternKind :: Range { lo, hi, end } ,
591+ ConstantRange ( lo, hi, ty, end) => PatternKind :: Range {
592+ lo : ty:: Const :: from_bits ( cx. tcx , lo, ty:: ParamEnv :: empty ( ) . and ( ty) ) ,
593+ hi : ty:: Const :: from_bits ( cx. tcx , hi, ty:: ParamEnv :: empty ( ) . and ( ty) ) ,
594+ ty,
595+ end,
596+ } ,
592597 _ => PatternKind :: Wild ,
593598 }
594599 }
@@ -648,34 +653,32 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
648653 . collect ( )
649654 }
650655 ty:: Char if exhaustive_integer_patterns => {
651- let endpoint = |c : char | {
652- let ty = ty:: ParamEnv :: empty ( ) . and ( cx. tcx . types . char ) ;
653- ty:: Const :: from_bits ( cx. tcx , c as u128 , ty)
654- } ;
655656 vec ! [
656657 // The valid Unicode Scalar Value ranges.
657- ConstantRange ( endpoint( '\u{0000}' ) , endpoint( '\u{D7FF}' ) , RangeEnd :: Included ) ,
658- ConstantRange ( endpoint( '\u{E000}' ) , endpoint( '\u{10FFFF}' ) , RangeEnd :: Included ) ,
658+ ConstantRange ( '\u{0000}' as u128 ,
659+ '\u{D7FF}' as u128 ,
660+ cx. tcx. types. char ,
661+ RangeEnd :: Included
662+ ) ,
663+ ConstantRange ( '\u{E000}' as u128 ,
664+ '\u{10FFFF}' as u128 ,
665+ cx. tcx. types. char ,
666+ RangeEnd :: Included
667+ ) ,
659668 ]
660669 }
661670 ty:: Int ( ity) if exhaustive_integer_patterns => {
662671 // FIXME(49937): refactor these bit manipulations into interpret.
663672 let bits = Integer :: from_attr ( cx. tcx , SignedInt ( ity) ) . size ( ) . bits ( ) as u128 ;
664673 let min = 1u128 << ( bits - 1 ) ;
665674 let max = ( 1u128 << ( bits - 1 ) ) - 1 ;
666- let ty = ty:: ParamEnv :: empty ( ) . and ( pcx. ty ) ;
667- vec ! [ ConstantRange ( ty:: Const :: from_bits( cx. tcx, min as u128 , ty) ,
668- ty:: Const :: from_bits( cx. tcx, max as u128 , ty) ,
669- RangeEnd :: Included ) ]
675+ vec ! [ ConstantRange ( min, max, pcx. ty, RangeEnd :: Included ) ]
670676 }
671677 ty:: Uint ( uty) if exhaustive_integer_patterns => {
672678 // FIXME(49937): refactor these bit manipulations into interpret.
673679 let bits = Integer :: from_attr ( cx. tcx , UnsignedInt ( uty) ) . size ( ) . bits ( ) as u128 ;
674680 let max = !0u128 >> ( 128 - bits) ;
675- let ty = ty:: ParamEnv :: empty ( ) . and ( pcx. ty ) ;
676- vec ! [ ConstantRange ( ty:: Const :: from_bits( cx. tcx, 0 , ty) ,
677- ty:: Const :: from_bits( cx. tcx, max, ty) ,
678- RangeEnd :: Included ) ]
681+ vec ! [ ConstantRange ( 0 , max, pcx. ty, RangeEnd :: Included ) ]
679682 }
680683 _ => {
681684 if cx. is_uninhabited ( pcx. ty ) {
@@ -811,26 +814,18 @@ impl<'tcx> IntRange<'tcx> {
811814 ctor : & Constructor < ' tcx > )
812815 -> Option < IntRange < ' tcx > > {
813816 match ctor {
814- ConstantRange ( lo, hi, end) => {
815- assert_eq ! ( lo. ty, hi. ty) ;
816- let ty = lo. ty ;
817- let env_ty = ty:: ParamEnv :: empty ( ) . and ( ty) ;
818- if let Some ( lo) = lo. assert_bits ( tcx, env_ty) {
819- if let Some ( hi) = hi. assert_bits ( tcx, env_ty) {
820- // Perform a shift if the underlying types are signed,
821- // which makes the interval arithmetic simpler.
822- let bias = IntRange :: signed_bias ( tcx, ty) ;
823- let ( lo, hi) = ( lo ^ bias, hi ^ bias) ;
824- // Make sure the interval is well-formed.
825- return if lo > hi || lo == hi && * end == RangeEnd :: Excluded {
826- None
827- } else {
828- let offset = ( * end == RangeEnd :: Excluded ) as u128 ;
829- Some ( IntRange { range : lo..=( hi - offset) , ty } )
830- } ;
831- }
817+ ConstantRange ( lo, hi, ty, end) => {
818+ // Perform a shift if the underlying types are signed,
819+ // which makes the interval arithmetic simpler.
820+ let bias = IntRange :: signed_bias ( tcx, ty) ;
821+ let ( lo, hi) = ( lo ^ bias, hi ^ bias) ;
822+ // Make sure the interval is well-formed.
823+ if lo > hi || lo == hi && * end == RangeEnd :: Excluded {
824+ None
825+ } else {
826+ let offset = ( * end == RangeEnd :: Excluded ) as u128 ;
827+ Some ( IntRange { range : lo..=( hi - offset) , ty } )
832828 }
833- None
834829 }
835830 ConstantValue ( val) => {
836831 let ty = val. ty ;
@@ -853,7 +848,12 @@ impl<'tcx> IntRange<'tcx> {
853848 -> Option < IntRange < ' tcx > > {
854849 Self :: from_ctor ( tcx, & match pat. kind {
855850 box PatternKind :: Constant { value } => ConstantValue ( value) ,
856- box PatternKind :: Range { lo, hi, end } => ConstantRange ( lo, hi, end) ,
851+ box PatternKind :: Range { lo, hi, ty, end } => ConstantRange (
852+ lo. to_bits ( tcx, ty:: ParamEnv :: empty ( ) . and ( ty) ) . unwrap ( ) ,
853+ hi. to_bits ( tcx, ty:: ParamEnv :: empty ( ) . and ( ty) ) . unwrap ( ) ,
854+ ty,
855+ end,
856+ ) ,
857857 _ => return None ,
858858 } )
859859 }
@@ -876,14 +876,12 @@ impl<'tcx> IntRange<'tcx> {
876876 r : RangeInclusive < u128 > ,
877877 ) -> Constructor < ' tcx > {
878878 let bias = IntRange :: signed_bias ( tcx, ty) ;
879- let ty = ty:: ParamEnv :: empty ( ) . and ( ty) ;
880879 let ( lo, hi) = r. into_inner ( ) ;
881880 if lo == hi {
881+ let ty = ty:: ParamEnv :: empty ( ) . and ( ty) ;
882882 ConstantValue ( ty:: Const :: from_bits ( tcx, lo ^ bias, ty) )
883883 } else {
884- ConstantRange ( ty:: Const :: from_bits ( tcx, lo ^ bias, ty) ,
885- ty:: Const :: from_bits ( tcx, hi ^ bias, ty) ,
886- RangeEnd :: Included )
884+ ConstantRange ( lo ^ bias, hi ^ bias, ty, RangeEnd :: Included )
887885 }
888886 }
889887
@@ -1228,8 +1226,8 @@ fn is_useful_specialized<'p, 'a:'p, 'tcx: 'a>(
12281226/// Slice patterns, however, can match slices of different lengths. For instance,
12291227/// `[a, b, ..tail]` can match a slice of length 2, 3, 4 and so on.
12301228///
1231- /// Returns ` None` in case of a catch-all, which can't be specialized.
1232- fn pat_constructors < ' tcx > ( cx : & mut MatchCheckCtxt ,
1229+ /// Returns None in case of a catch-all, which can't be specialized.
1230+ fn pat_constructors < ' tcx > ( cx : & mut MatchCheckCtxt < ' _ , ' tcx > ,
12331231 pat : & Pattern < ' tcx > ,
12341232 pcx : PatternContext )
12351233 -> Option < Vec < Constructor < ' tcx > > >
@@ -1241,7 +1239,13 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt,
12411239 Some ( vec ! [ Variant ( adt_def. variants[ variant_index] . did) ] )
12421240 }
12431241 PatternKind :: Constant { value } => Some ( vec ! [ ConstantValue ( value) ] ) ,
1244- PatternKind :: Range { lo, hi, end } => Some ( vec ! [ ConstantRange ( lo, hi, end) ] ) ,
1242+ PatternKind :: Range { lo, hi, ty, end } =>
1243+ Some ( vec ! [ ConstantRange (
1244+ lo. to_bits( cx. tcx, ty:: ParamEnv :: empty( ) . and( ty) ) . unwrap( ) ,
1245+ hi. to_bits( cx. tcx, ty:: ParamEnv :: empty( ) . and( ty) ) . unwrap( ) ,
1246+ ty,
1247+ end,
1248+ ) ] ) ,
12451249 PatternKind :: Array { .. } => match pcx. ty . sty {
12461250 ty:: Array ( _, length) => Some ( vec ! [
12471251 Slice ( length. unwrap_usize( cx. tcx) )
@@ -1381,10 +1385,13 @@ fn slice_pat_covered_by_constructor<'tcx>(
13811385// constructor is a range or constant with an integer type.
13821386fn should_treat_range_exhaustively ( tcx : TyCtxt < ' _ , ' tcx , ' tcx > , ctor : & Constructor < ' tcx > ) -> bool {
13831387 if tcx. features ( ) . exhaustive_integer_patterns {
1384- if let ConstantValue ( value) | ConstantRange ( value, _, _) = ctor {
1385- if let ty:: Char | ty:: Int ( _) | ty:: Uint ( _) = value. ty . sty {
1386- return true ;
1387- }
1388+ let ty = match ctor {
1389+ ConstantValue ( value) => value. ty ,
1390+ ConstantRange ( _, _, ty, _) => ty,
1391+ _ => return false ,
1392+ } ;
1393+ if let ty:: Char | ty:: Int ( _) | ty:: Uint ( _) = ty. sty {
1394+ return true ;
13881395 }
13891396 }
13901397 false
@@ -1535,7 +1542,7 @@ fn constructor_covered_by_range<'a, 'tcx>(
15351542) -> Result < bool , ErrorReported > {
15361543 let ( from, to, end, ty) = match pat. kind {
15371544 box PatternKind :: Constant { value } => ( value, value, RangeEnd :: Included , value. ty ) ,
1538- box PatternKind :: Range { lo, hi, end } => ( lo, hi, end, lo . ty ) ,
1545+ box PatternKind :: Range { lo, hi, ty , end } => ( lo, hi, end, ty) ,
15391546 _ => bug ! ( "`constructor_covered_by_range` called with {:?}" , pat) ,
15401547 } ;
15411548 trace ! ( "constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}" , ctor, from, to, ty) ;
@@ -1557,17 +1564,33 @@ fn constructor_covered_by_range<'a, 'tcx>(
15571564 ( end == RangeEnd :: Included && to == Ordering :: Equal ) ;
15581565 Ok ( some_or_ok ! ( cmp_from( value) ) && end)
15591566 } ,
1560- ConstantRange ( from, to, RangeEnd :: Included ) => {
1561- let to = some_or_ok ! ( cmp_to( to) ) ;
1567+ ConstantRange ( from, to, ty, RangeEnd :: Included ) => {
1568+ let to = some_or_ok ! ( cmp_to( ty:: Const :: from_bits(
1569+ tcx,
1570+ to,
1571+ ty:: ParamEnv :: empty( ) . and( ty) ,
1572+ ) ) ) ;
15621573 let end = ( to == Ordering :: Less ) ||
15631574 ( end == RangeEnd :: Included && to == Ordering :: Equal ) ;
1564- Ok ( some_or_ok ! ( cmp_from( from) ) && end)
1575+ Ok ( some_or_ok ! ( cmp_from( ty:: Const :: from_bits(
1576+ tcx,
1577+ from,
1578+ ty:: ParamEnv :: empty( ) . and( ty) ,
1579+ ) ) ) && end)
15651580 } ,
1566- ConstantRange ( from, to, RangeEnd :: Excluded ) => {
1567- let to = some_or_ok ! ( cmp_to( to) ) ;
1581+ ConstantRange ( from, to, ty, RangeEnd :: Excluded ) => {
1582+ let to = some_or_ok ! ( cmp_to( ty:: Const :: from_bits(
1583+ tcx,
1584+ to,
1585+ ty:: ParamEnv :: empty( ) . and( ty)
1586+ ) ) ) ;
15681587 let end = ( to == Ordering :: Less ) ||
15691588 ( end == RangeEnd :: Excluded && to == Ordering :: Equal ) ;
1570- Ok ( some_or_ok ! ( cmp_from( from) ) && end)
1589+ Ok ( some_or_ok ! ( cmp_from( ty:: Const :: from_bits(
1590+ tcx,
1591+ from,
1592+ ty:: ParamEnv :: empty( ) . and( ty) ) )
1593+ ) && end)
15711594 }
15721595 Single => Ok ( true ) ,
15731596 _ => bug ! ( ) ,
0 commit comments