@@ -649,7 +649,7 @@ impl<'tcx> Constructor<'tcx> {
649
649
match self {
650
650
// Any base constructor can be used unchanged.
651
651
Single | Variant ( _) | ConstantValue ( _) | FixedLenSlice ( _) => smallvec ! [ self ] ,
652
- IntRange ( .. ) if IntRange :: should_treat_range_exhaustively ( cx. tcx , ty) => {
652
+ IntRange ( ctor_range ) if IntRange :: should_treat_range_exhaustively ( cx. tcx , ty) => {
653
653
// Splitting up a range naïvely would mean creating a separate constructor for
654
654
// every single value in the range, which is clearly impractical. We therefore want
655
655
// to keep together subranges for which the specialisation will be identical across
@@ -681,9 +681,6 @@ impl<'tcx> Constructor<'tcx> {
681
681
// essentially amounts to performing the intuitive merging operation depicted
682
682
// above.)
683
683
684
- // We only care about finding all the subranges within the range of `self`.
685
- let ctor_range = IntRange :: from_ctor ( cx. tcx , cx. param_env , & self ) . unwrap ( ) ;
686
-
687
684
/// Represents a border between 2 integers. Because the intervals spanning borders
688
685
/// must be able to cover every integer, we need to be able to represent
689
686
/// 2^128 + 1 such borders.
@@ -708,7 +705,7 @@ impl<'tcx> Constructor<'tcx> {
708
705
// class lies between 2 borders.
709
706
let row_borders = head_ctors
710
707
. iter ( )
711
- . flat_map ( |ctor| IntRange :: from_ctor ( cx . tcx , cx . param_env , ctor ) )
708
+ . flat_map ( IntRange :: from_ctor)
712
709
. flat_map ( |range| ctor_range. intersection ( cx. tcx , & range) )
713
710
. flat_map ( |range| range_borders ( range) ) ;
714
711
let ctor_borders = range_borders ( ctor_range. clone ( ) ) ;
@@ -731,7 +728,8 @@ impl<'tcx> Constructor<'tcx> {
731
728
( Border :: JustBefore ( n) , Border :: AfterMax ) => Some ( n..=u128:: MAX ) ,
732
729
( Border :: AfterMax , _) => None ,
733
730
} )
734
- . map ( |range| IntRange :: range_to_ctor ( cx. tcx , ty, range) )
731
+ . map ( |range| IntRange :: new ( ty, range) )
732
+ . map ( IntRange )
735
733
. collect ( )
736
734
}
737
735
// When not treated exhaustively, don't split ranges.
@@ -915,8 +913,8 @@ impl<'tcx> Constructor<'tcx> {
915
913
/// notation).
916
914
fn subtract_meta_constructor (
917
915
self ,
918
- tcx : TyCtxt < ' tcx > ,
919
- param_env : ty:: ParamEnv < ' tcx > ,
916
+ _tcx : TyCtxt < ' tcx > ,
917
+ _param_env : ty:: ParamEnv < ' tcx > ,
920
918
used_ctors : & Vec < Constructor < ' tcx > > ,
921
919
) -> SmallVec < [ Constructor < ' tcx > ; 1 ] > {
922
920
debug ! ( "subtract_meta_constructor {:?}" , self ) ;
@@ -1042,31 +1040,25 @@ impl<'tcx> Constructor<'tcx> {
1042
1040
1043
1041
remaining_ctors
1044
1042
}
1045
- IntRange ( ..) => {
1046
- let mut remaining_ctors = smallvec ! [ self ] ;
1043
+ IntRange ( range) => {
1044
+ let used_ranges = used_ctors. iter ( ) . flat_map ( IntRange :: from_ctor) ;
1045
+ let mut remaining_ranges: SmallVec < [ IntRange < ' tcx > ; 1 ] > = smallvec ! [ range] ;
1047
1046
1048
1047
// For each used ctor, subtract from the current set of constructors.
1049
- for used_ctor in used_ctors {
1050
- remaining_ctors = remaining_ctors
1048
+ for used_range in used_ranges {
1049
+ remaining_ranges = remaining_ranges
1051
1050
. into_iter ( )
1052
- . filter ( |ctor| ctor != used_ctor)
1053
- . flat_map ( |ctor| -> SmallVec < [ Constructor < ' tcx > ; 2 ] > {
1054
- if let Some ( interval) = IntRange :: from_ctor ( tcx, param_env, used_ctor) {
1055
- interval. subtract_from ( tcx, param_env, ctor)
1056
- } else {
1057
- smallvec ! [ ctor]
1058
- }
1059
- } )
1051
+ . flat_map ( |range| used_range. subtract_from ( range) )
1060
1052
. collect ( ) ;
1061
1053
1062
1054
// If the constructors that have been considered so far already cover
1063
1055
// the entire range of `self`, no need to look at more constructors.
1064
- if remaining_ctors . is_empty ( ) {
1056
+ if remaining_ranges . is_empty ( ) {
1065
1057
break ;
1066
1058
}
1067
1059
}
1068
1060
1069
- remaining_ctors
1061
+ remaining_ranges . into_iter ( ) . map ( IntRange ) . collect ( )
1070
1062
}
1071
1063
Wildcard | MissingConstructors ( _) => {
1072
1064
bug ! ( "shouldn't try to subtract constructor {:?}" , self )
@@ -1513,6 +1505,10 @@ struct IntRange<'tcx> {
1513
1505
}
1514
1506
1515
1507
impl < ' tcx > IntRange < ' tcx > {
1508
+ fn new ( ty : Ty < ' tcx > , range : RangeInclusive < u128 > ) -> Self {
1509
+ IntRange { ty, range }
1510
+ }
1511
+
1516
1512
#[ inline]
1517
1513
fn is_integral ( ty : Ty < ' _ > ) -> bool {
1518
1514
match ty. kind {
@@ -1597,11 +1593,7 @@ impl<'tcx> IntRange<'tcx> {
1597
1593
}
1598
1594
}
1599
1595
1600
- fn from_ctor (
1601
- _tcx : TyCtxt < ' tcx > ,
1602
- _param_env : ty:: ParamEnv < ' tcx > ,
1603
- ctor : & Constructor < ' tcx > ,
1604
- ) -> Option < IntRange < ' tcx > > {
1596
+ fn from_ctor ( ctor : & Constructor < ' tcx > ) -> Option < IntRange < ' tcx > > {
1605
1597
match ctor {
1606
1598
IntRange ( range) => Some ( range. clone ( ) ) ,
1607
1599
_ => None ,
@@ -1619,15 +1611,6 @@ impl<'tcx> IntRange<'tcx> {
1619
1611
}
1620
1612
}
1621
1613
1622
- /// Converts a `RangeInclusive` to a `Constructor`.
1623
- fn range_to_ctor (
1624
- _tcx : TyCtxt < ' tcx > ,
1625
- ty : Ty < ' tcx > ,
1626
- range : RangeInclusive < u128 > ,
1627
- ) -> Constructor < ' tcx > {
1628
- IntRange ( IntRange { ty, range } )
1629
- }
1630
-
1631
1614
/// Converts an `IntRange` to a `PatKind::Constant` or inclusive `PatKind::Range`.
1632
1615
fn to_patkind ( & self , tcx : TyCtxt < ' tcx > ) -> PatKind < ' tcx > {
1633
1616
let bias = IntRange :: signed_bias ( tcx, self . ty ) ;
@@ -1648,16 +1631,8 @@ impl<'tcx> IntRange<'tcx> {
1648
1631
1649
1632
/// Returns a collection of ranges that spans the values covered by `ctor`, subtracted
1650
1633
/// by the values covered by `self`: i.e., `ctor \ self` (in set notation).
1651
- fn subtract_from (
1652
- & self ,
1653
- tcx : TyCtxt < ' tcx > ,
1654
- param_env : ty:: ParamEnv < ' tcx > ,
1655
- ctor : Constructor < ' tcx > ,
1656
- ) -> SmallVec < [ Constructor < ' tcx > ; 2 ] > {
1657
- let range = match IntRange :: from_ctor ( tcx, param_env, & ctor) {
1658
- None => return smallvec ! [ ] ,
1659
- Some ( int_range) => int_range. range ,
1660
- } ;
1634
+ fn subtract_from ( & self , other : Self ) -> SmallVec < [ Self ; 2 ] > {
1635
+ let range = other. range ;
1661
1636
1662
1637
let ty = self . ty ;
1663
1638
let ( lo, hi) = ( * self . range . start ( ) , * self . range . end ( ) ) ;
@@ -1666,17 +1641,17 @@ impl<'tcx> IntRange<'tcx> {
1666
1641
if lo > range_hi || range_lo > hi {
1667
1642
// The pattern doesn't intersect with the range at all,
1668
1643
// so the range remains untouched.
1669
- remaining_ranges. push ( Self :: range_to_ctor ( tcx , ty, range_lo..=range_hi) ) ;
1644
+ remaining_ranges. push ( Self :: new ( ty, range_lo..=range_hi) ) ;
1670
1645
} else {
1671
1646
if lo > range_lo {
1672
1647
// The pattern intersects an upper section of the
1673
1648
// range, so a lower section will remain.
1674
- remaining_ranges. push ( Self :: range_to_ctor ( tcx , ty, range_lo..=( lo - 1 ) ) ) ;
1649
+ remaining_ranges. push ( Self :: new ( ty, range_lo..=( lo - 1 ) ) ) ;
1675
1650
}
1676
1651
if hi < range_hi {
1677
1652
// The pattern intersects a lower section of the
1678
1653
// range, so an upper section will remain.
1679
- remaining_ranges. push ( Self :: range_to_ctor ( tcx , ty, ( hi + 1 ) ..=range_hi) ) ;
1654
+ remaining_ranges. push ( Self :: new ( ty, ( hi + 1 ) ..=range_hi) ) ;
1680
1655
}
1681
1656
}
1682
1657
remaining_ranges
0 commit comments