From de4bd9f0f8aeb4b89e55ba33b755c9a93e999e1c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 21 Aug 2020 17:52:52 -0400 Subject: [PATCH] Attach `TokenStream` to `ast::Block` A `Block` does not have outer attributes, so we only capture tokens when parsing a `macro_rules!` matcher --- compiler/rustc_ast/src/ast.rs | 1 + compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_builtin_macros/src/deriving/mod.rs | 1 + compiler/rustc_expand/src/build.rs | 8 +++++++- compiler/rustc_interface/src/util.rs | 1 + compiler/rustc_parse/src/lib.rs | 1 + compiler/rustc_parse/src/parser/nonterminal.rs | 9 ++++++++- compiler/rustc_parse/src/parser/stmt.rs | 2 +- 8 files changed, 21 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index b9f380dc4e8..8fbf5ccf5ac 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -540,6 +540,7 @@ pub struct Block { /// Distinguishes between `unsafe { ... }` and `{ ... }`. pub rules: BlockCheckMode, pub span: Span, + pub tokens: Option, } /// A match pattern. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 3119c5e0a12..3e86528fcef 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -871,7 +871,7 @@ pub fn noop_visit_mt(MutTy { ty, mutbl: _ }: &mut MutTy, vis: &mu } pub fn noop_visit_block(block: &mut P, vis: &mut T) { - let Block { id, stmts, rules: _, span } = block.deref_mut(); + let Block { id, stmts, rules: _, span, tokens: _ } = block.deref_mut(); vis.visit_id(id); stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); vis.visit_span(span); diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 7e3fd131d44..9c8e0fc2f01 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -75,6 +75,7 @@ fn call_intrinsic( id: ast::DUMMY_NODE_ID, rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated), span, + tokens: None, })) } diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 9490b62aa17..717c4e9406c 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -207,7 +207,13 @@ impl<'a> ExtCtxt<'a> { ) } pub fn block(&self, span: Span, stmts: Vec) -> P { - P(ast::Block { stmts, id: ast::DUMMY_NODE_ID, rules: BlockCheckMode::Default, span }) + P(ast::Block { + stmts, + id: ast::DUMMY_NODE_ID, + rules: BlockCheckMode::Default, + span, + tokens: None, + }) } pub fn expr(&self, span: Span, kind: ast::ExprKind) -> P { diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index b1b39fd1ad2..01441cafe8a 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -693,6 +693,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { rules, id: resolver.next_node_id(), span: rustc_span::DUMMY_SP, + tokens: None, } } diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 12afc48356c..65ded67dcf6 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -268,6 +268,7 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke Nonterminal::NtItem(ref item) => { prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span) } + Nonterminal::NtBlock(ref block) => block.tokens.clone(), Nonterminal::NtPat(ref pat) => pat.tokens.clone(), Nonterminal::NtIdent(ident, is_raw) => { Some(tokenstream::TokenTree::token(token::Ident(ident.name, is_raw), ident.span).into()) diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index f40cd1131d2..47ed98b8599 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -111,7 +111,14 @@ impl<'a> Parser<'a> { return Err(self.struct_span_err(self.token.span, "expected an item keyword")); } }, - NonterminalKind::Block => token::NtBlock(self.parse_block()?), + NonterminalKind::Block => { + let (mut block, tokens) = self.collect_tokens(|this| this.parse_block())?; + // We have have eaten an NtBlock, which could already have tokens + if block.tokens.is_none() { + block.tokens = Some(tokens); + } + token::NtBlock(block) + } NonterminalKind::Stmt => match self.parse_stmt()? { Some(s) => token::NtStmt(s), None => return Err(self.struct_span_err(self.token.span, "expected a statement")), diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 947ca6b5bd5..6cc42487684 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -411,7 +411,7 @@ impl<'a> Parser<'a> { } pub(super) fn mk_block(&self, stmts: Vec, rules: BlockCheckMode, span: Span) -> P { - P(Block { stmts, id: DUMMY_NODE_ID, rules, span }) + P(Block { stmts, id: DUMMY_NODE_ID, rules, span, tokens: None }) } pub(super) fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt {