@@ -594,51 +594,17 @@ enum SliceKind {
594594 VarLen ( u64 , u64 ) ,
595595}
596596
597- /// A constructor for array and slice patterns.
598- #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
599- struct Slice {
600- /// `None` if the matched value is a slice, `Some(n)` if it is an array of size `n`.
601- array_len : Option < u64 > ,
602- /// The kind of pattern it is: fixed-length `[x, y]` or variable length `[x, .., y]`.
603- kind : SliceKind ,
604- }
605-
606- impl Slice {
607- /// Returns what patterns this constructor covers: either fixed-length patterns or
608- /// variable-length patterns.
609- fn pattern_kind ( self ) -> SliceKind {
610- match self {
611- Slice { array_len : Some ( len) , kind : VarLen ( prefix, suffix) }
612- if prefix + suffix == len =>
613- {
614- FixedLen ( len)
615- }
616- _ => self . kind ,
617- }
618- }
619-
620- /// Returns what values this constructor covers: either values of only one given length, or
621- /// values of length above a given length.
622- /// This is different from `pattern_kind()` because in some cases the pattern only takes into
623- /// account a subset of the entries of the array, but still only captures values of a given
624- /// length.
625- fn value_kind ( self ) -> SliceKind {
626- match self {
627- Slice { array_len : Some ( len) , kind : VarLen ( _, _) } => FixedLen ( len) ,
628- _ => self . kind ,
629- }
630- }
631-
597+ impl SliceKind {
632598 fn arity ( self ) -> u64 {
633- match self . pattern_kind ( ) {
599+ match self {
634600 FixedLen ( length) => length,
635601 VarLen ( prefix, suffix) => prefix + suffix,
636602 }
637603 }
638604
639605 /// Whether this pattern includes patterns of length `other_len`.
640606 fn covers_length ( self , other_len : u64 ) -> bool {
641- match self . value_kind ( ) {
607+ match self {
642608 FixedLen ( len) => len == other_len,
643609 VarLen ( prefix, suffix) => prefix + suffix <= other_len,
644610 }
@@ -649,7 +615,7 @@ impl Slice {
649615 fn subtract ( self , other : Self ) -> SmallVec < [ Self ; 1 ] > {
650616 // Remember, `VarLen(i, j)` covers the union of `FixedLen` from `i + j` to infinity.
651617 // Naming: we remove the "neg" constructors from the "pos" ones.
652- match self . value_kind ( ) {
618+ match self {
653619 FixedLen ( pos_len) => {
654620 if other. covers_length ( pos_len) {
655621 smallvec ! [ ]
@@ -659,7 +625,7 @@ impl Slice {
659625 }
660626 VarLen ( pos_prefix, pos_suffix) => {
661627 let pos_len = pos_prefix + pos_suffix;
662- match other. value_kind ( ) {
628+ match other {
663629 FixedLen ( neg_len) => {
664630 if neg_len < pos_len {
665631 smallvec ! [ self ]
@@ -668,7 +634,6 @@ impl Slice {
668634 . map ( FixedLen )
669635 // We know that `neg_len + 1 >= pos_len >= pos_suffix`.
670636 . chain ( Some ( VarLen ( neg_len + 1 - pos_suffix, pos_suffix) ) )
671- . map ( |kind| Slice { array_len : None , kind } )
672637 . collect ( )
673638 }
674639 }
@@ -677,10 +642,7 @@ impl Slice {
677642 if neg_len <= pos_len {
678643 smallvec ! [ ]
679644 } else {
680- ( pos_len..neg_len)
681- . map ( FixedLen )
682- . map ( |kind| Slice { array_len : None , kind } )
683- . collect ( )
645+ ( pos_len..neg_len) . map ( FixedLen ) . collect ( )
684646 }
685647 }
686648 }
@@ -689,6 +651,46 @@ impl Slice {
689651 }
690652}
691653
654+ /// A constructor for array and slice patterns.
655+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
656+ struct Slice {
657+ /// `None` if the matched value is a slice, `Some(n)` if it is an array of size `n`.
658+ array_len : Option < u64 > ,
659+ /// The kind of pattern it is: fixed-length `[x, y]` or variable length `[x, .., y]`.
660+ kind : SliceKind ,
661+ }
662+
663+ impl Slice {
664+ /// Returns what patterns this constructor covers: either fixed-length patterns or
665+ /// variable-length patterns.
666+ fn pattern_kind ( self ) -> SliceKind {
667+ match self {
668+ Slice { array_len : Some ( len) , kind : VarLen ( prefix, suffix) }
669+ if prefix + suffix == len =>
670+ {
671+ FixedLen ( len)
672+ }
673+ _ => self . kind ,
674+ }
675+ }
676+
677+ /// Returns what values this constructor covers: either values of only one given length, or
678+ /// values of length above a given length.
679+ /// This is different from `pattern_kind()` because in some cases the pattern only takes into
680+ /// account a subset of the entries of the array, but still only captures values of a given
681+ /// length.
682+ fn value_kind ( self ) -> SliceKind {
683+ match self {
684+ Slice { array_len : Some ( len) , kind : VarLen ( _, _) } => FixedLen ( len) ,
685+ _ => self . kind ,
686+ }
687+ }
688+
689+ fn arity ( self ) -> u64 {
690+ self . pattern_kind ( ) . arity ( )
691+ }
692+ }
693+
692694#[ derive( Clone , Debug , PartialEq ) ]
693695enum Constructor < ' tcx > {
694696 /// The constructor of all patterns that don't vary by constructor,
@@ -743,26 +745,25 @@ impl<'tcx> Constructor<'tcx> {
743745 & Slice ( slice) => match slice. value_kind ( ) {
744746 FixedLen ( self_len) => {
745747 let overlaps = |c : & Constructor < ' _ > | match * c {
746- Slice ( other_slice) => other_slice. covers_length ( self_len) ,
748+ Slice ( other_slice) => other_slice. value_kind ( ) . covers_length ( self_len) ,
747749 _ => false ,
748750 } ;
749751 if other_ctors. iter ( ) . any ( overlaps) { vec ! [ ] } else { vec ! [ Slice ( slice) ] }
750752 }
751753 VarLen ( ..) => {
752- let mut remaining_slices = vec ! [ slice] ;
754+ let mut remaining_slices = vec ! [ slice. value_kind ( ) ] ;
753755
754756 // For each used slice, subtract from the current set of slices.
755- // Naming: we remove the "neg" constructors from the "pos" ones.
756- for neg_ctor in other_ctors {
757- let neg_slice = match neg_ctor {
758- Slice ( slice) => * slice,
759- // FIXME(#65413): If `neg_ctor` is not a slice, we assume it doesn't
757+ for other_ctor in other_ctors {
758+ let other_slice = match other_ctor {
759+ Slice ( slice) => slice. value_kind ( ) ,
760+ // FIXME(#65413): If `other_ctor` is not a slice, we assume it doesn't
760761 // cover any value here.
761762 _ => continue ,
762763 } ;
763764 remaining_slices = remaining_slices
764765 . into_iter ( )
765- . flat_map ( |pos_slice| pos_slice . subtract ( neg_slice ) )
766+ . flat_map ( |remaining_slice| remaining_slice . subtract ( other_slice ) )
766767 . collect ( ) ;
767768
768769 // If the constructors that have been considered so far already cover
@@ -772,7 +773,11 @@ impl<'tcx> Constructor<'tcx> {
772773 }
773774 }
774775
775- remaining_slices. into_iter ( ) . map ( Slice ) . collect ( )
776+ remaining_slices
777+ . into_iter ( )
778+ . map ( |kind| Slice { array_len : slice. array_len , kind } )
779+ . map ( Slice )
780+ . collect ( )
776781 }
777782 } ,
778783 IntRange ( self_range) => {
0 commit comments