@@ -649,7 +649,7 @@ impl<'tcx> Constructor<'tcx> {
649649 match self {
650650 // Any base constructor can be used unchanged.
651651 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) => {
653653 // Splitting up a range naïvely would mean creating a separate constructor for
654654 // every single value in the range, which is clearly impractical. We therefore want
655655 // to keep together subranges for which the specialisation will be identical across
@@ -681,9 +681,6 @@ impl<'tcx> Constructor<'tcx> {
681681 // essentially amounts to performing the intuitive merging operation depicted
682682 // above.)
683683
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-
687684 /// Represents a border between 2 integers. Because the intervals spanning borders
688685 /// must be able to cover every integer, we need to be able to represent
689686 /// 2^128 + 1 such borders.
@@ -708,7 +705,7 @@ impl<'tcx> Constructor<'tcx> {
708705 // class lies between 2 borders.
709706 let row_borders = head_ctors
710707 . iter ( )
711- . flat_map ( |ctor| IntRange :: from_ctor ( cx . tcx , cx . param_env , ctor ) )
708+ . flat_map ( IntRange :: from_ctor)
712709 . flat_map ( |range| ctor_range. intersection ( cx. tcx , & range) )
713710 . flat_map ( |range| range_borders ( range) ) ;
714711 let ctor_borders = range_borders ( ctor_range. clone ( ) ) ;
@@ -731,7 +728,8 @@ impl<'tcx> Constructor<'tcx> {
731728 ( Border :: JustBefore ( n) , Border :: AfterMax ) => Some ( n..=u128:: MAX ) ,
732729 ( Border :: AfterMax , _) => None ,
733730 } )
734- . map ( |range| IntRange :: range_to_ctor ( cx. tcx , ty, range) )
731+ . map ( |range| IntRange :: new ( ty, range) )
732+ . map ( IntRange )
735733 . collect ( )
736734 }
737735 // When not treated exhaustively, don't split ranges.
@@ -915,8 +913,8 @@ impl<'tcx> Constructor<'tcx> {
915913 /// notation).
916914 fn subtract_meta_constructor (
917915 self ,
918- tcx : TyCtxt < ' tcx > ,
919- param_env : ty:: ParamEnv < ' tcx > ,
916+ _tcx : TyCtxt < ' tcx > ,
917+ _param_env : ty:: ParamEnv < ' tcx > ,
920918 used_ctors : & Vec < Constructor < ' tcx > > ,
921919 ) -> SmallVec < [ Constructor < ' tcx > ; 1 ] > {
922920 debug ! ( "subtract_meta_constructor {:?}" , self ) ;
@@ -1042,31 +1040,25 @@ impl<'tcx> Constructor<'tcx> {
10421040
10431041 remaining_ctors
10441042 }
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] ;
10471046
10481047 // 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
10511050 . 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) )
10601052 . collect ( ) ;
10611053
10621054 // If the constructors that have been considered so far already cover
10631055 // the entire range of `self`, no need to look at more constructors.
1064- if remaining_ctors . is_empty ( ) {
1056+ if remaining_ranges . is_empty ( ) {
10651057 break ;
10661058 }
10671059 }
10681060
1069- remaining_ctors
1061+ remaining_ranges . into_iter ( ) . map ( IntRange ) . collect ( )
10701062 }
10711063 Wildcard | MissingConstructors ( _) => {
10721064 bug ! ( "shouldn't try to subtract constructor {:?}" , self )
@@ -1513,6 +1505,10 @@ struct IntRange<'tcx> {
15131505}
15141506
15151507impl < ' tcx > IntRange < ' tcx > {
1508+ fn new ( ty : Ty < ' tcx > , range : RangeInclusive < u128 > ) -> Self {
1509+ IntRange { ty, range }
1510+ }
1511+
15161512 #[ inline]
15171513 fn is_integral ( ty : Ty < ' _ > ) -> bool {
15181514 match ty. kind {
@@ -1597,11 +1593,7 @@ impl<'tcx> IntRange<'tcx> {
15971593 }
15981594 }
15991595
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 > > {
16051597 match ctor {
16061598 IntRange ( range) => Some ( range. clone ( ) ) ,
16071599 _ => None ,
@@ -1619,15 +1611,6 @@ impl<'tcx> IntRange<'tcx> {
16191611 }
16201612 }
16211613
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-
16311614 /// Converts an `IntRange` to a `PatKind::Constant` or inclusive `PatKind::Range`.
16321615 fn to_patkind ( & self , tcx : TyCtxt < ' tcx > ) -> PatKind < ' tcx > {
16331616 let bias = IntRange :: signed_bias ( tcx, self . ty ) ;
@@ -1648,16 +1631,8 @@ impl<'tcx> IntRange<'tcx> {
16481631
16491632 /// Returns a collection of ranges that spans the values covered by `ctor`, subtracted
16501633 /// 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 ;
16611636
16621637 let ty = self . ty ;
16631638 let ( lo, hi) = ( * self . range . start ( ) , * self . range . end ( ) ) ;
@@ -1666,17 +1641,17 @@ impl<'tcx> IntRange<'tcx> {
16661641 if lo > range_hi || range_lo > hi {
16671642 // The pattern doesn't intersect with the range at all,
16681643 // 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) ) ;
16701645 } else {
16711646 if lo > range_lo {
16721647 // The pattern intersects an upper section of the
16731648 // 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 ) ) ) ;
16751650 }
16761651 if hi < range_hi {
16771652 // The pattern intersects a lower section of the
16781653 // 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) ) ;
16801655 }
16811656 }
16821657 remaining_ranges
0 commit comments