Skip to content

Commit bd0e3cc

Browse files
committed
Store SliceKinds directly when subtracting
1 parent daa117e commit bd0e3cc

File tree

1 file changed

+58
-53
lines changed

1 file changed

+58
-53
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
693695
enum 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

Comments
 (0)