mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
ast: Reduce size of ExprKind
by boxing fields of ExprKind::Struct
This commit is contained in:
parent
b25d3ba781
commit
d1522b39dd
@ -1074,7 +1074,7 @@ pub struct Expr {
|
|||||||
|
|
||||||
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
|
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
#[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 {
|
impl Expr {
|
||||||
/// Returns `true` if this expression would be valid somewhere that expects a value;
|
/// Returns `true` if this expression would be valid somewhere that expects a value;
|
||||||
@ -1244,6 +1244,13 @@ pub enum StructRest {
|
|||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
|
pub struct StructExpr {
|
||||||
|
pub path: Path,
|
||||||
|
pub fields: Vec<ExprField>,
|
||||||
|
pub rest: StructRest,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub enum ExprKind {
|
pub enum ExprKind {
|
||||||
/// A `box x` expression.
|
/// A `box x` expression.
|
||||||
@ -1369,7 +1376,7 @@ pub enum ExprKind {
|
|||||||
/// A struct literal expression.
|
/// A struct literal expression.
|
||||||
///
|
///
|
||||||
/// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. rest}`.
|
/// 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.
|
/// An array literal constructed from one repeated element.
|
||||||
///
|
///
|
||||||
|
@ -1286,10 +1286,11 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
|||||||
visit_vec(inputs, |(_c, expr)| vis.visit_expr(expr));
|
visit_vec(inputs, |(_c, expr)| vis.visit_expr(expr));
|
||||||
}
|
}
|
||||||
ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
|
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);
|
vis.visit_path(path);
|
||||||
fields.flat_map_in_place(|field| vis.flat_map_expr_field(field));
|
fields.flat_map_in_place(|field| vis.flat_map_expr_field(field));
|
||||||
match expr {
|
match rest {
|
||||||
StructRest::Base(expr) => vis.visit_expr(expr),
|
StructRest::Base(expr) => vis.visit_expr(expr),
|
||||||
StructRest::Rest(_span) => {}
|
StructRest::Rest(_span) => {}
|
||||||
StructRest::None => {}
|
StructRest::None => {}
|
||||||
|
@ -721,10 +721,10 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
|||||||
visitor.visit_expr(element);
|
visitor.visit_expr(element);
|
||||||
visitor.visit_anon_const(count)
|
visitor.visit_anon_const(count)
|
||||||
}
|
}
|
||||||
ExprKind::Struct(ref path, ref fields, ref optional_base) => {
|
ExprKind::Struct(ref se) => {
|
||||||
visitor.visit_path(path, expression.id);
|
visitor.visit_path(&se.path, expression.id);
|
||||||
walk_list!(visitor, visit_expr_field, fields);
|
walk_list!(visitor, visit_expr_field, &se.fields);
|
||||||
match optional_base {
|
match &se.rest {
|
||||||
StructRest::Base(expr) => visitor.visit_expr(expr),
|
StructRest::Base(expr) => visitor.visit_expr(expr),
|
||||||
StructRest::Rest(_span) => {}
|
StructRest::Rest(_span) => {}
|
||||||
StructRest::None => {}
|
StructRest::None => {}
|
||||||
|
@ -224,8 +224,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
}
|
}
|
||||||
ExprKind::InlineAsm(ref asm) => self.lower_expr_asm(e.span, asm),
|
ExprKind::InlineAsm(ref asm) => self.lower_expr_asm(e.span, asm),
|
||||||
ExprKind::LlvmInlineAsm(ref asm) => self.lower_expr_llvm_asm(asm),
|
ExprKind::LlvmInlineAsm(ref asm) => self.lower_expr_llvm_asm(asm),
|
||||||
ExprKind::Struct(ref path, ref fields, ref rest) => {
|
ExprKind::Struct(ref se) => {
|
||||||
let rest = match rest {
|
let rest = match &se.rest {
|
||||||
StructRest::Base(e) => Some(self.lower_expr(e)),
|
StructRest::Base(e) => Some(self.lower_expr(e)),
|
||||||
StructRest::Rest(sp) => {
|
StructRest::Rest(sp) => {
|
||||||
self.sess
|
self.sess
|
||||||
@ -240,11 +240,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
self.arena.alloc(self.lower_qpath(
|
self.arena.alloc(self.lower_qpath(
|
||||||
e.id,
|
e.id,
|
||||||
&None,
|
&None,
|
||||||
path,
|
&se.path,
|
||||||
ParamMode::Optional,
|
ParamMode::Optional,
|
||||||
ImplTraitContext::disallowed(),
|
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,
|
rest,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1110,8 +1111,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Structs.
|
// Structs.
|
||||||
ExprKind::Struct(path, fields, rest) => {
|
ExprKind::Struct(se) => {
|
||||||
let field_pats = self.arena.alloc_from_iter(fields.iter().map(|f| {
|
let field_pats = self.arena.alloc_from_iter(se.fields.iter().map(|f| {
|
||||||
let pat = self.destructure_assign(&f.expr, eq_sign_span, assignments);
|
let pat = self.destructure_assign(&f.expr, eq_sign_span, assignments);
|
||||||
hir::PatField {
|
hir::PatField {
|
||||||
hir_id: self.next_id(),
|
hir_id: self.next_id(),
|
||||||
@ -1124,11 +1125,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
let qpath = self.lower_qpath(
|
let qpath = self.lower_qpath(
|
||||||
lhs.id,
|
lhs.id,
|
||||||
&None,
|
&None,
|
||||||
path,
|
&se.path,
|
||||||
ParamMode::Optional,
|
ParamMode::Optional,
|
||||||
ImplTraitContext::disallowed(),
|
ImplTraitContext::disallowed(),
|
||||||
);
|
);
|
||||||
let fields_omitted = match rest {
|
let fields_omitted = match &se.rest {
|
||||||
StructRest::Base(e) => {
|
StructRest::Base(e) => {
|
||||||
self.sess
|
self.sess
|
||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
|
@ -1873,8 +1873,8 @@ impl<'a> State<'a> {
|
|||||||
ast::ExprKind::Repeat(ref element, ref count) => {
|
ast::ExprKind::Repeat(ref element, ref count) => {
|
||||||
self.print_expr_repeat(element, count, attrs);
|
self.print_expr_repeat(element, count, attrs);
|
||||||
}
|
}
|
||||||
ast::ExprKind::Struct(ref path, ref fields, ref rest) => {
|
ast::ExprKind::Struct(ref se) => {
|
||||||
self.print_expr_struct(path, &fields[..], rest, attrs);
|
self.print_expr_struct(&se.path, &se.fields, &se.rest, attrs);
|
||||||
}
|
}
|
||||||
ast::ExprKind::Tup(ref exprs) => {
|
ast::ExprKind::Tup(ref exprs) => {
|
||||||
self.print_expr_tup(&exprs[..], attrs);
|
self.print_expr_tup(&exprs[..], attrs);
|
||||||
|
@ -284,7 +284,10 @@ impl<'a> ExtCtxt<'a> {
|
|||||||
path: ast::Path,
|
path: ast::Path,
|
||||||
fields: Vec<ast::ExprField>,
|
fields: Vec<ast::ExprField>,
|
||||||
) -> P<ast::Expr> {
|
) -> 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(
|
pub fn expr_struct_ident(
|
||||||
&self,
|
&self,
|
||||||
|
@ -2373,7 +2373,11 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
let span = pth.span.to(self.token.span);
|
let span = pth.span.to(self.token.span);
|
||||||
self.expect(&token::CloseDelim(token::Brace))?;
|
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))
|
Ok(self.mk_expr(span, expr, attrs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2251,8 +2251,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||||||
visit::walk_expr(self, expr);
|
visit::walk_expr(self, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprKind::Struct(ref path, ..) => {
|
ExprKind::Struct(ref se) => {
|
||||||
self.smart_resolve_path(expr.id, None, path, PathSource::Struct);
|
self.smart_resolve_path(expr.id, None, &se.path, PathSource::Struct);
|
||||||
visit::walk_expr(self, expr);
|
visit::walk_expr(self, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +155,9 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
|
|||||||
},
|
},
|
||||||
17 => {
|
17 => {
|
||||||
let path = Path::from_ident(Ident::from_str("S"));
|
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 => {
|
18 => {
|
||||||
iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e)));
|
iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e)));
|
||||||
|
@ -58,8 +58,8 @@ impl EarlyLintPass for RedundantFieldNames {
|
|||||||
if in_external_macro(cx.sess, expr.span) {
|
if in_external_macro(cx.sess, expr.span) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let ExprKind::Struct(_, ref fields, _) = expr.kind {
|
if let ExprKind::Struct(ref se) = expr.kind {
|
||||||
for field in fields {
|
for field in &se.fields {
|
||||||
if field.is_shorthand {
|
if field.is_shorthand {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -564,7 +564,7 @@ fn ident_difference_expr_with_base_location(
|
|||||||
| (Try(_), Try(_))
|
| (Try(_), Try(_))
|
||||||
| (Paren(_), Paren(_))
|
| (Paren(_), Paren(_))
|
||||||
| (Repeat(_, _), Repeat(_, _))
|
| (Repeat(_, _), Repeat(_, _))
|
||||||
| (Struct(_, _, _), Struct(_, _, _))
|
| (Struct(_), Struct(_))
|
||||||
| (MacCall(_), MacCall(_))
|
| (MacCall(_), MacCall(_))
|
||||||
| (LlvmInlineAsm(_), LlvmInlineAsm(_))
|
| (LlvmInlineAsm(_), LlvmInlineAsm(_))
|
||||||
| (InlineAsm(_), InlineAsm(_))
|
| (InlineAsm(_), InlineAsm(_))
|
||||||
|
@ -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),
|
(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),
|
(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),
|
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
|
||||||
(Struct(lp, lfs, lb), Struct(rp, rfs, rb)) => {
|
(Struct(lse), Struct(rse)) => {
|
||||||
eq_path(lp, rp) && eq_struct_rest(lb, rb) && unordered_over(lfs, rfs, |l, r| eq_field(l, r))
|
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,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user