about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-10-26 04:32:16 +0000
committerbors <bors@rust-lang.org>2017-10-26 04:32:16 +0000
commit56dc171a2f2dc2373b1930f71140a354fa84b982 (patch)
tree661192bf832814b7238b5cf5bf3785a2cf7a3ed7
parentfa29bcedd1163f2b9db9fbc6c59e429374fbdfd3 (diff)
parent9f1a8bf318fb378cc928eee477515ab026004eb1 (diff)
Auto merge of #45464 - sinkuu:ice_44851, r=jseyfried
Visit attribute tokens in `DefCollector` and `BuildReducedGraphVisitor`

Fixes #44851.
-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.rs31
-rw-r--r--src/test/run-pass/issue-44851.rs24
4 files changed, 82 insertions, 2 deletions
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index fcbe79131eb..9d49776749b 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -17,6 +17,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};
 
@@ -286,4 +287,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 078a63cba20..4198055f670 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,17 @@ 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) {}
+    // FIXME: add `visit_interpolated` and `walk_interpolated`
     fn visit_vis(&mut self, vis: &'ast Visibility) {
         walk_vis(self, vis)
     }
@@ -810,3 +822,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() {}