@@ -588,8 +588,8 @@ enum Constructor<'tcx> {
588588 ConstantRange ( u128 , u128 , Ty < ' tcx > , RangeEnd , Span ) ,
589589 /// Array patterns of length n.
590590 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 ) ,
593593}
594594
595595// 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> {
604604 Constructor :: ConstantRange ( b_start, b_end, b_ty, b_range_end, _) ,
605605 ) => a_start == b_start && a_end == b_end && a_ty == b_ty && a_range_end == b_range_end,
606606 ( 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,
608611 _ => false ,
609612 }
610613 }
@@ -649,7 +652,7 @@ impl<'tcx> Constructor<'tcx> {
649652 )
650653 }
651654 Constructor :: FixedLenSlice ( val) => format ! ( "[{}]" , val) ,
652- Constructor :: VarLenSlice ( val ) => format ! ( "[{}, ..]" , val ) ,
655+ Constructor :: VarLenSlice ( prefix , suffix ) => format ! ( "[{}, .., {} ]" , prefix , suffix ) ,
653656 _ => bug ! ( "bad constructor being displayed: `{:?}" , self ) ,
654657 }
655658 }
@@ -662,7 +665,7 @@ impl<'tcx> Constructor<'tcx> {
662665 param_env : ty:: ParamEnv < ' tcx > ,
663666 other_ctors : & Vec < Constructor < ' tcx > > ,
664667 ) -> Vec < Constructor < ' tcx > > {
665- match self {
668+ match * self {
666669 // Those constructors can only match themselves.
667670 Single | Variant ( _) => {
668671 if other_ctors. iter ( ) . any ( |c| c == self ) {
@@ -672,47 +675,58 @@ impl<'tcx> Constructor<'tcx> {
672675 }
673676 }
674677 FixedLenSlice ( self_len) => {
675- let overlaps = |c : & Constructor < ' _ > | match c {
678+ let overlaps = |c : & Constructor < ' _ > | match * c {
676679 FixedLenSlice ( other_len) => other_len == self_len,
677- VarLenSlice ( other_len ) => other_len <= self_len,
680+ VarLenSlice ( prefix , suffix ) => prefix + suffix <= self_len,
678681 _ => false ,
679682 } ;
680683 if other_ctors. iter ( ) . any ( overlaps) { vec ! [ ] } else { vec ! [ self . clone( ) ] }
681684 }
682- VarLenSlice ( _ ) => {
685+ VarLenSlice ( .. ) => {
683686 let mut remaining_ctors = vec ! [ self . clone( ) ] ;
684687
685688 // For each used ctor, subtract from the current set of constructors.
686689 // 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.
689692 for neg_ctor in other_ctors {
690693 remaining_ctors = remaining_ctors
691694 . into_iter ( )
692695 . flat_map ( |pos_ctor| -> SmallVec < [ Constructor < ' tcx > ; 1 ] > {
693696 // Compute pos_ctor \ neg_ctor
694697 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;
696700 if neg_len <= pos_len {
697701 smallvec ! [ ]
698702 } else {
699703 smallvec ! [ pos_ctor]
700704 }
701705 }
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;
703712 if neg_len <= pos_len {
704713 smallvec ! [ ]
705714 } else {
706- ( * pos_len..* neg_len) . map ( FixedLenSlice ) . collect ( )
715+ ( pos_len..neg_len) . map ( FixedLenSlice ) . collect ( )
707716 }
708717 }
709- ( VarLenSlice ( pos_len) , FixedLenSlice ( neg_len) ) => {
718+ ( & VarLenSlice ( pos_prefix, pos_suffix) , & FixedLenSlice ( neg_len) ) => {
719+ let pos_len = pos_prefix + pos_suffix;
710720 if neg_len < pos_len {
711721 smallvec ! [ pos_ctor]
712722 } else {
713- ( * pos_len..* neg_len)
723+ ( pos_len..neg_len)
714724 . 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+ ) ) )
716730 . collect ( )
717731 }
718732 }
@@ -784,7 +798,8 @@ impl<'tcx> Constructor<'tcx> {
784798 match ty. kind {
785799 ty:: Tuple ( ref fs) => fs. len ( ) as u64 ,
786800 ty:: Slice ( ..) | ty:: Array ( ..) => match * self {
787- FixedLenSlice ( length) | VarLenSlice ( length) => length,
801+ FixedLenSlice ( length) => length,
802+ VarLenSlice ( prefix, suffix) => prefix + suffix,
788803 ConstantValue ( ..) => 0 ,
789804 _ => bug ! ( "bad slice pattern {:?} {:?}" , self , ty) ,
790805 } ,
@@ -845,10 +860,11 @@ impl<'tcx> Constructor<'tcx> {
845860 FixedLenSlice ( _) => {
846861 PatKind :: Slice { prefix : subpatterns. collect ( ) , slice : None , suffix : vec ! [ ] }
847862 }
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 ( ) ;
850866 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 }
852868 }
853869 _ => bug ! ( "bad slice pattern {:?} {:?}" , self , ty) ,
854870 } ,
@@ -1072,7 +1088,7 @@ fn all_constructors<'a, 'tcx>(
10721088 if cx. is_uninhabited ( sub_ty) {
10731089 vec ! [ FixedLenSlice ( 0 ) ]
10741090 } else {
1075- vec ! [ VarLenSlice ( 0 ) ]
1091+ vec ! [ VarLenSlice ( 0 , 0 ) ]
10761092 }
10771093 }
10781094 ty:: Adt ( def, substs) if def. is_enum ( ) => def
@@ -1796,11 +1812,12 @@ fn pat_constructors<'tcx>(
17961812 _ => span_bug ! ( pat. span, "bad ty {:?} for array pattern" , pcx. ty) ,
17971813 } ,
17981814 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 ;
18001817 if slice. is_some ( ) {
1801- Some ( vec ! [ VarLenSlice ( pat_len ) ] )
1818+ Some ( vec ! [ VarLenSlice ( prefix , suffix ) ] )
18021819 } else {
1803- Some ( vec ! [ FixedLenSlice ( pat_len ) ] )
1820+ Some ( vec ! [ FixedLenSlice ( prefix + suffix ) ] )
18041821 }
18051822 }
18061823 PatKind :: Or { .. } => {
@@ -1822,7 +1839,8 @@ fn constructor_sub_pattern_tys<'a, 'tcx>(
18221839 match ty. kind {
18231840 ty:: Tuple ( ref fs) => fs. into_iter ( ) . map ( |t| t. expect_ty ( ) ) . collect ( ) ,
18241841 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 ( ) ,
18261844 ConstantValue ( ..) => vec ! [ ] ,
18271845 _ => bug ! ( "bad slice pattern {:?} {:?}" , ctor, ty) ,
18281846 } ,
@@ -2078,8 +2096,8 @@ fn split_grouped_constructors<'p, 'tcx>(
20782096 split_ctors. push ( IntRange :: range_to_ctor ( tcx, ty, range, span) ) ;
20792097 }
20802098 }
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 ) )
20832101 }
20842102 // Any other constructor can be used unchanged.
20852103 _ => split_ctors. push ( ctor) ,
0 commit comments