From 0d69fe8308a76630a104504c14e1d3d74e2a3f15 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 12 Dec 2019 16:41:18 +1100 Subject: [PATCH 1/2] Use `P` for `NtTraitItem`, `NtImplItem`, and `NtForeignItem`. This commit reduces the size of `Nonterminal` from a whopping 240 bytes to 72 bytes (on x86-64), which gets it below the `memcpy` threshold. It also removes some impedance mismatches with `Annotatable`, which already uses `P` for these variants. --- .../deriving/generic/mod.rs | 15 ++-- src/librustc_expand/base.rs | 36 ++++---- src/librustc_expand/expand.rs | 84 +++++++++++-------- src/librustc_expand/placeholders.rs | 37 ++++---- src/librustc_interface/util.rs | 4 +- src/librustc_parse/config.rs | 4 +- src/librustc_parse/parser/item.rs | 34 ++++---- src/librustc_resolve/late.rs | 4 +- src/librustc_save_analysis/dump_visitor.rs | 4 +- src/libsyntax/ast.rs | 6 +- src/libsyntax/mut_visit.rs | 18 ++-- src/libsyntax/token.rs | 10 ++- 12 files changed, 138 insertions(+), 118 deletions(-) diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index f8918016c1b98..9377f194dcd5e 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -531,13 +531,13 @@ impl<'a> TraitDef<'a> { type_ident: Ident, generics: &Generics, field_tys: Vec>, - methods: Vec, + methods: Vec>, ) -> P { let trait_path = self.path.to_path(cx, self.span, type_ident, generics); // Transform associated types from `deriving::ty::Ty` into `ast::AssocItem` - let associated_types = - self.associated_types.iter().map(|&(ident, ref type_def)| ast::AssocItem { + let associated_types = self.associated_types.iter().map(|&(ident, ref type_def)| { + P(ast::AssocItem { id: ast::DUMMY_NODE_ID, span: self.span, ident, @@ -550,7 +550,8 @@ impl<'a> TraitDef<'a> { Some(type_def.to_ty(cx, self.span, type_ident, generics)), ), tokens: None, - }); + }) + }); let Generics { mut params, mut where_clause, span } = self.generics.to_generics(cx, self.span, type_ident, generics); @@ -938,7 +939,7 @@ impl<'a> MethodDef<'a> { explicit_self: Option, arg_types: Vec<(Ident, P)>, body: P, - ) -> ast::AssocItem { + ) -> P { // Create the generics that aren't for `Self`. let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics); @@ -968,7 +969,7 @@ impl<'a> MethodDef<'a> { }; // Create the method. - ast::AssocItem { + P(ast::AssocItem { id: ast::DUMMY_NODE_ID, attrs: self.attributes.clone(), generics: fn_generics, @@ -978,7 +979,7 @@ impl<'a> MethodDef<'a> { ident: method_ident, kind: ast::AssocItemKind::Fn(sig, Some(body_block)), tokens: None, - } + }) } /// ``` diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 52ba14dbc3df0..9debae19fa57e 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -136,23 +136,23 @@ impl Annotatable { } } - pub fn expect_trait_item(self) -> ast::AssocItem { + pub fn expect_trait_item(self) -> P { match self { - Annotatable::TraitItem(i) => i.into_inner(), + Annotatable::TraitItem(i) => i, _ => panic!("expected Item"), } } - pub fn expect_impl_item(self) -> ast::AssocItem { + pub fn expect_impl_item(self) -> P { match self { - Annotatable::ImplItem(i) => i.into_inner(), + Annotatable::ImplItem(i) => i, _ => panic!("expected Item"), } } - pub fn expect_foreign_item(self) -> ast::ForeignItem { + pub fn expect_foreign_item(self) -> P { match self { - Annotatable::ForeignItem(i) => i.into_inner(), + Annotatable::ForeignItem(i) => i, _ => panic!("expected foreign item"), } } @@ -382,17 +382,17 @@ pub trait MacResult { } /// Creates zero or more impl items. - fn make_impl_items(self: Box) -> Option> { + fn make_impl_items(self: Box) -> Option; 1]>> { None } /// Creates zero or more trait items. - fn make_trait_items(self: Box) -> Option> { + fn make_trait_items(self: Box) -> Option; 1]>> { None } /// Creates zero or more items in an `extern {}` block - fn make_foreign_items(self: Box) -> Option> { + fn make_foreign_items(self: Box) -> Option; 1]>> { None } @@ -470,9 +470,9 @@ make_MacEager! { expr: P, pat: P, items: SmallVec<[P; 1]>, - impl_items: SmallVec<[ast::AssocItem; 1]>, - trait_items: SmallVec<[ast::AssocItem; 1]>, - foreign_items: SmallVec<[ast::ForeignItem; 1]>, + impl_items: SmallVec<[P; 1]>, + trait_items: SmallVec<[P; 1]>, + foreign_items: SmallVec<[P; 1]>, stmts: SmallVec<[ast::Stmt; 1]>, ty: P, } @@ -486,15 +486,15 @@ impl MacResult for MacEager { self.items } - fn make_impl_items(self: Box) -> Option> { + fn make_impl_items(self: Box) -> Option; 1]>> { self.impl_items } - fn make_trait_items(self: Box) -> Option> { + fn make_trait_items(self: Box) -> Option; 1]>> { self.trait_items } - fn make_foreign_items(self: Box) -> Option> { + fn make_foreign_items(self: Box) -> Option; 1]>> { self.foreign_items } @@ -586,15 +586,15 @@ impl MacResult for DummyResult { Some(SmallVec::new()) } - fn make_impl_items(self: Box) -> Option> { + fn make_impl_items(self: Box) -> Option; 1]>> { Some(SmallVec::new()) } - fn make_trait_items(self: Box) -> Option> { + fn make_trait_items(self: Box) -> Option; 1]>> { Some(SmallVec::new()) } - fn make_foreign_items(self: Box) -> Option> { + fn make_foreign_items(self: Box) -> Option; 1]>> { Some(SmallVec::new()) } diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index f915f44c17ab9..ea459064b0957 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -152,13 +152,13 @@ ast_fragments! { Items(SmallVec<[P; 1]>) { "item"; many fn flat_map_item; fn visit_item; fn make_items; } - TraitItems(SmallVec<[ast::AssocItem; 1]>) { + TraitItems(SmallVec<[P; 1]>) { "trait item"; many fn flat_map_trait_item; fn visit_trait_item; fn make_trait_items; } - ImplItems(SmallVec<[ast::AssocItem; 1]>) { + ImplItems(SmallVec<[P; 1]>) { "impl item"; many fn flat_map_impl_item; fn visit_impl_item; fn make_impl_items; } - ForeignItems(SmallVec<[ast::ForeignItem; 1]>) { + ForeignItems(SmallVec<[P; 1]>) { "foreign item"; many fn flat_map_foreign_item; fn visit_foreign_item; @@ -554,15 +554,15 @@ impl<'a, 'b> MacroExpander<'a, 'b> { // we know that fold result vector will contain exactly one element match item { Annotatable::Item(item) => Annotatable::Item(cfg.flat_map_item(item).pop().unwrap()), - Annotatable::TraitItem(item) => Annotatable::TraitItem( - item.map(|item| cfg.flat_map_trait_item(item).pop().unwrap()), - ), + Annotatable::TraitItem(item) => { + Annotatable::TraitItem(cfg.flat_map_trait_item(item).pop().unwrap()) + } Annotatable::ImplItem(item) => { - Annotatable::ImplItem(item.map(|item| cfg.flat_map_impl_item(item).pop().unwrap())) + Annotatable::ImplItem(cfg.flat_map_impl_item(item).pop().unwrap()) + } + Annotatable::ForeignItem(item) => { + Annotatable::ForeignItem(cfg.flat_map_foreign_item(item).pop().unwrap()) } - Annotatable::ForeignItem(item) => Annotatable::ForeignItem( - item.map(|item| cfg.flat_map_foreign_item(item).pop().unwrap()), - ), Annotatable::Stmt(stmt) => { Annotatable::Stmt(stmt.map(|stmt| cfg.flat_map_stmt(stmt).pop().unwrap())) } @@ -643,11 +643,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let item_tok = TokenTree::token( token::Interpolated(Lrc::new(match item { Annotatable::Item(item) => token::NtItem(item), - Annotatable::TraitItem(item) => token::NtTraitItem(item.into_inner()), - Annotatable::ImplItem(item) => token::NtImplItem(item.into_inner()), - Annotatable::ForeignItem(item) => { - token::NtForeignItem(item.into_inner()) - } + Annotatable::TraitItem(item) => token::NtTraitItem(item), + Annotatable::ImplItem(item) => token::NtImplItem(item), + Annotatable::ForeignItem(item) => token::NtForeignItem(item), Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()), Annotatable::Expr(expr) => token::NtExpr(expr), Annotatable::Arm(..) @@ -1411,7 +1409,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } } - fn flat_map_trait_item(&mut self, item: ast::AssocItem) -> SmallVec<[ast::AssocItem; 1]> { + fn flat_map_trait_item(&mut self, item: P) -> SmallVec<[P; 1]> { let mut item = configure!(self, item); let (attr, traits, after_derive) = self.classify_item(&mut item); @@ -1420,7 +1418,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { .collect_attr( attr, traits, - Annotatable::TraitItem(P(item)), + Annotatable::TraitItem(item), AstFragmentKind::TraitItems, after_derive, ) @@ -1428,16 +1426,20 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } match item.kind { - ast::AssocItemKind::Macro(mac) => { - let ast::AssocItem { attrs, span, .. } = item; - self.check_attributes(&attrs); - self.collect_bang(mac, span, AstFragmentKind::TraitItems).make_trait_items() + ast::AssocItemKind::Macro(..) => { + self.check_attributes(&item.attrs); + item.and_then(|item| match item.kind { + ast::AssocItemKind::Macro(mac) => self + .collect_bang(mac, item.span, AstFragmentKind::TraitItems) + .make_trait_items(), + _ => unreachable!(), + }) } _ => noop_flat_map_assoc_item(item, self), } } - fn flat_map_impl_item(&mut self, item: ast::AssocItem) -> SmallVec<[ast::AssocItem; 1]> { + fn flat_map_impl_item(&mut self, item: P) -> SmallVec<[P; 1]> { let mut item = configure!(self, item); let (attr, traits, after_derive) = self.classify_item(&mut item); @@ -1446,7 +1448,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { .collect_attr( attr, traits, - Annotatable::ImplItem(P(item)), + Annotatable::ImplItem(item), AstFragmentKind::ImplItems, after_derive, ) @@ -1454,10 +1456,14 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } match item.kind { - ast::AssocItemKind::Macro(mac) => { - let ast::AssocItem { attrs, span, .. } = item; - self.check_attributes(&attrs); - self.collect_bang(mac, span, AstFragmentKind::ImplItems).make_impl_items() + ast::AssocItemKind::Macro(..) => { + self.check_attributes(&item.attrs); + item.and_then(|item| match item.kind { + ast::AssocItemKind::Macro(mac) => self + .collect_bang(mac, item.span, AstFragmentKind::ImplItems) + .make_impl_items(), + _ => unreachable!(), + }) } _ => noop_flat_map_assoc_item(item, self), } @@ -1482,8 +1488,8 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { fn flat_map_foreign_item( &mut self, - mut foreign_item: ast::ForeignItem, - ) -> SmallVec<[ast::ForeignItem; 1]> { + mut foreign_item: P, + ) -> SmallVec<[P; 1]> { let (attr, traits, after_derive) = self.classify_item(&mut foreign_item); if attr.is_some() || !traits.is_empty() { @@ -1491,21 +1497,25 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { .collect_attr( attr, traits, - Annotatable::ForeignItem(P(foreign_item)), + Annotatable::ForeignItem(foreign_item), AstFragmentKind::ForeignItems, after_derive, ) .make_foreign_items(); } - if let ast::ForeignItemKind::Macro(mac) = foreign_item.kind { - self.check_attributes(&foreign_item.attrs); - return self - .collect_bang(mac, foreign_item.span, AstFragmentKind::ForeignItems) - .make_foreign_items(); + match foreign_item.kind { + ast::ForeignItemKind::Macro(..) => { + self.check_attributes(&foreign_item.attrs); + foreign_item.and_then(|item| match item.kind { + ast::ForeignItemKind::Macro(mac) => self + .collect_bang(mac, item.span, AstFragmentKind::ForeignItems) + .make_foreign_items(), + _ => unreachable!(), + }) + } + _ => noop_flat_map_foreign_item(foreign_item, self), } - - noop_flat_map_foreign_item(foreign_item, self) } fn visit_item_kind(&mut self, item: &mut ast::ItemKind) { diff --git a/src/librustc_expand/placeholders.rs b/src/librustc_expand/placeholders.rs index 8b18a5dc4bbbb..6bcb8f45f001e 100644 --- a/src/librustc_expand/placeholders.rs +++ b/src/librustc_expand/placeholders.rs @@ -51,7 +51,7 @@ pub fn placeholder( kind: ast::ItemKind::Mac(mac_placeholder()), tokens: None, })]), - AstFragmentKind::TraitItems => AstFragment::TraitItems(smallvec![ast::AssocItem { + AstFragmentKind::TraitItems => AstFragment::TraitItems(smallvec![P(ast::AssocItem { id, span, ident, @@ -61,8 +61,8 @@ pub fn placeholder( kind: ast::AssocItemKind::Macro(mac_placeholder()), defaultness: ast::Defaultness::Final, tokens: None, - }]), - AstFragmentKind::ImplItems => AstFragment::ImplItems(smallvec![ast::AssocItem { + })]), + AstFragmentKind::ImplItems => AstFragment::ImplItems(smallvec![P(ast::AssocItem { id, span, ident, @@ -72,16 +72,18 @@ pub fn placeholder( kind: ast::AssocItemKind::Macro(mac_placeholder()), defaultness: ast::Defaultness::Final, tokens: None, - }]), - AstFragmentKind::ForeignItems => AstFragment::ForeignItems(smallvec![ast::ForeignItem { - id, - span, - ident, - vis, - attrs, - kind: ast::ForeignItemKind::Macro(mac_placeholder()), - tokens: None, - }]), + })]), + AstFragmentKind::ForeignItems => { + AstFragment::ForeignItems(smallvec![P(ast::ForeignItem { + id, + span, + ident, + vis, + attrs, + kind: ast::ForeignItemKind::Macro(mac_placeholder()), + tokens: None, + })]) + } AstFragmentKind::Pat => { AstFragment::Pat(P(ast::Pat { id, span, kind: ast::PatKind::Mac(mac_placeholder()) })) } @@ -250,21 +252,24 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { noop_flat_map_item(item, self) } - fn flat_map_trait_item(&mut self, item: ast::AssocItem) -> SmallVec<[ast::AssocItem; 1]> { + fn flat_map_trait_item(&mut self, item: P) -> SmallVec<[P; 1]> { match item.kind { ast::AssocItemKind::Macro(_) => self.remove(item.id).make_trait_items(), _ => noop_flat_map_assoc_item(item, self), } } - fn flat_map_impl_item(&mut self, item: ast::AssocItem) -> SmallVec<[ast::AssocItem; 1]> { + fn flat_map_impl_item(&mut self, item: P) -> SmallVec<[P; 1]> { match item.kind { ast::AssocItemKind::Macro(_) => self.remove(item.id).make_impl_items(), _ => noop_flat_map_assoc_item(item, self), } } - fn flat_map_foreign_item(&mut self, item: ast::ForeignItem) -> SmallVec<[ast::ForeignItem; 1]> { + fn flat_map_foreign_item( + &mut self, + item: P, + ) -> SmallVec<[P; 1]> { match item.kind { ast::ForeignItemKind::Macro(_) => self.remove(item.id).make_foreign_items(), _ => noop_flat_map_foreign_item(item, self), diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 3e65da9c47b7e..00528eca92301 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -682,7 +682,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { self.run(is_const, |s| noop_visit_item_kind(i, s)) } - fn flat_map_trait_item(&mut self, i: ast::AssocItem) -> SmallVec<[ast::AssocItem; 1]> { + fn flat_map_trait_item(&mut self, i: P) -> SmallVec<[P; 1]> { let is_const = match i.kind { ast::AssocItemKind::Const(..) => true, ast::AssocItemKind::Fn(ref sig, _) => Self::is_sig_const(sig), @@ -691,7 +691,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { self.run(is_const, |s| noop_flat_map_assoc_item(i, s)) } - fn flat_map_impl_item(&mut self, i: ast::AssocItem) -> SmallVec<[ast::AssocItem; 1]> { + fn flat_map_impl_item(&mut self, i: P) -> SmallVec<[P; 1]> { self.flat_map_trait_item(i) } diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs index bf696faf2f3f4..da158e17f25e6 100644 --- a/src/librustc_parse/config.rs +++ b/src/librustc_parse/config.rs @@ -531,11 +531,11 @@ impl<'a> MutVisitor for StripUnconfigured<'a> { noop_flat_map_item(configure!(self, item), self) } - fn flat_map_impl_item(&mut self, item: ast::AssocItem) -> SmallVec<[ast::AssocItem; 1]> { + fn flat_map_impl_item(&mut self, item: P) -> SmallVec<[P; 1]> { noop_flat_map_assoc_item(configure!(self, item), self) } - fn flat_map_trait_item(&mut self, item: ast::AssocItem) -> SmallVec<[ast::AssocItem; 1]> { + fn flat_map_trait_item(&mut self, item: P) -> SmallVec<[P; 1]> { noop_flat_map_assoc_item(configure!(self, item), self) } diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 31db7fc5f759d..f170abac73a63 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -661,7 +661,7 @@ impl<'a> Parser<'a> { Ok((Ident::invalid(), item_kind, Some(attrs))) } - fn parse_impl_body(&mut self) -> PResult<'a, (Vec, Vec)> { + fn parse_impl_body(&mut self) -> PResult<'a, (Vec>, Vec)> { self.expect(&token::OpenDelim(token::Brace))?; let attrs = self.parse_inner_attributes()?; @@ -786,12 +786,12 @@ impl<'a> Parser<'a> { } } - pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, AssocItem> { + pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, P> { maybe_whole!(self, NtImplItem, |x| x); self.parse_assoc_item(at_end, |_| true) } - pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, AssocItem> { + pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, P> { maybe_whole!(self, NtTraitItem, |x| x); // This is somewhat dubious; We don't want to allow // param names to be left off if there is a definition... @@ -805,7 +805,7 @@ impl<'a> Parser<'a> { &mut self, at_end: &mut bool, is_name_required: fn(&token::Token) -> bool, - ) -> PResult<'a, AssocItem> { + ) -> PResult<'a, P> { let attrs = self.parse_outer_attributes()?; let mut unclosed_delims = vec![]; let (mut item, tokens) = self.collect_tokens(|this| { @@ -818,7 +818,7 @@ impl<'a> Parser<'a> { if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) { item.tokens = Some(tokens); } - Ok(item) + Ok(P(item)) } fn parse_assoc_item_( @@ -1064,7 +1064,7 @@ impl<'a> Parser<'a> { } /// Parses a foreign item. - pub fn parse_foreign_item(&mut self, extern_sp: Span) -> PResult<'a, ForeignItem> { + pub fn parse_foreign_item(&mut self, extern_sp: Span) -> PResult<'a, P> { maybe_whole!(self, NtForeignItem, |ni| ni); let attrs = self.parse_outer_attributes()?; @@ -1112,7 +1112,7 @@ impl<'a> Parser<'a> { } match self.parse_assoc_macro_invoc("extern", Some(&visibility), &mut false)? { - Some(mac) => Ok(ForeignItem { + Some(mac) => Ok(P(ForeignItem { ident: Ident::invalid(), span: lo.to(self.prev_span), id: DUMMY_NODE_ID, @@ -1120,7 +1120,7 @@ impl<'a> Parser<'a> { vis: visibility, kind: ForeignItemKind::Macro(mac), tokens: None, - }), + })), None => { if !attrs.is_empty() { self.expected_item_err(&attrs)?; @@ -1138,14 +1138,14 @@ impl<'a> Parser<'a> { vis: ast::Visibility, lo: Span, attrs: Vec, - ) -> PResult<'a, ForeignItem> { + ) -> PResult<'a, P> { let mutbl = self.parse_mutability(); let ident = self.parse_ident()?; self.expect(&token::Colon)?; let ty = self.parse_ty()?; let hi = self.token.span; self.expect_semi()?; - Ok(ForeignItem { + Ok(P(ForeignItem { ident, attrs, kind: ForeignItemKind::Static(ty, mutbl), @@ -1153,7 +1153,7 @@ impl<'a> Parser<'a> { span: lo.to(hi), vis, tokens: None, - }) + })) } /// Parses a type from a foreign module. @@ -1162,13 +1162,13 @@ impl<'a> Parser<'a> { vis: ast::Visibility, lo: Span, attrs: Vec, - ) -> PResult<'a, ForeignItem> { + ) -> PResult<'a, P> { self.expect_keyword(kw::Type)?; let ident = self.parse_ident()?; let hi = self.token.span; self.expect_semi()?; - Ok(ast::ForeignItem { + Ok(P(ast::ForeignItem { ident, attrs, kind: ForeignItemKind::Ty, @@ -1176,7 +1176,7 @@ impl<'a> Parser<'a> { span: lo.to(hi), vis, tokens: None, - }) + })) } fn is_static_global(&mut self) -> bool { @@ -1740,13 +1740,13 @@ impl<'a> Parser<'a> { lo: Span, attrs: Vec, extern_sp: Span, - ) -> PResult<'a, ForeignItem> { + ) -> PResult<'a, P> { self.expect_keyword(kw::Fn)?; let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { is_self_allowed: false, is_name_required: |_| true })?; let span = lo.to(self.token.span); self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?; - Ok(ast::ForeignItem { + Ok(P(ast::ForeignItem { ident, attrs, kind: ForeignItemKind::Fn(decl, generics), @@ -1754,7 +1754,7 @@ impl<'a> Parser<'a> { span, vis, tokens: None, - }) + })) } fn parse_assoc_fn( diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index faa9eb3bc2fa7..f1622af130e77 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -1007,7 +1007,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { /// When evaluating a `trait` use its associated types' idents for suggestionsa in E0412. fn with_trait_items( &mut self, - trait_items: &Vec, + trait_items: &Vec>, f: impl FnOnce(&mut Self) -> T, ) -> T { let trait_assoc_types = replace( @@ -1084,7 +1084,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { opt_trait_reference: &'ast Option, self_type: &'ast Ty, item_id: NodeId, - impl_items: &'ast [AssocItem], + impl_items: &'ast [P], ) { debug!("resolve_implementation"); // If applicable, create a rib for the type parameters. diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index d252fc542c325..2e3e06c36f22b 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -650,7 +650,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { generics: &'l ast::Generics, trait_ref: &'l Option, typ: &'l ast::Ty, - impl_items: &'l [ast::AssocItem], + impl_items: &'l [P], ) { if let Some(impl_data) = self.save_ctxt.get_item_data(item) { if !self.span.filter_generated(item.span) { @@ -681,7 +681,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { item: &'l ast::Item, generics: &'l ast::Generics, trait_refs: &'l ast::GenericBounds, - methods: &'l [ast::AssocItem], + methods: &'l [P], ) { let name = item.ident.to_string(); let qualname = format!( diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 5c64cc440cef3..db4fd53fe1697 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2243,7 +2243,7 @@ pub struct Mod { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct ForeignMod { pub abi: Option, - pub items: Vec, + pub items: Vec>, } /// Global inline assembly. @@ -2605,7 +2605,7 @@ pub enum ItemKind { /// A trait declaration (`trait`). /// /// E.g., `trait Foo { .. }`, `trait Foo { .. }` or `auto trait Foo {}`. - Trait(IsAuto, Unsafety, Generics, GenericBounds, Vec), + Trait(IsAuto, Unsafety, Generics, GenericBounds, Vec>), /// Trait alias /// /// E.g., `trait Foo = Bar + Quux;`. @@ -2624,7 +2624,7 @@ pub enum ItemKind { of_trait: Option, self_ty: P, - items: Vec, + items: Vec>, }, /// A macro invocation. /// diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 4a460c5d7b24c..e9e1675b9b06e 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -82,7 +82,7 @@ pub trait MutVisitor: Sized { noop_visit_use_tree(use_tree, self); } - fn flat_map_foreign_item(&mut self, ni: ForeignItem) -> SmallVec<[ForeignItem; 1]> { + fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { noop_flat_map_foreign_item(ni, self) } @@ -102,11 +102,11 @@ pub trait MutVisitor: Sized { noop_visit_item_kind(i, self); } - fn flat_map_trait_item(&mut self, i: AssocItem) -> SmallVec<[AssocItem; 1]> { + fn flat_map_trait_item(&mut self, i: P) -> SmallVec<[P; 1]> { noop_flat_map_assoc_item(i, self) } - fn flat_map_impl_item(&mut self, i: AssocItem) -> SmallVec<[AssocItem; 1]> { + fn flat_map_impl_item(&mut self, i: P) -> SmallVec<[P; 1]> { noop_flat_map_assoc_item(i, self) } @@ -947,11 +947,11 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { } pub fn noop_flat_map_assoc_item( - mut item: AssocItem, + mut item: P, visitor: &mut T, -) -> SmallVec<[AssocItem; 1]> { +) -> SmallVec<[P; 1]> { let AssocItem { id, ident, vis, defaultness: _, attrs, generics, kind, span, tokens: _ } = - &mut item; + item.deref_mut(); visitor.visit_id(id); visitor.visit_ident(ident); visitor.visit_vis(vis); @@ -1036,10 +1036,10 @@ pub fn noop_flat_map_item( } pub fn noop_flat_map_foreign_item( - mut item: ForeignItem, + mut item: P, visitor: &mut T, -) -> SmallVec<[ForeignItem; 1]> { - let ForeignItem { ident, attrs, id, kind, vis, span, tokens: _ } = &mut item; +) -> SmallVec<[P; 1]> { + let ForeignItem { ident, attrs, id, kind, vis, span, tokens: _ } = item.deref_mut(); visitor.visit_ident(ident); visit_attrs(attrs, visitor); match kind { diff --git a/src/libsyntax/token.rs b/src/libsyntax/token.rs index 14279561cbb8d..c826b728f8004 100644 --- a/src/libsyntax/token.rs +++ b/src/libsyntax/token.rs @@ -680,11 +680,15 @@ pub enum Nonterminal { // Used only for passing items to proc macro attributes (they are not // strictly necessary for that, `Annotatable` can be converted into // tokens directly, but doing that naively regresses pretty-printing). - NtTraitItem(ast::AssocItem), - NtImplItem(ast::AssocItem), - NtForeignItem(ast::ForeignItem), + NtTraitItem(P), + NtImplItem(P), + NtForeignItem(P), } +// `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger. +#[cfg(target_arch = "x86_64")] +rustc_data_structures::static_assert_size!(Nonterminal, 72); + impl PartialEq for Nonterminal { fn eq(&self, rhs: &Self) -> bool { match (self, rhs) { From 7d2173ed27c1cddc4d4a7a9755f244b66cf1ec81 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 13 Dec 2019 11:25:08 +1100 Subject: [PATCH 2/2] Use `P` for `NtMeta`. This commit reduces the size of `Nonterminal` from a 72 bytes to 40 bytes (on x86-64). --- src/librustc_expand/mbe/macro_parser.rs | 3 ++- src/librustc_parse/parser/attr.rs | 2 +- src/libsyntax/mut_visit.rs | 3 ++- src/libsyntax/token.rs | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index 246f66084b813..6e7a4a556b80c 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -81,6 +81,7 @@ use rustc_parse::Directory; use rustc_span::symbol::{kw, sym, Symbol}; use syntax::ast::{Ident, Name}; use syntax::print::pprust; +use syntax::ptr::P; use syntax::sess::ParseSess; use syntax::token::{self, DocComment, Nonterminal, Token}; use syntax::tokenstream::TokenStream; @@ -914,7 +915,7 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, } } sym::path => token::NtPath(p.parse_path(PathStyle::Type)?), - sym::meta => token::NtMeta(p.parse_attr_item()?), + sym::meta => token::NtMeta(P(p.parse_attr_item()?)), sym::vis => token::NtVis(p.parse_visibility(FollowedByType::Yes)?), sym::lifetime => { if p.check_lifetime() { diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index 3d40b91a7bdc8..1869389dbd9e6 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -177,7 +177,7 @@ impl<'a> Parser<'a> { pub fn parse_attr_item(&mut self) -> PResult<'a, ast::AttrItem> { let item = match self.token.kind { token::Interpolated(ref nt) => match **nt { - Nonterminal::NtMeta(ref item) => Some(item.clone()), + Nonterminal::NtMeta(ref item) => Some(item.clone().into_inner()), _ => None, }, _ => None, diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index e9e1675b9b06e..3bcdf8fe286e4 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -704,7 +704,8 @@ pub fn noop_visit_interpolated(nt: &mut token::Nonterminal, vis: token::NtIdent(ident, _is_raw) => vis.visit_ident(ident), token::NtLifetime(ident) => vis.visit_ident(ident), token::NtLiteral(expr) => vis.visit_expr(expr), - token::NtMeta(AttrItem { path, args }) => { + token::NtMeta(item) => { + let AttrItem { path, args } = item.deref_mut(); vis.visit_path(path); visit_mac_args(args, vis); } diff --git a/src/libsyntax/token.rs b/src/libsyntax/token.rs index c826b728f8004..3045f147698a5 100644 --- a/src/libsyntax/token.rs +++ b/src/libsyntax/token.rs @@ -673,7 +673,7 @@ pub enum Nonterminal { NtLifetime(ast::Ident), NtLiteral(P), /// Stuff inside brackets for attributes - NtMeta(ast::AttrItem), + NtMeta(P), NtPath(ast::Path), NtVis(ast::Visibility), NtTT(TokenTree), @@ -687,7 +687,7 @@ pub enum Nonterminal { // `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_arch = "x86_64")] -rustc_data_structures::static_assert_size!(Nonterminal, 72); +rustc_data_structures::static_assert_size!(Nonterminal, 40); impl PartialEq for Nonterminal { fn eq(&self, rhs: &Self) -> bool {