Skip to content

Commit 766ab78

Browse files
committed
Simplify slice splitting a bit
1 parent cd4c714 commit 766ab78

File tree

1 file changed

+28
-41
lines changed
  • compiler/rustc_mir_build/src/thir/pattern

1 file changed

+28
-41
lines changed

compiler/rustc_mir_build/src/thir/pattern/_match.rs

+28-41
Original file line numberDiff line numberDiff line change
@@ -620,21 +620,17 @@ struct Slice {
620620
}
621621

622622
impl Slice {
623-
/// Returns what patterns this constructor covers: either fixed-length patterns or
624-
/// variable-length patterns.
625-
fn kind(self) -> SliceKind {
626-
match self {
627-
Slice { array_len: Some(len), kind: VarLen(prefix, suffix) }
628-
if prefix + suffix == len =>
629-
{
630-
FixedLen(len)
631-
}
632-
_ => self.kind,
633-
}
623+
fn new(array_len: Option<u64>, kind: SliceKind) -> Self {
624+
let kind = match (array_len, kind) {
625+
// If the middle `..` is empty, we effectively have a fixed-length pattern.
626+
(Some(len), VarLen(prefix, suffix)) if prefix + suffix >= len => FixedLen(len),
627+
_ => kind,
628+
};
629+
Slice { array_len, kind }
634630
}
635631

636632
fn arity(self) -> u64 {
637-
self.kind().arity()
633+
self.kind.arity()
638634
}
639635

640636
/// The exhaustiveness-checking paper does not include any details on
@@ -701,10 +697,8 @@ impl Slice {
701697
/// witness of length ≥2 (say, `[false, false, true]`) can be
702698
/// turned to a witness from any other length ≥2.
703699
fn split<'p, 'tcx>(self, pcx: PatCtxt<'_, 'p, 'tcx>) -> SmallVec<[Constructor<'tcx>; 1]> {
704-
let (array_len, self_prefix, self_suffix) = match self {
705-
Slice { array_len, kind: VarLen(self_prefix, self_suffix) } => {
706-
(array_len, self_prefix, self_suffix)
707-
}
700+
let (self_prefix, self_suffix) = match self.kind {
701+
VarLen(self_prefix, self_suffix) => (self_prefix, self_suffix),
708702
_ => return smallvec![Slice(self)],
709703
};
710704

@@ -716,7 +710,7 @@ impl Slice {
716710

717711
for ctor in head_ctors {
718712
if let Slice(slice) = ctor {
719-
match slice.kind() {
713+
match slice.kind {
720714
FixedLen(len) => {
721715
max_fixed_len = cmp::max(max_fixed_len, len);
722716
}
@@ -725,6 +719,8 @@ impl Slice {
725719
max_suffix_len = cmp::max(max_suffix_len, suffix);
726720
}
727721
}
722+
} else {
723+
bug!("unexpected ctor for slice type: {:?}", ctor);
728724
}
729725
}
730726

@@ -738,27 +734,19 @@ impl Slice {
738734
max_prefix_len = max_fixed_len + 1 - max_suffix_len;
739735
}
740736

741-
match array_len {
742-
Some(len) => {
743-
let kind = if max_prefix_len + max_suffix_len < len {
744-
VarLen(max_prefix_len, max_suffix_len)
745-
} else {
746-
FixedLen(len)
747-
};
748-
smallvec![Slice(Slice { array_len, kind })]
749-
}
737+
let final_slice = VarLen(max_prefix_len, max_suffix_len);
738+
let final_slice = Slice::new(self.array_len, final_slice);
739+
match self.array_len {
740+
Some(_) => smallvec![Slice(final_slice)],
750741
None => {
751-
// `ctor` originally covered the range `(self_prefix +
752-
// self_suffix..infinity)`. We now split it into two: lengths smaller than
753-
// `max_prefix_len + max_suffix_len` are treated independently as
754-
// fixed-lengths slices, and lengths above are captured by a final VarLen
755-
// constructor.
756-
let smaller_lengths =
757-
(self_prefix + self_suffix..max_prefix_len + max_suffix_len).map(FixedLen);
758-
let final_slice = VarLen(max_prefix_len, max_suffix_len);
742+
// `self` originally covered the range `(self.arity()..infinity)`. We split that
743+
// range into two: lengths smaller than `final_slice.arity()` are treated
744+
// independently as fixed-lengths slices, and lengths above are captured by
745+
// `final_slice`.
746+
let smaller_lengths = (self.arity()..final_slice.arity()).map(FixedLen);
759747
smaller_lengths
748+
.map(|kind| Slice::new(self.array_len, kind))
760749
.chain(Some(final_slice))
761-
.map(|kind| Slice { array_len, kind })
762750
.map(Slice)
763751
.collect()
764752
}
@@ -767,7 +755,7 @@ impl Slice {
767755

768756
/// See `Constructor::is_covered_by`
769757
fn is_covered_by(self, other: Self) -> bool {
770-
other.kind().covers_length(self.arity())
758+
other.kind.covers_length(self.arity())
771759
}
772760
}
773761

@@ -934,7 +922,6 @@ impl<'tcx> Constructor<'tcx> {
934922
None => false,
935923
}
936924
}
937-
938925
(Slice(self_slice), Slice(other_slice)) => self_slice.is_covered_by(*other_slice),
939926

940927
// We are trying to inspect an opaque constant. Thus we skip the row.
@@ -1029,7 +1016,7 @@ impl<'tcx> Constructor<'tcx> {
10291016
ty::Slice(_) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, pcx.ty),
10301017
_ => PatKind::Wild,
10311018
},
1032-
Slice(slice) => match slice.kind() {
1019+
Slice(slice) => match slice.kind {
10331020
FixedLen(_) => {
10341021
PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
10351022
}
@@ -1533,13 +1520,13 @@ fn all_constructors<'p, 'tcx>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Vec<Constructor<'tc
15331520
if len != 0 && cx.is_uninhabited(sub_ty) {
15341521
vec![]
15351522
} else {
1536-
vec![Slice(Slice { array_len: Some(len), kind: VarLen(0, 0) })]
1523+
vec![Slice(Slice::new(Some(len), VarLen(0, 0)))]
15371524
}
15381525
}
15391526
// Treat arrays of a constant but unknown length like slices.
15401527
ty::Array(sub_ty, _) | ty::Slice(sub_ty) => {
15411528
let kind = if cx.is_uninhabited(sub_ty) { FixedLen(0) } else { VarLen(0, 0) };
1542-
vec![Slice(Slice { array_len: None, kind })]
1529+
vec![Slice(Slice::new(None, kind))]
15431530
}
15441531
ty::Adt(def, substs) if def.is_enum() => {
15451532
// If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an
@@ -2224,7 +2211,7 @@ fn pat_constructor<'p, 'tcx>(
22242211
let suffix = suffix.len() as u64;
22252212
let kind =
22262213
if slice.is_some() { VarLen(prefix, suffix) } else { FixedLen(prefix + suffix) };
2227-
Slice(Slice { array_len, kind })
2214+
Slice(Slice::new(array_len, kind))
22282215
}
22292216
PatKind::Or { .. } => bug!("Or-pattern should have been expanded earlier on."),
22302217
}

0 commit comments

Comments
 (0)