about summary refs log tree commit diff
path: root/src/librustc_resolve
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-11-08 03:16:54 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-11-10 10:23:35 +0000
commit11195676a03cf08b13c41684de328869ac345ff8 (patch)
tree3ce9b0569f6a0fa57b46d6bfb3025721f35cfdde /src/librustc_resolve
parentb46ce08df51f95e5d9f6dff9156b1d8e38cf4795 (diff)
downloadrust-11195676a03cf08b13c41684de328869ac345ff8.tar.gz
rust-11195676a03cf08b13c41684de328869ac345ff8.zip
Elimite `$crate` before invokng custom derives.
Diffstat (limited to 'src/librustc_resolve')
-rw-r--r--src/librustc_resolve/macros.rs29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index e3078a42f65..f51ea3545e4 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use {Module, Resolver};
+use {Module, ModuleKind, Resolver};
 use build_reduced_graph::BuildReducedGraphVisitor;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, DefIndex};
 use rustc::hir::map::{self, DefCollector};
@@ -21,7 +21,9 @@ use syntax::ext::base::{NormalTT, SyntaxExtension};
 use syntax::ext::expand::Expansion;
 use syntax::ext::hygiene::Mark;
 use syntax::ext::tt::macro_rules;
+use syntax::fold::Folder;
 use syntax::parse::token::intern;
+use syntax::ptr::P;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax_pos::Span;
 
@@ -97,6 +99,31 @@ impl<'a> base::Resolver for Resolver<'a> {
         mark
     }
 
+    fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item> {
+        struct EliminateCrateVar<'b, 'a: 'b>(&'b mut Resolver<'a>);
+
+        impl<'a, 'b> Folder for EliminateCrateVar<'a, 'b> {
+            fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
+                let ident = path.segments[0].identifier;
+                if &ident.name.as_str() == "$crate" {
+                    path.global = true;
+                    let module = self.0.resolve_crate_var(ident.ctxt);
+                    if module.is_local() {
+                        path.segments.remove(0);
+                    } else {
+                        path.segments[0].identifier = match module.kind {
+                            ModuleKind::Def(_, name) => ast::Ident::with_empty_ctxt(name),
+                            _ => unreachable!(),
+                        };
+                    }
+                }
+                path
+            }
+        }
+
+        EliminateCrateVar(self).fold_item(item).expect_one("")
+    }
+
     fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion) {
         let invocation = self.invocations[&mark];
         self.collect_def_ids(invocation, expansion);