Skip to content

Commit d7044f2

Browse files
committed
Store both prefix and suffix length in VarLenSlice
1 parent 58de9d9 commit d7044f2

File tree

1 file changed

+45
-27
lines changed

1 file changed

+45
-27
lines changed

src/librustc_mir/hair/pattern/_match.rs

+45-27
Original file line numberDiff line numberDiff line change
@@ -588,8 +588,8 @@ enum Constructor<'tcx> {
588588
ConstantRange(u128, u128, Ty<'tcx>, RangeEnd, Span),
589589
/// Array patterns of length n.
590590
FixedLenSlice(u64),
591-
/// Slice patterns. Stands for any array constructor of length >= n.
592-
VarLenSlice(u64),
591+
/// Slice patterns. Captures any array constructor of length >= i+j.
592+
VarLenSlice(u64, u64),
593593
}
594594

595595
// Ignore spans when comparing, they don't carry semantic information as they are only for lints.
@@ -604,7 +604,10 @@ impl<'tcx> std::cmp::PartialEq for Constructor<'tcx> {
604604
Constructor::ConstantRange(b_start, b_end, b_ty, b_range_end, _),
605605
) => a_start == b_start && a_end == b_end && a_ty == b_ty && a_range_end == b_range_end,
606606
(Constructor::FixedLenSlice(a), Constructor::FixedLenSlice(b)) => a == b,
607-
(Constructor::VarLenSlice(a), Constructor::VarLenSlice(b)) => a == b,
607+
(
608+
Constructor::VarLenSlice(a_prefix, a_suffix),
609+
Constructor::VarLenSlice(b_prefix, b_suffix),
610+
) => a_prefix == b_prefix && a_suffix == b_suffix,
608611
_ => false,
609612
}
610613
}
@@ -649,7 +652,7 @@ impl<'tcx> Constructor<'tcx> {
649652
)
650653
}
651654
Constructor::FixedLenSlice(val) => format!("[{}]", val),
652-
Constructor::VarLenSlice(val) => format!("[{}, ..]", val),
655+
Constructor::VarLenSlice(prefix, suffix) => format!("[{}, .., {}]", prefix, suffix),
653656
_ => bug!("bad constructor being displayed: `{:?}", self),
654657
}
655658
}
@@ -662,7 +665,7 @@ impl<'tcx> Constructor<'tcx> {
662665
param_env: ty::ParamEnv<'tcx>,
663666
other_ctors: &Vec<Constructor<'tcx>>,
664667
) -> Vec<Constructor<'tcx>> {
665-
match self {
668+
match *self {
666669
// Those constructors can only match themselves.
667670
Single | Variant(_) => {
668671
if other_ctors.iter().any(|c| c == self) {
@@ -672,47 +675,58 @@ impl<'tcx> Constructor<'tcx> {
672675
}
673676
}
674677
FixedLenSlice(self_len) => {
675-
let overlaps = |c: &Constructor<'_>| match c {
678+
let overlaps = |c: &Constructor<'_>| match *c {
676679
FixedLenSlice(other_len) => other_len == self_len,
677-
VarLenSlice(other_len) => other_len <= self_len,
680+
VarLenSlice(prefix, suffix) => prefix + suffix <= self_len,
678681
_ => false,
679682
};
680683
if other_ctors.iter().any(overlaps) { vec![] } else { vec![self.clone()] }
681684
}
682-
VarLenSlice(_) => {
685+
VarLenSlice(..) => {
683686
let mut remaining_ctors = vec![self.clone()];
684687

685688
// For each used ctor, subtract from the current set of constructors.
686689
// Naming: we remove the "neg" constructors from the "pos" ones.
687-
// Remember, VarLenSlice(n) covers the union of FixedLenSlice from
688-
// n to infinity.
690+
// Remember, VarLenSlice(i, j) covers the union of FixedLenSlice from
691+
// i+j to infinity.
689692
for neg_ctor in other_ctors {
690693
remaining_ctors = remaining_ctors
691694
.into_iter()
692695
.flat_map(|pos_ctor| -> SmallVec<[Constructor<'tcx>; 1]> {
693696
// Compute pos_ctor \ neg_ctor
694697
match (&pos_ctor, neg_ctor) {
695-
(FixedLenSlice(pos_len), VarLenSlice(neg_len)) => {
698+
(&FixedLenSlice(pos_len), &VarLenSlice(neg_prefix, neg_suffix)) => {
699+
let neg_len = neg_prefix + neg_suffix;
696700
if neg_len <= pos_len {
697701
smallvec![]
698702
} else {
699703
smallvec![pos_ctor]
700704
}
701705
}
702-
(VarLenSlice(pos_len), VarLenSlice(neg_len)) => {
706+
(
707+
&VarLenSlice(pos_prefix, pos_suffix),
708+
&VarLenSlice(neg_prefix, neg_suffix),
709+
) => {
710+
let neg_len = neg_prefix + neg_suffix;
711+
let pos_len = pos_prefix + pos_suffix;
703712
if neg_len <= pos_len {
704713
smallvec![]
705714
} else {
706-
(*pos_len..*neg_len).map(FixedLenSlice).collect()
715+
(pos_len..neg_len).map(FixedLenSlice).collect()
707716
}
708717
}
709-
(VarLenSlice(pos_len), FixedLenSlice(neg_len)) => {
718+
(&VarLenSlice(pos_prefix, pos_suffix), &FixedLenSlice(neg_len)) => {
719+
let pos_len = pos_prefix + pos_suffix;
710720
if neg_len < pos_len {
711721
smallvec![pos_ctor]
712722
} else {
713-
(*pos_len..*neg_len)
723+
(pos_len..neg_len)
714724
.map(FixedLenSlice)
715-
.chain(Some(VarLenSlice(neg_len + 1)))
725+
// We know neg_len + 1 >= pos_len >= pos_suffix
726+
.chain(Some(VarLenSlice(
727+
neg_len + 1 - pos_suffix,
728+
pos_suffix,
729+
)))
716730
.collect()
717731
}
718732
}
@@ -784,7 +798,8 @@ impl<'tcx> Constructor<'tcx> {
784798
match ty.kind {
785799
ty::Tuple(ref fs) => fs.len() as u64,
786800
ty::Slice(..) | ty::Array(..) => match *self {
787-
FixedLenSlice(length) | VarLenSlice(length) => length,
801+
FixedLenSlice(length) => length,
802+
VarLenSlice(prefix, suffix) => prefix + suffix,
788803
ConstantValue(..) => 0,
789804
_ => bug!("bad slice pattern {:?} {:?}", self, ty),
790805
},
@@ -845,10 +860,11 @@ impl<'tcx> Constructor<'tcx> {
845860
FixedLenSlice(_) => {
846861
PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
847862
}
848-
VarLenSlice(_) => {
849-
let prefix = subpatterns.collect();
863+
VarLenSlice(prefix_len, _suffix_len) => {
864+
let prefix = subpatterns.by_ref().take(*prefix_len as usize).collect();
865+
let suffix = subpatterns.collect();
850866
let wild = Pat { ty, span: DUMMY_SP, kind: Box::new(PatKind::Wild) };
851-
PatKind::Slice { prefix, slice: Some(wild), suffix: vec![] }
867+
PatKind::Slice { prefix, slice: Some(wild), suffix }
852868
}
853869
_ => bug!("bad slice pattern {:?} {:?}", self, ty),
854870
},
@@ -1072,7 +1088,7 @@ fn all_constructors<'a, 'tcx>(
10721088
if cx.is_uninhabited(sub_ty) {
10731089
vec![FixedLenSlice(0)]
10741090
} else {
1075-
vec![VarLenSlice(0)]
1091+
vec![VarLenSlice(0, 0)]
10761092
}
10771093
}
10781094
ty::Adt(def, substs) if def.is_enum() => def
@@ -1796,11 +1812,12 @@ fn pat_constructors<'tcx>(
17961812
_ => span_bug!(pat.span, "bad ty {:?} for array pattern", pcx.ty),
17971813
},
17981814
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
1799-
let pat_len = prefix.len() as u64 + suffix.len() as u64;
1815+
let prefix = prefix.len() as u64;
1816+
let suffix = suffix.len() as u64;
18001817
if slice.is_some() {
1801-
Some(vec![VarLenSlice(pat_len)])
1818+
Some(vec![VarLenSlice(prefix, suffix)])
18021819
} else {
1803-
Some(vec![FixedLenSlice(pat_len)])
1820+
Some(vec![FixedLenSlice(prefix + suffix)])
18041821
}
18051822
}
18061823
PatKind::Or { .. } => {
@@ -1822,7 +1839,8 @@ fn constructor_sub_pattern_tys<'a, 'tcx>(
18221839
match ty.kind {
18231840
ty::Tuple(ref fs) => fs.into_iter().map(|t| t.expect_ty()).collect(),
18241841
ty::Slice(ty) | ty::Array(ty, _) => match *ctor {
1825-
FixedLenSlice(length) | VarLenSlice(length) => (0..length).map(|_| ty).collect(),
1842+
FixedLenSlice(length) => (0..length).map(|_| ty).collect(),
1843+
VarLenSlice(prefix, suffix) => (0..prefix + suffix).map(|_| ty).collect(),
18261844
ConstantValue(..) => vec![],
18271845
_ => bug!("bad slice pattern {:?} {:?}", ctor, ty),
18281846
},
@@ -2078,8 +2096,8 @@ fn split_grouped_constructors<'p, 'tcx>(
20782096
split_ctors.push(IntRange::range_to_ctor(tcx, ty, range, span));
20792097
}
20802098
}
2081-
VarLenSlice(len) => {
2082-
split_ctors.extend((len..pcx.max_slice_length + 1).map(FixedLenSlice))
2099+
VarLenSlice(prefix, suffix) => {
2100+
split_ctors.extend((prefix + suffix..pcx.max_slice_length + 1).map(FixedLenSlice))
20832101
}
20842102
// Any other constructor can be used unchanged.
20852103
_ => split_ctors.push(ctor),

0 commit comments

Comments
 (0)