From d1522b39dded68a3c442bed0b0a231020c6e2291 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 16 Mar 2021 03:15:53 +0300 Subject: [PATCH] ast: Reduce size of `ExprKind` by boxing fields of `ExprKind::Struct` --- compiler/rustc_ast/src/ast.rs | 11 +++++++++-- compiler/rustc_ast/src/mut_visit.rs | 5 +++-- compiler/rustc_ast/src/visit.rs | 8 ++++---- compiler/rustc_ast_lowering/src/expr.rs | 17 +++++++++-------- compiler/rustc_ast_pretty/src/pprust/state.rs | 4 ++-- compiler/rustc_expand/src/build.rs | 5 ++++- compiler/rustc_parse/src/parser/expr.rs | 6 +++++- compiler/rustc_resolve/src/late.rs | 4 ++-- src/test/ui-fulldeps/pprust-expr-roundtrip.rs | 4 +++- .../clippy_lints/src/redundant_field_names.rs | 4 ++-- .../src/suspicious_operation_groupings.rs | 2 +- src/tools/clippy/clippy_utils/src/ast_utils.rs | 6 ++++-- 12 files changed, 48 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index e3de0cc0a7e..d48b70e902e 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -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, + 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, StructRest), + Struct(P), /// An array literal constructed from one repeated element. /// diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 9bdd8935914..f426f2c7fec 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1286,10 +1286,11 @@ pub fn noop_visit_expr( 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 => {} diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 722666af7ac..b1ad29e4ad8 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -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 => {} diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 16514f7cc13..0400a421f7f 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -224,8 +224,8 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'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 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'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 @@ fn destructure_assign( } } // 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 @@ fn destructure_assign( 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( diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 9b893de7da3..cb6f567c551 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1873,8 +1873,8 @@ fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline: bool) { 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); diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index efaac1f11e9..3664ff3ae8a 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -284,7 +284,10 @@ pub fn expr_struct( path: ast::Path, fields: Vec, ) -> P { - 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, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 083702d9469..a3f2a8b3c57 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2373,7 +2373,11 @@ pub(super) fn parse_struct_expr( 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)) } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 6f24d7e9413..af241ef8afc 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2251,8 +2251,8 @@ fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) { 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); } diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs index bff92d8607e..ac2d29c9caf 100644 --- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs @@ -155,7 +155,9 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P)) { }, 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))); diff --git a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs index 38dcf7a192c..9688ef39331 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs @@ -58,8 +58,8 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { 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; } diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs index 44521885d20..9acc47deb06 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs @@ -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(_)) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 05afa534296..ea9a910d1b9 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -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, }