ast: Reduce size of `ExprKind` by boxing fields of `ExprKind::Struct`

This commit is contained in:
Vadim Petrochenkov 2021-03-16 03:15:53 +03:00
parent b25d3ba781
commit d1522b39dd
12 changed files with 48 additions and 28 deletions

View File

@ -1074,7 +1074,7 @@ pub struct Expr {
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Expr, 120);
rustc_data_structures::static_assert_size!(Expr, 104);
impl Expr {
/// Returns `true` if this expression would be valid somewhere that expects a value;
@ -1244,6 +1244,13 @@ pub enum StructRest {
None,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct StructExpr {
pub path: Path,
pub fields: Vec<ExprField>,
pub rest: StructRest,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ExprKind {
/// A `box x` expression.
@ -1369,7 +1376,7 @@ pub enum ExprKind {
/// A struct literal expression.
///
/// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. rest}`.
Struct(Path, Vec<ExprField>, StructRest),
Struct(P<StructExpr>),
/// An array literal constructed from one repeated element.
///

View File

@ -1286,10 +1286,11 @@ pub fn noop_visit_expr<T: MutVisitor>(
visit_vec(inputs, |(_c, expr)| vis.visit_expr(expr));
}
ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
ExprKind::Struct(path, fields, expr) => {
ExprKind::Struct(se) => {
let StructExpr { path, fields, rest } = se.deref_mut();
vis.visit_path(path);
fields.flat_map_in_place(|field| vis.flat_map_expr_field(field));
match expr {
match rest {
StructRest::Base(expr) => vis.visit_expr(expr),
StructRest::Rest(_span) => {}
StructRest::None => {}

View File

@ -721,10 +721,10 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
visitor.visit_expr(element);
visitor.visit_anon_const(count)
}
ExprKind::Struct(ref path, ref fields, ref optional_base) => {
visitor.visit_path(path, expression.id);
walk_list!(visitor, visit_expr_field, fields);
match optional_base {
ExprKind::Struct(ref se) => {
visitor.visit_path(&se.path, expression.id);
walk_list!(visitor, visit_expr_field, &se.fields);
match &se.rest {
StructRest::Base(expr) => visitor.visit_expr(expr),
StructRest::Rest(_span) => {}
StructRest::None => {}

View File

@ -224,8 +224,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
ExprKind::InlineAsm(ref asm) => self.lower_expr_asm(e.span, asm),
ExprKind::LlvmInlineAsm(ref asm) => self.lower_expr_llvm_asm(asm),
ExprKind::Struct(ref path, ref fields, ref rest) => {
let rest = match rest {
ExprKind::Struct(ref se) => {
let rest = match &se.rest {
StructRest::Base(e) => Some(self.lower_expr(e)),
StructRest::Rest(sp) => {
self.sess
@ -240,11 +240,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc(self.lower_qpath(
e.id,
&None,
path,
&se.path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
)),
self.arena.alloc_from_iter(fields.iter().map(|x| self.lower_expr_field(x))),
self.arena
.alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))),
rest,
)
}
@ -1110,8 +1111,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
// Structs.
ExprKind::Struct(path, fields, rest) => {
let field_pats = self.arena.alloc_from_iter(fields.iter().map(|f| {
ExprKind::Struct(se) => {
let field_pats = self.arena.alloc_from_iter(se.fields.iter().map(|f| {
let pat = self.destructure_assign(&f.expr, eq_sign_span, assignments);
hir::PatField {
hir_id: self.next_id(),
@ -1124,11 +1125,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
let qpath = self.lower_qpath(
lhs.id,
&None,
path,
&se.path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
);
let fields_omitted = match rest {
let fields_omitted = match &se.rest {
StructRest::Base(e) => {
self.sess
.struct_span_err(

View File

@ -1873,8 +1873,8 @@ impl<'a> State<'a> {
ast::ExprKind::Repeat(ref element, ref count) => {
self.print_expr_repeat(element, count, attrs);
}
ast::ExprKind::Struct(ref path, ref fields, ref rest) => {
self.print_expr_struct(path, &fields[..], rest, attrs);
ast::ExprKind::Struct(ref se) => {
self.print_expr_struct(&se.path, &se.fields, &se.rest, attrs);
}
ast::ExprKind::Tup(ref exprs) => {
self.print_expr_tup(&exprs[..], attrs);

View File

@ -284,7 +284,10 @@ impl<'a> ExtCtxt<'a> {
path: ast::Path,
fields: Vec<ast::ExprField>,
) -> P<ast::Expr> {
self.expr(span, ast::ExprKind::Struct(path, fields, ast::StructRest::None))
self.expr(
span,
ast::ExprKind::Struct(P(ast::StructExpr { path, fields, rest: ast::StructRest::None })),
)
}
pub fn expr_struct_ident(
&self,

View File

@ -2373,7 +2373,11 @@ impl<'a> Parser<'a> {
let span = pth.span.to(self.token.span);
self.expect(&token::CloseDelim(token::Brace))?;
let expr = if recover_async { ExprKind::Err } else { ExprKind::Struct(pth, fields, base) };
let expr = if recover_async {
ExprKind::Err
} else {
ExprKind::Struct(P(ast::StructExpr { path: pth, fields, rest: base }))
};
Ok(self.mk_expr(span, expr, attrs))
}

View File

@ -2251,8 +2251,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
visit::walk_expr(self, expr);
}
ExprKind::Struct(ref path, ..) => {
self.smart_resolve_path(expr.id, None, path, PathSource::Struct);
ExprKind::Struct(ref se) => {
self.smart_resolve_path(expr.id, None, &se.path, PathSource::Struct);
visit::walk_expr(self, expr);
}

View File

@ -155,7 +155,9 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
},
17 => {
let path = Path::from_ident(Ident::from_str("S"));
g(ExprKind::Struct(path, vec![], StructRest::Base(make_x())));
g(ExprKind::Struct(P(StructExpr {
path, fields: vec![], rest: StructRest::Base(make_x())
})));
},
18 => {
iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e)));

View File

@ -58,8 +58,8 @@ impl EarlyLintPass for RedundantFieldNames {
if in_external_macro(cx.sess, expr.span) {
return;
}
if let ExprKind::Struct(_, ref fields, _) = expr.kind {
for field in fields {
if let ExprKind::Struct(ref se) = expr.kind {
for field in &se.fields {
if field.is_shorthand {
continue;
}

View File

@ -564,7 +564,7 @@ fn ident_difference_expr_with_base_location(
| (Try(_), Try(_))
| (Paren(_), Paren(_))
| (Repeat(_, _), Repeat(_, _))
| (Struct(_, _, _), Struct(_, _, _))
| (Struct(_), Struct(_))
| (MacCall(_), MacCall(_))
| (LlvmInlineAsm(_), LlvmInlineAsm(_))
| (InlineAsm(_), InlineAsm(_))

View File

@ -168,8 +168,10 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re),
(Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
(Struct(lp, lfs, lb), Struct(rp, rfs, rb)) => {
eq_path(lp, rp) && eq_struct_rest(lb, rb) && unordered_over(lfs, rfs, |l, r| eq_field(l, r))
(Struct(lse), Struct(rse)) => {
eq_path(&lse.path, &rse.path) &&
eq_struct_rest(&lse.rest, &rse.rest) &&
unordered_over(&lse.fields, &rse.fields, |l, r| eq_field(l, r))
},
_ => false,
}