about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorsinkuu <sinkuu@sinkuu.xyz>2017-10-23 17:22:28 +0900
committersinkuu <sinkuu@sinkuu.xyz>2017-10-23 17:41:25 +0900
commitc0ccab4c2330659b67edb5889d7f9ee702aebbe3 (patch)
tree8afd6e8b7447152b6f449ea35d296f78eb5c883f /src
parent1042190f8c18b93a8987c30c5bf97d7b9259638b (diff)
downloadrust-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.rs14
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs15
-rw-r--r--src/libsyntax/visit.rs30
-rw-r--r--src/test/run-pass/issue-44851.rs24
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() {}