Skip to content

Commit ad09cc5

Browse files
committed
Store both prefix and suffix length in VarLenSlice
1 parent 244ac8d commit ad09cc5

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -582,8 +582,8 @@ enum Constructor<'tcx> {
582582
// Meta-constructors
583583
/// Ranges of literal values (`2..=5` and `2..5`).
584584
ConstantRange(u128, u128, Ty<'tcx>, RangeEnd),
585-
/// Slice patterns. Captures any array constructor of length >= n.
586-
VarLenSlice(u64),
585+
/// Slice patterns. Captures any array constructor of length >= i+j.
586+
VarLenSlice(u64, u64),
587587
/// Wildcard metaconstructor.
588588
Wildcard,
589589
/// List of constructors that were _not_ present in the first column
@@ -739,7 +739,9 @@ impl<'tcx> Constructor<'tcx> {
739739
.collect()
740740
}
741741
ConstantRange(..) => smallvec![self],
742-
VarLenSlice(len) => (*len..pcx.max_slice_length + 1).map(FixedLenSlice).collect(),
742+
VarLenSlice(prefix, suffix) => {
743+
(prefix + suffix..pcx.max_slice_length + 1).map(FixedLenSlice).collect()
744+
}
743745
Wildcard => {
744746
let is_declared_nonexhaustive =
745747
!cx.is_local(pcx.ty) && cx.is_non_exhaustive_enum(pcx.ty);
@@ -852,20 +854,21 @@ impl<'tcx> Constructor<'tcx> {
852854
FixedLenSlice(self_len) => {
853855
let overlaps = |c: &Constructor<'_>| match c {
854856
FixedLenSlice(other_len) => *other_len == self_len,
855-
VarLenSlice(other_len) => *other_len <= self_len,
857+
VarLenSlice(prefix, suffix) => prefix + suffix <= self_len,
856858
_ => false,
857859
};
858860
if used_ctors.iter().any(overlaps) { smallvec![] } else { smallvec![self] }
859861
}
860-
VarLenSlice(self_len) => {
862+
VarLenSlice(self_prefix, self_suffix) => {
863+
let self_len = self_prefix + self_suffix;
861864
// Initially we cover all slice lengths starting from self_len.
862865

863866
// If there is a VarLenSlice(n) in used_ctors, then we have to discard
864867
// all lengths >= n. So we pick the smallest one.
865868
let max_len: Option<_> = used_ctors
866869
.iter()
867870
.filter_map(|c: &Constructor<'tcx>| match c {
868-
VarLenSlice(other_len) => Some(*other_len),
871+
VarLenSlice(prefix, suffix) => Some(prefix + suffix),
869872
_ => None,
870873
})
871874
.min();
@@ -926,7 +929,7 @@ impl<'tcx> Constructor<'tcx> {
926929
Start => self_len,
927930
Boundary(n) => n + 1,
928931
};
929-
remaining_ctors.push(VarLenSlice(final_length));
932+
remaining_ctors.push(VarLenSlice(final_length, 0));
930933
}
931934

932935
remaining_ctors
@@ -970,7 +973,7 @@ impl<'tcx> Constructor<'tcx> {
970973
ty: Ty<'tcx>,
971974
) -> impl Iterator<Item = Pat<'tcx>> + DoubleEndedIterator {
972975
debug!("wildcard_subpatterns({:#?}, {:?})", self, ty);
973-
let subpattern_types = match self {
976+
let subpattern_types = match *self {
974977
Single | Variant(_) => match ty.kind {
975978
ty::Tuple(ref fs) => fs.into_iter().map(|t| t.expect_ty()).collect(),
976979
ty::Ref(_, rty, _) => vec![rty],
@@ -1015,8 +1018,12 @@ impl<'tcx> Constructor<'tcx> {
10151018
ty::Slice(ty) | ty::Array(ty, _) => bug!("bad slice pattern {:?} {:?}", self, ty),
10161019
_ => vec![],
10171020
},
1018-
FixedLenSlice(length) | VarLenSlice(length) => match ty.kind {
1019-
ty::Slice(ty) | ty::Array(ty, _) => (0..*length).map(|_| ty).collect(),
1021+
FixedLenSlice(length) => match ty.kind {
1022+
ty::Slice(ty) | ty::Array(ty, _) => (0..length).map(|_| ty).collect(),
1023+
_ => bug!("bad slice pattern {:?} {:?}", self, ty),
1024+
},
1025+
VarLenSlice(prefix, suffix) => match ty.kind {
1026+
ty::Slice(ty) | ty::Array(ty, _) => (0..prefix + suffix).map(|_| ty).collect(),
10201027
_ => bug!("bad slice pattern {:?} {:?}", self, ty),
10211028
},
10221029
ConstantValue(_) | MissingConstructors(_) | ConstantRange(..) | Wildcard => vec![],
@@ -1032,7 +1039,7 @@ impl<'tcx> Constructor<'tcx> {
10321039
/// A struct pattern's arity is the number of fields it contains, etc.
10331040
fn arity<'a>(&self, cx: &MatchCheckCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> u64 {
10341041
debug!("Constructor::arity({:#?}, {:?})", self, ty);
1035-
match self {
1042+
match *self {
10361043
Single | Variant(_) => match ty.kind {
10371044
ty::Tuple(ref fs) => fs.len() as u64,
10381045
ty::Ref(..) => 1,
@@ -1042,7 +1049,8 @@ impl<'tcx> Constructor<'tcx> {
10421049
ty::Slice(..) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, ty),
10431050
_ => 0,
10441051
},
1045-
FixedLenSlice(length) | VarLenSlice(length) => *length,
1052+
FixedLenSlice(length) => length,
1053+
VarLenSlice(prefix, suffix) => prefix + suffix,
10461054
ConstantValue(_) | ConstantRange(..) | Wildcard | MissingConstructors(_) => 0,
10471055
}
10481056
}
@@ -1095,7 +1103,7 @@ impl<'tcx> Constructor<'tcx> {
10951103
FixedLenSlice(_) => {
10961104
PatKind::Slice { prefix: pats.collect(), slice: None, suffix: vec![] }
10971105
}
1098-
VarLenSlice(_) => match ty.kind {
1106+
VarLenSlice(_, _) => match ty.kind {
10991107
ty::Slice(ty) | ty::Array(ty, _) => {
11001108
let prefix = pats.collect();
11011109
if cx.tcx.features().slice_patterns {
@@ -1303,7 +1311,7 @@ fn all_constructors<'a, 'tcx>(
13031311
if cx.is_uninhabited(sub_ty) {
13041312
vec![FixedLenSlice(0)]
13051313
} else {
1306-
vec![VarLenSlice(0)]
1314+
vec![VarLenSlice(0, 0)]
13071315
}
13081316
}
13091317
ty::Adt(def, substs) if def.is_enum() => def
@@ -1866,11 +1874,12 @@ fn pat_constructors<'tcx>(
18661874
_ => span_bug!(pat.span, "bad ty {:?} for array pattern", pcx.ty),
18671875
},
18681876
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
1869-
let pat_len = prefix.len() as u64 + suffix.len() as u64;
1877+
let prefix = prefix.len() as u64;
1878+
let suffix = suffix.len() as u64;
18701879
if slice.is_some() {
1871-
smallvec![VarLenSlice(pat_len)]
1880+
smallvec![VarLenSlice(prefix, suffix)]
18721881
} else {
1873-
smallvec![FixedLenSlice(pat_len)]
1882+
smallvec![FixedLenSlice(prefix + suffix)]
18741883
}
18751884
}
18761885
PatKind::Or { .. } => {

0 commit comments

Comments
 (0)