@@ -594,51 +594,17 @@ enum SliceKind {
594
594
VarLen ( u64 , u64 ) ,
595
595
}
596
596
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 {
632
598
fn arity ( self ) -> u64 {
633
- match self . pattern_kind ( ) {
599
+ match self {
634
600
FixedLen ( length) => length,
635
601
VarLen ( prefix, suffix) => prefix + suffix,
636
602
}
637
603
}
638
604
639
605
/// Whether this pattern includes patterns of length `other_len`.
640
606
fn covers_length ( self , other_len : u64 ) -> bool {
641
- match self . value_kind ( ) {
607
+ match self {
642
608
FixedLen ( len) => len == other_len,
643
609
VarLen ( prefix, suffix) => prefix + suffix <= other_len,
644
610
}
@@ -649,7 +615,7 @@ impl Slice {
649
615
fn subtract ( self , other : Self ) -> SmallVec < [ Self ; 1 ] > {
650
616
// Remember, `VarLen(i, j)` covers the union of `FixedLen` from `i + j` to infinity.
651
617
// Naming: we remove the "neg" constructors from the "pos" ones.
652
- match self . value_kind ( ) {
618
+ match self {
653
619
FixedLen ( pos_len) => {
654
620
if other. covers_length ( pos_len) {
655
621
smallvec ! [ ]
@@ -659,7 +625,7 @@ impl Slice {
659
625
}
660
626
VarLen ( pos_prefix, pos_suffix) => {
661
627
let pos_len = pos_prefix + pos_suffix;
662
- match other. value_kind ( ) {
628
+ match other {
663
629
FixedLen ( neg_len) => {
664
630
if neg_len < pos_len {
665
631
smallvec ! [ self ]
@@ -668,7 +634,6 @@ impl Slice {
668
634
. map ( FixedLen )
669
635
// We know that `neg_len + 1 >= pos_len >= pos_suffix`.
670
636
. chain ( Some ( VarLen ( neg_len + 1 - pos_suffix, pos_suffix) ) )
671
- . map ( |kind| Slice { array_len : None , kind } )
672
637
. collect ( )
673
638
}
674
639
}
@@ -677,10 +642,7 @@ impl Slice {
677
642
if neg_len <= pos_len {
678
643
smallvec ! [ ]
679
644
} 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 ( )
684
646
}
685
647
}
686
648
}
@@ -689,6 +651,46 @@ impl Slice {
689
651
}
690
652
}
691
653
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
+
692
694
#[ derive( Clone , Debug , PartialEq ) ]
693
695
enum Constructor < ' tcx > {
694
696
/// The constructor of all patterns that don't vary by constructor,
@@ -743,26 +745,25 @@ impl<'tcx> Constructor<'tcx> {
743
745
& Slice ( slice) => match slice. value_kind ( ) {
744
746
FixedLen ( self_len) => {
745
747
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) ,
747
749
_ => false ,
748
750
} ;
749
751
if other_ctors. iter ( ) . any ( overlaps) { vec ! [ ] } else { vec ! [ Slice ( slice) ] }
750
752
}
751
753
VarLen ( ..) => {
752
- let mut remaining_slices = vec ! [ slice] ;
754
+ let mut remaining_slices = vec ! [ slice. value_kind ( ) ] ;
753
755
754
756
// 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
760
761
// cover any value here.
761
762
_ => continue ,
762
763
} ;
763
764
remaining_slices = remaining_slices
764
765
. into_iter ( )
765
- . flat_map ( |pos_slice| pos_slice . subtract ( neg_slice ) )
766
+ . flat_map ( |remaining_slice| remaining_slice . subtract ( other_slice ) )
766
767
. collect ( ) ;
767
768
768
769
// If the constructors that have been considered so far already cover
@@ -772,7 +773,11 @@ impl<'tcx> Constructor<'tcx> {
772
773
}
773
774
}
774
775
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 ( )
776
781
}
777
782
} ,
778
783
IntRange ( self_range) => {
0 commit comments