Shrink Nonterminal
.
By heap allocating the argument within `NtPath`, `NtVis`, and `NtStmt`. This slightly reduces cumulative and peak allocation amounts, most notably on `deep-vector`.
This commit is contained in:
parent
c2afaba465
commit
d9592c2d9f
@ -439,7 +439,7 @@ impl MetaItem {
|
|||||||
}
|
}
|
||||||
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt {
|
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt {
|
||||||
token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
|
token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
|
||||||
token::Nonterminal::NtPath(ref path) => path.clone(),
|
token::Nonterminal::NtPath(ref path) => (**path).clone(),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
},
|
},
|
||||||
_ => return None,
|
_ => return None,
|
||||||
|
@ -772,7 +772,9 @@ pub fn visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut
|
|||||||
token::NtBlock(block) => vis.visit_block(block),
|
token::NtBlock(block) => vis.visit_block(block),
|
||||||
token::NtStmt(stmt) => visit_clobber(stmt, |stmt| {
|
token::NtStmt(stmt) => visit_clobber(stmt, |stmt| {
|
||||||
// See reasoning above.
|
// See reasoning above.
|
||||||
vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item")
|
stmt.map(|stmt| {
|
||||||
|
vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item")
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
token::NtPat(pat) => vis.visit_pat(pat),
|
token::NtPat(pat) => vis.visit_pat(pat),
|
||||||
token::NtExpr(expr) => vis.visit_expr(expr),
|
token::NtExpr(expr) => vis.visit_expr(expr),
|
||||||
|
@ -668,7 +668,7 @@ impl PartialEq<TokenKind> for Token {
|
|||||||
pub enum Nonterminal {
|
pub enum Nonterminal {
|
||||||
NtItem(P<ast::Item>),
|
NtItem(P<ast::Item>),
|
||||||
NtBlock(P<ast::Block>),
|
NtBlock(P<ast::Block>),
|
||||||
NtStmt(ast::Stmt),
|
NtStmt(P<ast::Stmt>),
|
||||||
NtPat(P<ast::Pat>),
|
NtPat(P<ast::Pat>),
|
||||||
NtExpr(P<ast::Expr>),
|
NtExpr(P<ast::Expr>),
|
||||||
NtTy(P<ast::Ty>),
|
NtTy(P<ast::Ty>),
|
||||||
@ -677,13 +677,13 @@ pub enum Nonterminal {
|
|||||||
NtLiteral(P<ast::Expr>),
|
NtLiteral(P<ast::Expr>),
|
||||||
/// Stuff inside brackets for attributes
|
/// Stuff inside brackets for attributes
|
||||||
NtMeta(P<ast::AttrItem>),
|
NtMeta(P<ast::AttrItem>),
|
||||||
NtPath(ast::Path),
|
NtPath(P<ast::Path>),
|
||||||
NtVis(ast::Visibility),
|
NtVis(P<ast::Visibility>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger.
|
// `Nonterminal` 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!(Nonterminal, 48);
|
rustc_data_structures::static_assert_size!(Nonterminal, 16);
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
|
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
|
||||||
pub enum NonterminalKind {
|
pub enum NonterminalKind {
|
||||||
|
@ -118,7 +118,7 @@ impl Annotatable {
|
|||||||
Annotatable::ForeignItem(item) => {
|
Annotatable::ForeignItem(item) => {
|
||||||
token::NtItem(P(item.and_then(ast::ForeignItem::into_item)))
|
token::NtItem(P(item.and_then(ast::ForeignItem::into_item)))
|
||||||
}
|
}
|
||||||
Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()),
|
Annotatable::Stmt(stmt) => token::NtStmt(stmt),
|
||||||
Annotatable::Expr(expr) => token::NtExpr(expr),
|
Annotatable::Expr(expr) => token::NtExpr(expr),
|
||||||
Annotatable::Arm(..)
|
Annotatable::Arm(..)
|
||||||
| Annotatable::ExprField(..)
|
| Annotatable::ExprField(..)
|
||||||
|
@ -90,7 +90,7 @@ impl MultiItemModifier for ProcMacroDerive {
|
|||||||
// A proc macro can't observe the fact that we're passing
|
// A proc macro can't observe the fact that we're passing
|
||||||
// them an `NtStmt` - it can only see the underlying tokens
|
// them an `NtStmt` - it can only see the underlying tokens
|
||||||
// of the wrapped item
|
// of the wrapped item
|
||||||
token::NtStmt(stmt.into_inner())
|
token::NtStmt(stmt)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
@ -41,7 +41,7 @@ macro_rules! maybe_whole_expr {
|
|||||||
return Ok(e);
|
return Ok(e);
|
||||||
}
|
}
|
||||||
token::NtPath(path) => {
|
token::NtPath(path) => {
|
||||||
let path = path.clone();
|
let path = (**path).clone();
|
||||||
$p.bump();
|
$p.bump();
|
||||||
return Ok($p.mk_expr(
|
return Ok($p.mk_expr(
|
||||||
$p.prev_token.span,
|
$p.prev_token.span,
|
||||||
|
@ -1289,7 +1289,7 @@ impl<'a> Parser<'a> {
|
|||||||
/// so emit a proper diagnostic.
|
/// so emit a proper diagnostic.
|
||||||
// Public for rustfmt usage.
|
// Public for rustfmt usage.
|
||||||
pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> {
|
pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> {
|
||||||
maybe_whole!(self, NtVis, |x| x);
|
maybe_whole!(self, NtVis, |x| x.into_inner());
|
||||||
|
|
||||||
self.expected_tokens.push(TokenType::Keyword(kw::Crate));
|
self.expected_tokens.push(TokenType::Keyword(kw::Crate));
|
||||||
if self.is_crate_vis() {
|
if self.is_crate_vis() {
|
||||||
|
@ -118,7 +118,7 @@ impl<'a> Parser<'a> {
|
|||||||
token::NtBlock(self.collect_tokens_no_attrs(|this| this.parse_block())?)
|
token::NtBlock(self.collect_tokens_no_attrs(|this| this.parse_block())?)
|
||||||
}
|
}
|
||||||
NonterminalKind::Stmt => match self.parse_stmt(ForceCollect::Yes)? {
|
NonterminalKind::Stmt => match self.parse_stmt(ForceCollect::Yes)? {
|
||||||
Some(s) => token::NtStmt(s),
|
Some(s) => token::NtStmt(P(s)),
|
||||||
None => {
|
None => {
|
||||||
return Err(self.struct_span_err(self.token.span, "expected a statement"));
|
return Err(self.struct_span_err(self.token.span, "expected a statement"));
|
||||||
}
|
}
|
||||||
@ -161,11 +161,11 @@ impl<'a> Parser<'a> {
|
|||||||
return Err(self.struct_span_err(self.token.span, msg));
|
return Err(self.struct_span_err(self.token.span, msg));
|
||||||
}
|
}
|
||||||
NonterminalKind::Path => token::NtPath(
|
NonterminalKind::Path => token::NtPath(
|
||||||
self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?,
|
P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?),
|
||||||
),
|
),
|
||||||
NonterminalKind::Meta => token::NtMeta(P(self.parse_attr_item(true)?)),
|
NonterminalKind::Meta => token::NtMeta(P(self.parse_attr_item(true)?)),
|
||||||
NonterminalKind::Vis => token::NtVis(
|
NonterminalKind::Vis => token::NtVis(
|
||||||
self.collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?,
|
P(self.collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?),
|
||||||
),
|
),
|
||||||
NonterminalKind::Lifetime => {
|
NonterminalKind::Lifetime => {
|
||||||
if self.check_lifetime() {
|
if self.check_lifetime() {
|
||||||
|
@ -165,7 +165,7 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
maybe_whole!(self, NtPath, |path| {
|
maybe_whole!(self, NtPath, |path| {
|
||||||
reject_generics_if_mod_style(self, &path);
|
reject_generics_if_mod_style(self, &path);
|
||||||
path
|
path.into_inner()
|
||||||
});
|
});
|
||||||
|
|
||||||
if let token::Interpolated(nt) = &self.token.kind {
|
if let token::Interpolated(nt) = &self.token.kind {
|
||||||
|
@ -54,7 +54,7 @@ impl<'a> Parser<'a> {
|
|||||||
stmt.visit_attrs(|stmt_attrs| {
|
stmt.visit_attrs(|stmt_attrs| {
|
||||||
attrs.prepend_to_nt_inner(stmt_attrs);
|
attrs.prepend_to_nt_inner(stmt_attrs);
|
||||||
});
|
});
|
||||||
return Ok(Some(stmt));
|
return Ok(Some(stmt.into_inner()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(if self.token.is_keyword(kw::Let) {
|
Ok(Some(if self.token.is_keyword(kw::Let) {
|
||||||
@ -535,7 +535,7 @@ impl<'a> Parser<'a> {
|
|||||||
recover: AttemptLocalParseRecovery,
|
recover: AttemptLocalParseRecovery,
|
||||||
) -> PResult<'a, Option<Stmt>> {
|
) -> PResult<'a, Option<Stmt>> {
|
||||||
// Skip looking for a trailing semicolon when we have an interpolated statement.
|
// Skip looking for a trailing semicolon when we have an interpolated statement.
|
||||||
maybe_whole!(self, NtStmt, |x| Some(x));
|
maybe_whole!(self, NtStmt, |x| Some(x.into_inner()));
|
||||||
|
|
||||||
let Some(mut stmt) = self.parse_stmt_without_recovery(true, ForceCollect::No)? else {
|
let Some(mut stmt) = self.parse_stmt_without_recovery(true, ForceCollect::No)? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user