diff options
| author | sinkuu <sinkuu@sinkuu.xyz> | 2017-10-23 17:22:28 +0900 |
|---|---|---|
| committer | sinkuu <sinkuu@sinkuu.xyz> | 2017-10-23 17:41:25 +0900 |
| commit | c0ccab4c2330659b67edb5889d7f9ee702aebbe3 (patch) | |
| tree | 8afd6e8b7447152b6f449ea35d296f78eb5c883f /src | |
| parent | 1042190f8c18b93a8987c30c5bf97d7b9259638b (diff) | |
| download | rust-c0ccab4c2330659b67edb5889d7f9ee702aebbe3.tar.gz rust-c0ccab4c2330659b67edb5889d7f9ee702aebbe3.zip | |
Fix #44851 by visiting tokens in `DefCollector` and `BuildReducedGraphVisitor`
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/hir/map/def_collector.rs | 14 | ||||
| -rw-r--r-- | src/librustc_resolve/build_reduced_graph.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 30 | ||||
| -rw-r--r-- | src/test/run-pass/issue-44851.rs | 24 |
4 files changed, 81 insertions, 2 deletions
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 673e6d3bbfb..567f0ee3b0d 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -16,6 +16,7 @@ use syntax::ext::hygiene::Mark; use syntax::visit; use syntax::symbol::keywords; use syntax::symbol::Symbol; +use syntax::parse::token::{self, Token}; use hir::map::{ITEM_LIKE_SPACE, REGULAR_SPACE}; @@ -283,4 +284,17 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { _ => visit::walk_stmt(self, stmt), } } + + fn visit_token(&mut self, t: Token) { + if let Token::Interpolated(nt) = t { + match nt.0 { + token::NtExpr(ref expr) => { + if let ExprKind::Mac(..) = expr.node { + self.visit_macro_invoc(expr.id, false); + } + } + _ => {} + } + } + } } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index a4d1ae16215..7b1a602d849 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -40,7 +40,7 @@ use syntax::ext::base::SyntaxExtension; use syntax::ext::base::Determinacy::Undetermined; use syntax::ext::hygiene::Mark; use syntax::ext::tt::macro_rules; -use syntax::parse::token; +use syntax::parse::token::{self, Token}; use syntax::symbol::keywords; use syntax::symbol::Symbol; use syntax::visit::{self, Visitor}; @@ -830,4 +830,17 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> { visit::walk_trait_item(self, item); self.resolver.current_module = parent; } + + fn visit_token(&mut self, t: Token) { + if let Token::Interpolated(nt) = t { + match nt.0 { + token::NtExpr(ref expr) => { + if let ast::ExprKind::Mac(..) = expr.node { + self.visit_invoc(expr.id); + } + } + _ => {} + } + } + } } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 521c6030eba..7893145a4a7 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -27,6 +27,8 @@ use abi::Abi; use ast::*; use syntax_pos::Span; use codemap::Spanned; +use parse::token::Token; +use tokenstream::{TokenTree, TokenStream}; #[derive(Copy, Clone, PartialEq, Eq)] pub enum FnKind<'a> { @@ -130,7 +132,16 @@ pub trait Visitor<'ast>: Sized { fn visit_assoc_type_binding(&mut self, type_binding: &'ast TypeBinding) { walk_assoc_type_binding(self, type_binding) } - fn visit_attribute(&mut self, _attr: &'ast Attribute) {} + fn visit_attribute(&mut self, attr: &'ast Attribute) { + walk_attribute(self, attr) + } + fn visit_tt(&mut self, tt: TokenTree) { + walk_tt(self, tt) + } + fn visit_tts(&mut self, tts: TokenStream) { + walk_tts(self, tts) + } + fn visit_token(&mut self, _t: Token) {} fn visit_vis(&mut self, vis: &'ast Visibility) { walk_vis(self, vis) } @@ -810,3 +821,20 @@ pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) { visitor.visit_path(path, id); } } + +pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) { + visitor.visit_tts(attr.tokens.clone()); +} + +pub fn walk_tt<'a, V: Visitor<'a>>(visitor: &mut V, tt: TokenTree) { + match tt { + TokenTree::Token(_, tok) => visitor.visit_token(tok), + TokenTree::Delimited(_, delimed) => visitor.visit_tts(delimed.stream()), + } +} + +pub fn walk_tts<'a, V: Visitor<'a>>(visitor: &mut V, tts: TokenStream) { + for tt in tts.trees() { + visitor.visit_tt(tt); + } +} diff --git a/src/test/run-pass/issue-44851.rs b/src/test/run-pass/issue-44851.rs new file mode 100644 index 00000000000..62d675b13be --- /dev/null +++ b/src/test/run-pass/issue-44851.rs @@ -0,0 +1,24 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +macro_rules! a { + () => { "a" } +} + +macro_rules! b { + ($doc:expr) => { + #[doc = $doc] + pub struct B; + } +} + +b!(a!()); + +fn main() {} |
