Use boxed slices in PatKind.

To shrink it a little more.
This commit is contained in:
Nicholas Nethercote 2022-08-26 12:06:13 +10:00
parent a40124e01c
commit 43a0268f3a
6 changed files with 36 additions and 25 deletions

View File

@ -634,22 +634,22 @@ pub enum PatKind<'tcx> {
/// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty. /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
/// e.g., `&[ref xs @ ..]`. /// e.g., `&[ref xs @ ..]`.
Slice { Slice {
prefix: Vec<Box<Pat<'tcx>>>, prefix: Box<[Box<Pat<'tcx>>]>,
slice: Option<Box<Pat<'tcx>>>, slice: Option<Box<Pat<'tcx>>>,
suffix: Vec<Box<Pat<'tcx>>>, suffix: Box<[Box<Pat<'tcx>>]>,
}, },
/// Fixed match against an array; irrefutable. /// Fixed match against an array; irrefutable.
Array { Array {
prefix: Vec<Box<Pat<'tcx>>>, prefix: Box<[Box<Pat<'tcx>>]>,
slice: Option<Box<Pat<'tcx>>>, slice: Option<Box<Pat<'tcx>>>,
suffix: Vec<Box<Pat<'tcx>>>, suffix: Box<[Box<Pat<'tcx>>]>,
}, },
/// An or-pattern, e.g. `p | q`. /// An or-pattern, e.g. `p | q`.
/// Invariant: `pats.len() >= 2`. /// Invariant: `pats.len() >= 2`.
Or { Or {
pats: Vec<Box<Pat<'tcx>>>, pats: Box<[Box<Pat<'tcx>>]>,
}, },
} }
@ -775,7 +775,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
PatKind::Slice { ref prefix, ref slice, ref suffix } PatKind::Slice { ref prefix, ref slice, ref suffix }
| PatKind::Array { ref prefix, ref slice, ref suffix } => { | PatKind::Array { ref prefix, ref slice, ref suffix } => {
write!(f, "[")?; write!(f, "[")?;
for p in prefix { for p in prefix.iter() {
write!(f, "{}{}", start_or_comma(), p)?; write!(f, "{}{}", start_or_comma(), p)?;
} }
if let Some(ref slice) = *slice { if let Some(ref slice) = *slice {
@ -786,13 +786,13 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
} }
write!(f, "..")?; write!(f, "..")?;
} }
for p in suffix { for p in suffix.iter() {
write!(f, "{}{}", start_or_comma(), p)?; write!(f, "{}{}", start_or_comma(), p)?;
} }
write!(f, "]") write!(f, "]")
} }
PatKind::Or { ref pats } => { PatKind::Or { ref pats } => {
for pat in pats { for pat in pats.iter() {
write!(f, "{}{}", start_or_continue(" | "), pat)?; write!(f, "{}{}", start_or_continue(" | "), pat)?;
} }
Ok(()) Ok(())
@ -809,8 +809,8 @@ mod size_asserts {
static_assert_size!(Block, 56); static_assert_size!(Block, 56);
static_assert_size!(Expr<'_>, 64); static_assert_size!(Expr<'_>, 64);
static_assert_size!(ExprKind<'_>, 40); static_assert_size!(ExprKind<'_>, 40);
static_assert_size!(Pat<'_>, 80); static_assert_size!(Pat<'_>, 72);
static_assert_size!(PatKind<'_>, 64); static_assert_size!(PatKind<'_>, 56);
static_assert_size!(Stmt<'_>, 56); static_assert_size!(Stmt<'_>, 56);
static_assert_size!(StmtKind<'_>, 48); static_assert_size!(StmtKind<'_>, 48);
} }

View File

@ -232,18 +232,18 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
Constant { value: _ } => {} Constant { value: _ } => {}
Range(_) => {} Range(_) => {}
Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => { Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
for subpattern in prefix { for subpattern in prefix.iter() {
visitor.visit_pat(&subpattern); visitor.visit_pat(&subpattern);
} }
if let Some(pat) = slice { if let Some(pat) = slice {
visitor.visit_pat(&pat); visitor.visit_pat(&pat);
} }
for subpattern in suffix { for subpattern in suffix.iter() {
visitor.visit_pat(&subpattern); visitor.visit_pat(&subpattern);
} }
} }
Or { pats } => { Or { pats } => {
for pat in pats { for pat in pats.iter() {
visitor.visit_pat(&pat); visitor.visit_pat(&pat);
} }
} }

View File

