summary refs log tree commit diff
path: root/src/librustc_resolve
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2017-11-29 01:05:31 -0800
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2017-12-13 13:33:03 -0800
commitd052d28d70b31fac942765da137f794835e6536e (patch)
treeb339c73c8f824f39bab9aa06dc785964f46e917d /src/librustc_resolve
parent3dfbc88a626625be01e112da11ec367e2fc71bb3 (diff)
downloadrust-d052d28d70b31fac942765da137f794835e6536e.tar.gz
rust-d052d28d70b31fac942765da137f794835e6536e.zip
Improve interaction between macros 2.0 and `macro_rules!`.
Diffstat (limited to 'src/librustc_resolve')
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs2
-rw-r--r--src/librustc_resolve/lib.rs19
-rw-r--r--src/librustc_resolve/macros.rs2
-rw-r--r--src/librustc_resolve/resolve_imports.rs2
4 files changed, 17 insertions, 8 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 8df6458b72e..21b5bb6a971 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -156,7 +156,7 @@ impl<'a> Resolver<'a> {
 
                     // Disallow `use $crate;`
                     if source.name == keywords::DollarCrate.name() && path.segments.len() == 1 {
-                        let crate_root = self.resolve_crate_root(source.ctxt);
+                        let crate_root = self.resolve_crate_root(source.ctxt, true);
                         let crate_name = match crate_root.kind {
                             ModuleKind::Def(_, name) => name,
                             ModuleKind::Block(..) => unreachable!(),
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 33e57b2d180..2a97df92092 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -42,7 +42,7 @@ use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
 use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
 
 use syntax::codemap::{dummy_spanned, respan};
-use syntax::ext::hygiene::{Mark, SyntaxContext};
+use syntax::ext::hygiene::{Mark, MarkKind, SyntaxContext};
 use syntax::ast::{self, Name, NodeId, Ident, SpannedIdent, FloatTy, IntTy, UintTy};
 use syntax::ext::base::SyntaxExtension;
 use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
@@ -1775,8 +1775,17 @@ impl<'a> Resolver<'a> {
         result
     }
 
-    fn resolve_crate_root(&mut self, mut ctxt: SyntaxContext) -> Module<'a> {
-        let module = match ctxt.adjust(Mark::root()) {
+    fn resolve_crate_root(&mut self, mut ctxt: SyntaxContext, legacy: bool) -> Module<'a> {
+        let mark = if legacy {
+            // When resolving `$crate` from a `macro_rules!` invoked in a `macro`,
+            // we don't want to pretend that the `macro_rules!` definition is in the `macro`
+            // as described in `SyntaxContext::apply_mark`, so we ignore prepended modern marks.
+            ctxt.marks().into_iter().find(|&mark| mark.kind() != MarkKind::Modern)
+        } else {
+            ctxt = ctxt.modern();
+            ctxt.adjust(Mark::root())
+        };
+        let module = match mark {
             Some(def) => self.macro_def_scope(def),
             None => return self.graph_root,
         };
@@ -2961,11 +2970,11 @@ impl<'a> Resolver<'a> {
                    (i == 1 && name == keywords::Crate.name() &&
                               path[0].node.name == keywords::CrateRoot.name()) {
                     // `::a::b` or `::crate::a::b`
-                    module = Some(self.resolve_crate_root(ident.node.ctxt.modern()));
+                    module = Some(self.resolve_crate_root(ident.node.ctxt, false));
                     continue
                 } else if i == 0 && name == keywords::DollarCrate.name() {
                     // `$crate::a::b`
-                    module = Some(self.resolve_crate_root(ident.node.ctxt));
+                    module = Some(self.resolve_crate_root(ident.node.ctxt, true));
                     continue
                 } else if i == 1 && self.session.features.borrow().extern_absolute_paths &&
                                     path[0].node.name == keywords::CrateRoot.name() &&
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 260a0cd7cd7..fe6bbf45d9f 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -140,7 +140,7 @@ impl<'a> base::Resolver for Resolver<'a> {
                 let ident = path.segments[0].identifier;
                 if ident.name == keywords::DollarCrate.name() {
                     path.segments[0].identifier.name = keywords::CrateRoot.name();
-                    let module = self.0.resolve_crate_root(ident.ctxt);
+                    let module = self.0.resolve_crate_root(ident.ctxt, true);
                     if !module.is_local() {
                         let span = path.segments[0].span;
                         path.segments.insert(1, match module.kind {
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index e249ecfca58..4fd80170785 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -620,7 +620,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
                                          "crate root imports need to be explicitly named: \
                                           `use crate as name;`".to_string()));
                         } else {
-                            Some(self.resolve_crate_root(source.ctxt.modern()))
+                            Some(self.resolve_crate_root(source.ctxt.modern(), false))
                         }
                     } else if extern_absolute_paths &&
                               !token::Ident(source).is_path_segment_keyword() {