@@ -588,8 +588,8 @@ enum Constructor<'tcx> {
588
588
ConstantRange ( u128 , u128 , Ty < ' tcx > , RangeEnd , Span ) ,
589
589
/// Array patterns of length n.
590
590
FixedLenSlice ( u64 ) ,
591
- /// Slice patterns. Stands for any array constructor of length >= n .
592
- VarLenSlice ( u64 ) ,
591
+ /// Slice patterns. Captures any array constructor of length >= i+j .
592
+ VarLenSlice ( u64 , u64 ) ,
593
593
}
594
594
595
595
// Ignore spans when comparing, they don't carry semantic information as they are only for lints.
@@ -604,7 +604,10 @@ impl<'tcx> std::cmp::PartialEq for Constructor<'tcx> {
604
604
Constructor :: ConstantRange ( b_start, b_end, b_ty, b_range_end, _) ,
605
605
) => a_start == b_start && a_end == b_end && a_ty == b_ty && a_range_end == b_range_end,
606
606
( Constructor :: FixedLenSlice ( a) , Constructor :: FixedLenSlice ( b) ) => a == b,
607
- ( Constructor :: VarLenSlice ( a) , Constructor :: VarLenSlice ( b) ) => a == b,
607
+ (
608
+ Constructor :: VarLenSlice ( a_prefix, a_suffix) ,
609
+ Constructor :: VarLenSlice ( b_prefix, b_suffix) ,
610
+ ) => a_prefix == b_prefix && a_suffix == b_suffix,
608
611
_ => false ,
609
612
}
610
613
}
@@ -649,7 +652,7 @@ impl<'tcx> Constructor<'tcx> {
649
652
)
650
653
}
651
654
Constructor :: FixedLenSlice ( val) => format ! ( "[{}]" , val) ,
652
- Constructor :: VarLenSlice ( val ) => format ! ( "[{}, ..]" , val ) ,
655
+ Constructor :: VarLenSlice ( prefix , suffix ) => format ! ( "[{}, .., {} ]" , prefix , suffix ) ,
653
656
_ => bug ! ( "bad constructor being displayed: `{:?}" , self ) ,
654
657
}
655
658
}
@@ -662,7 +665,7 @@ impl<'tcx> Constructor<'tcx> {
662
665
param_env : ty:: ParamEnv < ' tcx > ,
663
666
other_ctors : & Vec < Constructor < ' tcx > > ,
664
667
) -> Vec < Constructor < ' tcx > > {
665
- match self {
668
+ match * self {
666
669
// Those constructors can only match themselves.
667
670
Single | Variant ( _) => {
668
671
if other_ctors. iter ( ) . any ( |c| c == self ) {
@@ -672,47 +675,58 @@ impl<'tcx> Constructor<'tcx> {
672
675
}
673
676
}
674
677
FixedLenSlice ( self_len) => {
675
- let overlaps = |c : & Constructor < ' _ > | match c {
678
+ let overlaps = |c : & Constructor < ' _ > | match * c {
676
679
FixedLenSlice ( other_len) => other_len == self_len,
677
- VarLenSlice ( other_len ) => other_len <= self_len,
680
+ VarLenSlice ( prefix , suffix ) => prefix + suffix <= self_len,
678
681
_ => false ,
679
682
} ;
680
683
if other_ctors. iter ( ) . any ( overlaps) { vec ! [ ] } else { vec ! [ self . clone( ) ] }
681
684
}
682
- VarLenSlice ( _ ) => {
685
+ VarLenSlice ( .. ) => {
683
686
let mut remaining_ctors = vec ! [ self . clone( ) ] ;
684
687
685
688
// For each used ctor, subtract from the current set of constructors.
686
689
// Naming: we remove the "neg" constructors from the "pos" ones.
687
- // Remember, VarLenSlice(n ) covers the union of FixedLenSlice from
688
- // n to infinity.
690
+ // Remember, VarLenSlice(i, j ) covers the union of FixedLenSlice from
691
+ // i+j to infinity.
689
692
for neg_ctor in other_ctors {
690
693
remaining_ctors = remaining_ctors
691
694
. into_iter ( )
692
695
. flat_map ( |pos_ctor| -> SmallVec < [ Constructor < ' tcx > ; 1 ] > {
693
696
// Compute pos_ctor \ neg_ctor
694
697
match ( & pos_ctor, neg_ctor) {
695
- ( FixedLenSlice ( pos_len) , VarLenSlice ( neg_len) ) => {
698
+ ( & FixedLenSlice ( pos_len) , & VarLenSlice ( neg_prefix, neg_suffix) ) => {
699
+ let neg_len = neg_prefix + neg_suffix;
696
700
if neg_len <= pos_len {
697
701
smallvec ! [ ]
698
702
} else {
699
703
smallvec ! [ pos_ctor]
700
704
}
701
705
}
702
- ( VarLenSlice ( pos_len) , VarLenSlice ( neg_len) ) => {
706
+ (
707
+ & VarLenSlice ( pos_prefix, pos_suffix) ,
708
+ & VarLenSlice ( neg_prefix, neg_suffix) ,
709
+ ) => {
710
+ let neg_len = neg_prefix + neg_suffix;
711
+ let pos_len = pos_prefix + pos_suffix;
703
712
if neg_len <= pos_len {
704
713
smallvec ! [ ]
705
714
} else {
706
- ( * pos_len..* neg_len) . map ( FixedLenSlice ) . collect ( )
715
+ ( pos_len..neg_len) . map ( FixedLenSlice ) . collect ( )
707
716
}
708
717
}
709
- ( VarLenSlice ( pos_len) , FixedLenSlice ( neg_len) ) => {
718
+ ( & VarLenSlice ( pos_prefix, pos_suffix) , & FixedLenSlice ( neg_len) ) => {
719
+ let pos_len = pos_prefix + pos_suffix;
710
720
if neg_len < pos_len {
711
721
smallvec ! [ pos_ctor]
712
722
} else {
713
- ( * pos_len..* neg_len)
723
+ ( pos_len..neg_len)
714
724
. map ( FixedLenSlice )
715
- . chain ( Some ( VarLenSlice ( neg_len + 1 ) ) )
725
+ // We know neg_len + 1 >= pos_len >= pos_suffix
726
+ . chain ( Some ( VarLenSlice (
727
+ neg_len + 1 - pos_suffix,
728
+ pos_suffix,
729
+ ) ) )
716
730
. collect ( )
717
731
}
718
732
}
@@ -784,7 +798,8 @@ impl<'tcx> Constructor<'tcx> {
784
798
match ty. kind {
785
799
ty:: Tuple ( ref fs) => fs. len ( ) as u64 ,
786
800
ty:: Slice ( ..) | ty:: Array ( ..) => match * self {
787
- FixedLenSlice ( length) | VarLenSlice ( length) => length,
801
+ FixedLenSlice ( length) => length,
802
+ VarLenSlice ( prefix, suffix) => prefix + suffix,
788
803
ConstantValue ( ..) => 0 ,
789
804
_ => bug ! ( "bad slice pattern {:?} {:?}" , self , ty) ,
790
805
} ,
@@ -845,10 +860,11 @@ impl<'tcx> Constructor<'tcx> {
845
860
FixedLenSlice ( _) => {
846
861
PatKind :: Slice { prefix : subpatterns. collect ( ) , slice : None , suffix : vec ! [ ] }
847
862
}
848
- VarLenSlice ( _) => {
849
- let prefix = subpatterns. collect ( ) ;
863
+ VarLenSlice ( prefix_len, _suffix_len) => {
864
+ let prefix = subpatterns. by_ref ( ) . take ( * prefix_len as usize ) . collect ( ) ;
865
+ let suffix = subpatterns. collect ( ) ;
850
866
let wild = Pat { ty, span : DUMMY_SP , kind : Box :: new ( PatKind :: Wild ) } ;
851
- PatKind :: Slice { prefix, slice : Some ( wild) , suffix : vec ! [ ] }
867
+ PatKind :: Slice { prefix, slice : Some ( wild) , suffix }
852
868
}
853
869
_ => bug ! ( "bad slice pattern {:?} {:?}" , self , ty) ,
854
870
} ,
@@ -1072,7 +1088,7 @@ fn all_constructors<'a, 'tcx>(
1072
1088
if cx. is_uninhabited ( sub_ty) {
1073
1089
vec ! [ FixedLenSlice ( 0 ) ]
1074
1090
} else {
1075
- vec ! [ VarLenSlice ( 0 ) ]
1091
+ vec ! [ VarLenSlice ( 0 , 0 ) ]
1076
1092
}
1077
1093
}
1078
1094
ty:: Adt ( def, substs) if def. is_enum ( ) => def
@@ -1796,11 +1812,12 @@ fn pat_constructors<'tcx>(
1796
1812
_ => span_bug ! ( pat. span, "bad ty {:?} for array pattern" , pcx. ty) ,
1797
1813
} ,
1798
1814
PatKind :: Slice { ref prefix, ref slice, ref suffix } => {
1799
- let pat_len = prefix. len ( ) as u64 + suffix. len ( ) as u64 ;
1815
+ let prefix = prefix. len ( ) as u64 ;
1816
+ let suffix = suffix. len ( ) as u64 ;
1800
1817
if slice. is_some ( ) {
1801
- Some ( vec ! [ VarLenSlice ( pat_len ) ] )
1818
+ Some ( vec ! [ VarLenSlice ( prefix , suffix ) ] )
1802
1819
} else {
1803
- Some ( vec ! [ FixedLenSlice ( pat_len ) ] )
1820
+ Some ( vec ! [ FixedLenSlice ( prefix + suffix ) ] )
1804
1821
}
1805
1822
}
1806
1823
PatKind :: Or { .. } => {
@@ -1822,7 +1839,8 @@ fn constructor_sub_pattern_tys<'a, 'tcx>(
1822
1839
match ty. kind {
1823
1840
ty:: Tuple ( ref fs) => fs. into_iter ( ) . map ( |t| t. expect_ty ( ) ) . collect ( ) ,
1824
1841
ty:: Slice ( ty) | ty:: Array ( ty, _) => match * ctor {
1825
- FixedLenSlice ( length) | VarLenSlice ( length) => ( 0 ..length) . map ( |_| ty) . collect ( ) ,
1842
+ FixedLenSlice ( length) => ( 0 ..length) . map ( |_| ty) . collect ( ) ,
1843
+ VarLenSlice ( prefix, suffix) => ( 0 ..prefix + suffix) . map ( |_| ty) . collect ( ) ,
1826
1844
ConstantValue ( ..) => vec ! [ ] ,
1827
1845
_ => bug ! ( "bad slice pattern {:?} {:?}" , ctor, ty) ,
1828
1846
} ,
@@ -2078,8 +2096,8 @@ fn split_grouped_constructors<'p, 'tcx>(
2078
2096
split_ctors. push ( IntRange :: range_to_ctor ( tcx, ty, range, span) ) ;
2079
2097
}
2080
2098
}
2081
- VarLenSlice ( len ) => {
2082
- split_ctors. extend ( ( len ..pcx. max_slice_length + 1 ) . map ( FixedLenSlice ) )
2099
+ VarLenSlice ( prefix , suffix ) => {
2100
+ split_ctors. extend ( ( prefix + suffix ..pcx. max_slice_length + 1 ) . map ( FixedLenSlice ) )
2083
2101
}
2084
2102
// Any other constructor can be used unchanged.
2085
2103
_ => split_ctors. push ( ctor) ,
0 commit comments