@ -764,7 +764,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
| PatKind::Slice { ref prefix, ref slice, ref suffix } => { | PatKind::Slice { ref prefix, ref slice, ref suffix } => {
let from = u64::try_from(prefix.len()).unwrap(); let from = u64::try_from(prefix.len()).unwrap();
let to = u64::try_from(suffix.len()).unwrap(); let to = u64::try_from(suffix.len()).unwrap();
for subpattern in prefix { for subpattern in prefix.iter() {
self.visit_primary_bindings(subpattern, pattern_user_ty.clone().index(), f); self.visit_primary_bindings(subpattern, pattern_user_ty.clone().index(), f);
} }
for subpattern in slice { for subpattern in slice {
@ -774,7 +774,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
f, f,
); );
} }
for subpattern in suffix { for subpattern in suffix.iter() {
self.visit_primary_bindings(subpattern, pattern_user_ty.clone().index(), f); self.visit_primary_bindings(subpattern, pattern_user_ty.clone().index(), f);
} }
} }
@ -827,7 +827,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// may not all be in the leftmost subpattern. For example in // may not all be in the leftmost subpattern. For example in
// `let (x | y) = ...`, the primary binding of `y` occurs in // `let (x | y) = ...`, the primary binding of `y` occurs in
// the right subpattern // the right subpattern
for subpattern in pats { for subpattern in pats.iter() {
self.visit_primary_bindings(subpattern, pattern_user_ty.clone(), f); self.visit_primary_bindings(subpattern, pattern_user_ty.clone(), f);
} }
} }

View File

@ -400,7 +400,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
.map(|val| self.recur(*val, false)) .map(|val| self.recur(*val, false))
.collect::<Result<_, _>>()?, .collect::<Result<_, _>>()?,
slice: None, slice: None,
suffix: Vec::new(), suffix: Box::new([]),
}, },
ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() { ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() {
// These are not allowed and will error elsewhere anyway. // These are not allowed and will error elsewhere anyway.
@ -436,7 +436,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
.map(|val| self.recur(*val, false)) .map(|val| self.recur(*val, false))
.collect::<Result<_, _>>()?, .collect::<Result<_, _>>()?,
slice: None, slice: None,
suffix: vec![], suffix: Box::new([]),
}, },
span, span,
ty: *pointee_ty, ty: *pointee_ty,
@ -462,7 +462,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
.map(|val| self.recur(*val, false)) .map(|val| self.recur(*val, false))
.collect::<Result<_, _>>()?, .collect::<Result<_, _>>()?,
slice: None, slice: None,
suffix: vec![], suffix: Box::new([]),
}, },
span, span,
ty: tcx.mk_slice(elem_ty), ty: tcx.mk_slice(elem_ty),

View File

@ -72,7 +72,7 @@ use std::ops::RangeInclusive;
fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> { fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> {
fn expand<'p, 'tcx>(pat: &'p Pat<'tcx>, vec: &mut Vec<&'p Pat<'tcx>>) { fn expand<'p, 'tcx>(pat: &'p Pat<'tcx>, vec: &mut Vec<&'p Pat<'tcx>>) {
if let PatKind::Or { pats } = &pat.kind { if let PatKind::Or { pats } = &pat.kind {
for pat in pats { for pat in pats.iter() {
expand(&pat, vec); expand(&pat, vec);
} }
} else { } else {
@ -1433,7 +1433,8 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
FixedLen(prefix.len() + suffix.len()) FixedLen(prefix.len() + suffix.len())
}; };
ctor = Slice(Slice::new(array_len, kind)); ctor = Slice(Slice::new(array_len, kind));
fields = Fields::from_iter(cx, prefix.iter().chain(suffix).map(|p| mkpat(&*p))); fields =
Fields::from_iter(cx, prefix.iter().chain(suffix.iter()).map(|p| mkpat(&*p)));
} }
PatKind::Or { .. } => { PatKind::Or { .. } => {
ctor = Or; ctor = Or;
@ -1489,7 +1490,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
FixedLen(_) => PatKind::Slice { FixedLen(_) => PatKind::Slice {
prefix: subpatterns.collect(), prefix: subpatterns.collect(),
slice: None, slice: None,
suffix: vec![], suffix: Box::new([]),
}, },
VarLen(prefix, _) => { VarLen(prefix, _) => {
let mut subpatterns = subpatterns.peekable(); let mut subpatterns = subpatterns.peekable();
@ -1508,9 +1509,13 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
subpatterns.next(); subpatterns.next();
} }
} }
let suffix: Vec<_> = subpatterns.collect(); let suffix: Box<[_]> = subpatterns.collect();
let wild = Pat::wildcard_from_ty(self.ty); let wild = Pat::wildcard_from_ty(self.ty);
PatKind::Slice { prefix, slice: Some(Box::new(wild)), suffix } PatKind::Slice {
prefix: prefix.into_boxed_slice(),
slice: Some(Box::new(wild)),
suffix,
}
} }
} }
} }

View File

@ -344,7 +344,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
.collect() .collect()
} }
fn lower_patterns(&mut self, pats: &'tcx [hir::Pat<'tcx>]) -> Vec<Box<Pat<'tcx>>> { fn lower_patterns(&mut self, pats: &'tcx [hir::Pat<'tcx>]) -> Box<[Box<Pat<'tcx>>]> {
pats.iter().map(|p| self.lower_pattern(p)).collect() pats.iter().map(|p| self.lower_pattern(p)).collect()
} }
@ -653,6 +653,12 @@ impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Vec<T> {
} }
} }
impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Box<[T]> {
fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
self.iter().map(|t| t.fold_with(folder)).collect()
}
}
impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Option<T> { impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Option<T> {
fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self { fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
self.as_ref().map(|t| t.fold_with(folder)) self.as_ref().map(|t| t.fold_with(folder))