@@ -620,21 +620,17 @@ struct Slice {
620620}
621621
622622impl Slice {
623- /// Returns what patterns this constructor covers: either fixed-length patterns or
624- /// variable-length patterns.
625- fn kind ( self ) -> SliceKind {
626- match self {
627- Slice { array_len : Some ( len) , kind : VarLen ( prefix, suffix) }
628- if prefix + suffix == len =>
629- {
630- FixedLen ( len)
631- }
632- _ => self . kind ,
633- }
623+ fn new ( array_len : Option < u64 > , kind : SliceKind ) -> Self {
624+ let kind = match ( array_len, kind) {
625+ // If the middle `..` is empty, we effectively have a fixed-length pattern.
626+ ( Some ( len) , VarLen ( prefix, suffix) ) if prefix + suffix >= len => FixedLen ( len) ,
627+ _ => kind,
628+ } ;
629+ Slice { array_len, kind }
634630 }
635631
636632 fn arity ( self ) -> u64 {
637- self . kind ( ) . arity ( )
633+ self . kind . arity ( )
638634 }
639635
640636 /// The exhaustiveness-checking paper does not include any details on
@@ -701,10 +697,8 @@ impl Slice {
701697 /// witness of length ≥2 (say, `[false, false, true]`) can be
702698 /// turned to a witness from any other length ≥2.
703699 fn split < ' p , ' tcx > ( self , pcx : PatCtxt < ' _ , ' p , ' tcx > ) -> SmallVec < [ Constructor < ' tcx > ; 1 ] > {
704- let ( array_len, self_prefix, self_suffix) = match self {
705- Slice { array_len, kind : VarLen ( self_prefix, self_suffix) } => {
706- ( array_len, self_prefix, self_suffix)
707- }
700+ let ( self_prefix, self_suffix) = match self . kind {
701+ VarLen ( self_prefix, self_suffix) => ( self_prefix, self_suffix) ,
708702 _ => return smallvec ! [ Slice ( self ) ] ,
709703 } ;
710704
@@ -716,7 +710,7 @@ impl Slice {
716710
717711 for ctor in head_ctors {
718712 if let Slice ( slice) = ctor {
719- match slice. kind ( ) {
713+ match slice. kind {
720714 FixedLen ( len) => {
721715 max_fixed_len = cmp:: max ( max_fixed_len, len) ;
722716 }
@@ -725,6 +719,8 @@ impl Slice {
725719 max_suffix_len = cmp:: max ( max_suffix_len, suffix) ;
726720 }
727721 }
722+ } else {
723+ bug ! ( "unexpected ctor for slice type: {:?}" , ctor) ;
728724 }
729725 }
730726
@@ -738,27 +734,19 @@ impl Slice {
738734 max_prefix_len = max_fixed_len + 1 - max_suffix_len;
739735 }
740736
741- match array_len {
742- Some ( len) => {
743- let kind = if max_prefix_len + max_suffix_len < len {
744- VarLen ( max_prefix_len, max_suffix_len)
745- } else {
746- FixedLen ( len)
747- } ;
748- smallvec ! [ Slice ( Slice { array_len, kind } ) ]
749- }
737+ let final_slice = VarLen ( max_prefix_len, max_suffix_len) ;
738+ let final_slice = Slice :: new ( self . array_len , final_slice) ;
739+ match self . array_len {
740+ Some ( _) => smallvec ! [ Slice ( final_slice) ] ,
750741 None => {
751- // `ctor` originally covered the range `(self_prefix +
752- // self_suffix..infinity)`. We now split it into two: lengths smaller than
753- // `max_prefix_len + max_suffix_len` are treated independently as
754- // fixed-lengths slices, and lengths above are captured by a final VarLen
755- // constructor.
756- let smaller_lengths =
757- ( self_prefix + self_suffix..max_prefix_len + max_suffix_len) . map ( FixedLen ) ;
758- let final_slice = VarLen ( max_prefix_len, max_suffix_len) ;
742+ // `self` originally covered the range `(self.arity()..infinity)`. We split that
743+ // range into two: lengths smaller than `final_slice.arity()` are treated
744+ // independently as fixed-lengths slices, and lengths above are captured by
745+ // `final_slice`.
746+ let smaller_lengths = ( self . arity ( ) ..final_slice. arity ( ) ) . map ( FixedLen ) ;
759747 smaller_lengths
748+ . map ( |kind| Slice :: new ( self . array_len , kind) )
760749 . chain ( Some ( final_slice) )
761- . map ( |kind| Slice { array_len, kind } )
762750 . map ( Slice )
763751 . collect ( )
764752 }
@@ -767,7 +755,7 @@ impl Slice {
767755
768756 /// See `Constructor::is_covered_by`
769757 fn is_covered_by ( self , other : Self ) -> bool {
770- other. kind ( ) . covers_length ( self . arity ( ) )
758+ other. kind . covers_length ( self . arity ( ) )
771759 }
772760}
773761
@@ -934,7 +922,6 @@ impl<'tcx> Constructor<'tcx> {
934922 None => false ,
935923 }
936924 }
937-
938925 ( Slice ( self_slice) , Slice ( other_slice) ) => self_slice. is_covered_by ( * other_slice) ,
939926
940927 // We are trying to inspect an opaque constant. Thus we skip the row.
@@ -1029,7 +1016,7 @@ impl<'tcx> Constructor<'tcx> {
10291016 ty:: Slice ( _) | ty:: Array ( ..) => bug ! ( "bad slice pattern {:?} {:?}" , self , pcx. ty) ,
10301017 _ => PatKind :: Wild ,
10311018 } ,
1032- Slice ( slice) => match slice. kind ( ) {
1019+ Slice ( slice) => match slice. kind {
10331020 FixedLen ( _) => {
10341021 PatKind :: Slice { prefix : subpatterns. collect ( ) , slice : None , suffix : vec ! [ ] }
10351022 }
@@ -1533,13 +1520,13 @@ fn all_constructors<'p, 'tcx>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Vec<Constructor<'tc
15331520 if len != 0 && cx. is_uninhabited ( sub_ty) {
15341521 vec ! [ ]
15351522 } else {
1536- vec ! [ Slice ( Slice { array_len : Some ( len) , kind : VarLen ( 0 , 0 ) } ) ]
1523+ vec ! [ Slice ( Slice :: new ( Some ( len) , VarLen ( 0 , 0 ) ) ) ]
15371524 }
15381525 }
15391526 // Treat arrays of a constant but unknown length like slices.
15401527 ty:: Array ( sub_ty, _) | ty:: Slice ( sub_ty) => {
15411528 let kind = if cx. is_uninhabited ( sub_ty) { FixedLen ( 0 ) } else { VarLen ( 0 , 0 ) } ;
1542- vec ! [ Slice ( Slice { array_len : None , kind } ) ]
1529+ vec ! [ Slice ( Slice :: new ( None , kind) ) ]
15431530 }
15441531 ty:: Adt ( def, substs) if def. is_enum ( ) => {
15451532 // If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an
@@ -2224,7 +2211,7 @@ fn pat_constructor<'p, 'tcx>(
22242211 let suffix = suffix. len ( ) as u64 ;
22252212 let kind =
22262213 if slice. is_some ( ) { VarLen ( prefix, suffix) } else { FixedLen ( prefix + suffix) } ;
2227- Slice ( Slice { array_len, kind } )
2214+ Slice ( Slice :: new ( array_len, kind) )
22282215 }
22292216 PatKind :: Or { .. } => bug ! ( "Or-pattern should have been expanded earlier on." ) ,
22302217 }
0 commit comments