@@ -620,21 +620,17 @@ struct Slice {
620
620
}
621
621
622
622
impl 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 }
634
630
}
635
631
636
632
fn arity ( self ) -> u64 {
637
- self . kind ( ) . arity ( )
633
+ self . kind . arity ( )
638
634
}
639
635
640
636
/// The exhaustiveness-checking paper does not include any details on
@@ -701,10 +697,8 @@ impl Slice {
701
697
/// witness of length ≥2 (say, `[false, false, true]`) can be
702
698
/// turned to a witness from any other length ≥2.
703
699
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) ,
708
702
_ => return smallvec ! [ Slice ( self ) ] ,
709
703
} ;
710
704
@@ -716,7 +710,7 @@ impl Slice {
716
710
717
711
for ctor in head_ctors {
718
712
if let Slice ( slice) = ctor {
719
- match slice. kind ( ) {
713
+ match slice. kind {
720
714
FixedLen ( len) => {
721
715
max_fixed_len = cmp:: max ( max_fixed_len, len) ;
722
716
}
@@ -725,6 +719,8 @@ impl Slice {
725
719
max_suffix_len = cmp:: max ( max_suffix_len, suffix) ;
726
720
}
727
721
}
722
+ } else {
723
+ bug ! ( "unexpected ctor for slice type: {:?}" , ctor) ;
728
724
}
729
725
}
730
726
@@ -738,27 +734,19 @@ impl Slice {
738
734
max_prefix_len = max_fixed_len + 1 - max_suffix_len;
739
735
}
740
736
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) ] ,
750
741
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 ) ;
759
747
smaller_lengths
748
+ . map ( |kind| Slice :: new ( self . array_len , kind) )
760
749
. chain ( Some ( final_slice) )
761
- . map ( |kind| Slice { array_len, kind } )
762
750
. map ( Slice )
763
751
. collect ( )
764
752
}
@@ -767,7 +755,7 @@ impl Slice {
767
755
768
756
/// See `Constructor::is_covered_by`
769
757
fn is_covered_by ( self , other : Self ) -> bool {
770
- other. kind ( ) . covers_length ( self . arity ( ) )
758
+ other. kind . covers_length ( self . arity ( ) )
771
759
}
772
760
}
773
761
@@ -934,7 +922,6 @@ impl<'tcx> Constructor<'tcx> {
934
922
None => false ,
935
923
}
936
924
}
937
-
938
925
( Slice ( self_slice) , Slice ( other_slice) ) => self_slice. is_covered_by ( * other_slice) ,
939
926
940
927
// We are trying to inspect an opaque constant. Thus we skip the row.
@@ -1029,7 +1016,7 @@ impl<'tcx> Constructor<'tcx> {
1029
1016
ty:: Slice ( _) | ty:: Array ( ..) => bug ! ( "bad slice pattern {:?} {:?}" , self , pcx. ty) ,
1030
1017
_ => PatKind :: Wild ,
1031
1018
} ,
1032
- Slice ( slice) => match slice. kind ( ) {
1019
+ Slice ( slice) => match slice. kind {
1033
1020
FixedLen ( _) => {
1034
1021
PatKind :: Slice { prefix : subpatterns. collect ( ) , slice : None , suffix : vec ! [ ] }
1035
1022
}
@@ -1533,13 +1520,13 @@ fn all_constructors<'p, 'tcx>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Vec<Constructor<'tc
1533
1520
if len != 0 && cx. is_uninhabited ( sub_ty) {
1534
1521
vec ! [ ]
1535
1522
} else {
1536
- vec ! [ Slice ( Slice { array_len : Some ( len) , kind : VarLen ( 0 , 0 ) } ) ]
1523
+ vec ! [ Slice ( Slice :: new ( Some ( len) , VarLen ( 0 , 0 ) ) ) ]
1537
1524
}
1538
1525
}
1539
1526
// Treat arrays of a constant but unknown length like slices.
1540
1527
ty:: Array ( sub_ty, _) | ty:: Slice ( sub_ty) => {
1541
1528
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) ) ]
1543
1530
}
1544
1531
ty:: Adt ( def, substs) if def. is_enum ( ) => {
1545
1532
// 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>(
2224
2211
let suffix = suffix. len ( ) as u64 ;
2225
2212
let kind =
2226
2213
if slice. is_some ( ) { VarLen ( prefix, suffix) } else { FixedLen ( prefix + suffix) } ;
2227
- Slice ( Slice { array_len, kind } )
2214
+ Slice ( Slice :: new ( array_len, kind) )
2228
2215
}
2229
2216
PatKind :: Or { .. } => bug ! ( "Or-pattern should have been expanded earlier on." ) ,
2230
2217
}
0 commit comments