@@ -416,7 +416,7 @@ pub enum Constructor<'tcx> {
416
416
/// Literal values.
417
417
ConstantValue ( & ' tcx ty:: Const < ' tcx > ) ,
418
418
/// 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 ) ,
420
420
/// Array patterns of length n.
421
421
Slice ( u64 ) ,
422
422
}
@@ -588,7 +588,12 @@ impl<'tcx> Witness<'tcx> {
588
588
_ => {
589
589
match * ctor {
590
590
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
+ } ,
592
597
_ => PatternKind :: Wild ,
593
598
}
594
599
}
@@ -648,34 +653,32 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
648
653
. collect ( )
649
654
}
650
655
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
- } ;
655
656
vec ! [
656
657
// 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
+ ) ,
659
668
]
660
669
}
661
670
ty:: Int ( ity) if exhaustive_integer_patterns => {
662
671
// FIXME(49937): refactor these bit manipulations into interpret.
663
672
let bits = Integer :: from_attr ( cx. tcx , SignedInt ( ity) ) . size ( ) . bits ( ) as u128 ;
664
673
let min = 1u128 << ( bits - 1 ) ;
665
674
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 ) ]
670
676
}
671
677
ty:: Uint ( uty) if exhaustive_integer_patterns => {
672
678
// FIXME(49937): refactor these bit manipulations into interpret.
673
679
let bits = Integer :: from_attr ( cx. tcx , UnsignedInt ( uty) ) . size ( ) . bits ( ) as u128 ;
674
680
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 ) ]
679
682
}
680
683
_ => {
681
684
if cx. is_uninhabited ( pcx. ty ) {
@@ -811,26 +814,18 @@ impl<'tcx> IntRange<'tcx> {
811
814
ctor : & Constructor < ' tcx > )
812
815
-> Option < IntRange < ' tcx > > {
813
816
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 } )
832
828
}
833
- None
834
829
}
835
830
ConstantValue ( val) => {
836
831
let ty = val. ty ;
@@ -853,7 +848,12 @@ impl<'tcx> IntRange<'tcx> {
853
848
-> Option < IntRange < ' tcx > > {
854
849
Self :: from_ctor ( tcx, & match pat. kind {
855
850
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
+ ) ,
857
857
_ => return None ,
858
858
} )
859
859
}
@@ -876,14 +876,12 @@ impl<'tcx> IntRange<'tcx> {
876
876
r : RangeInclusive < u128 > ,
877
877
) -> Constructor < ' tcx > {
878
878
let bias = IntRange :: signed_bias ( tcx, ty) ;
879
- let ty = ty:: ParamEnv :: empty ( ) . and ( ty) ;
880
879
let ( lo, hi) = r. into_inner ( ) ;
881
880
if lo == hi {
881
+ let ty = ty:: ParamEnv :: empty ( ) . and ( ty) ;
882
882
ConstantValue ( ty:: Const :: from_bits ( tcx, lo ^ bias, ty) )
883
883
} 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 )
887
885
}
888
886
}
889
887
@@ -1228,8 +1226,8 @@ fn is_useful_specialized<'p, 'a:'p, 'tcx: 'a>(
1228
1226
/// Slice patterns, however, can match slices of different lengths. For instance,
1229
1227
/// `[a, b, ..tail]` can match a slice of length 2, 3, 4 and so on.
1230
1228
///
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 > ,
1233
1231
pat : & Pattern < ' tcx > ,
1234
1232
pcx : PatternContext )
1235
1233
-> Option < Vec < Constructor < ' tcx > > >
@@ -1241,7 +1239,13 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt,
1241
1239
Some ( vec ! [ Variant ( adt_def. variants[ variant_index] . did) ] )
1242
1240
}
1243
1241
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
+ ) ] ) ,
1245
1249
PatternKind :: Array { .. } => match pcx. ty . sty {
1246
1250
ty:: Array ( _, length) => Some ( vec ! [
1247
1251
Slice ( length. unwrap_usize( cx. tcx) )
@@ -1381,10 +1385,13 @@ fn slice_pat_covered_by_constructor<'tcx>(
1381
1385
// constructor is a range or constant with an integer type.
1382
1386
fn should_treat_range_exhaustively ( tcx : TyCtxt < ' _ , ' tcx , ' tcx > , ctor : & Constructor < ' tcx > ) -> bool {
1383
1387
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 ;
1388
1395
}
1389
1396
}
1390
1397
false
@@ -1535,7 +1542,7 @@ fn constructor_covered_by_range<'a, 'tcx>(
1535
1542
) -> Result < bool , ErrorReported > {
1536
1543
let ( from, to, end, ty) = match pat. kind {
1537
1544
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) ,
1539
1546
_ => bug ! ( "`constructor_covered_by_range` called with {:?}" , pat) ,
1540
1547
} ;
1541
1548
trace ! ( "constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}" , ctor, from, to, ty) ;
@@ -1557,17 +1564,33 @@ fn constructor_covered_by_range<'a, 'tcx>(
1557
1564
( end == RangeEnd :: Included && to == Ordering :: Equal ) ;
1558
1565
Ok ( some_or_ok ! ( cmp_from( value) ) && end)
1559
1566
} ,
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
+ ) ) ) ;
1562
1573
let end = ( to == Ordering :: Less ) ||
1563
1574
( 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)
1565
1580
} ,
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
+ ) ) ) ;
1568
1587
let end = ( to == Ordering :: Less ) ||
1569
1588
( 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)
1571
1594
}
1572
1595
Single => Ok ( true ) ,
1573
1596
_ => bug ! ( ) ,
0 commit comments