Skip to content

Commit 1119567

Browse files
committed
Elimite $crate before invokng custom derives.
1 parent b46ce08 commit 1119567

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

src/librustc_resolve/macros.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use {Module, Resolver};
11+
use {Module, ModuleKind, Resolver};
1212
use build_reduced_graph::BuildReducedGraphVisitor;
1313
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefIndex};
1414
use rustc::hir::map::{self, DefCollector};
@@ -21,7 +21,9 @@ use syntax::ext::base::{NormalTT, SyntaxExtension};
2121
use syntax::ext::expand::Expansion;
2222
use syntax::ext::hygiene::Mark;
2323
use syntax::ext::tt::macro_rules;
24+
use syntax::fold::Folder;
2425
use syntax::parse::token::intern;
26+
use syntax::ptr::P;
2527
use syntax::util::lev_distance::find_best_match_for_name;
2628
use syntax_pos::Span;
2729

@@ -97,6 +99,31 @@ impl<'a> base::Resolver for Resolver<'a> {
9799
mark
98100
}
99101

102+
fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item> {
103+
struct EliminateCrateVar<'b, 'a: 'b>(&'b mut Resolver<'a>);
104+
105+
impl<'a, 'b> Folder for EliminateCrateVar<'a, 'b> {
106+
fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
107+
let ident = path.segments[0].identifier;
108+
if &ident.name.as_str() == "$crate" {
109+
path.global = true;
110+
let module = self.0.resolve_crate_var(ident.ctxt);
111+
if module.is_local() {
112+
path.segments.remove(0);
113+
} else {
114+
path.segments[0].identifier = match module.kind {
115+
ModuleKind::Def(_, name) => ast::Ident::with_empty_ctxt(name),
116+
_ => unreachable!(),
117+
};
118+
}
119+
}
120+
path
121+
}
122+
}
123+
124+
EliminateCrateVar(self).fold_item(item).expect_one("")
125+
}
126+
100127
fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion) {
101128
let invocation = self.invocations[&mark];
102129
self.collect_def_ids(invocation, expansion);

src/libsyntax/ext/base.rs

+2
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ pub type NamedSyntaxExtension = (Name, SyntaxExtension);
517517
pub trait Resolver {
518518
fn next_node_id(&mut self) -> ast::NodeId;
519519
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark;
520+
fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item>;
520521

521522
fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion);
522523
fn add_macro(&mut self, scope: Mark, def: ast::MacroDef, export: bool);
@@ -539,6 +540,7 @@ pub struct DummyResolver;
539540
impl Resolver for DummyResolver {
540541
fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID }
541542
fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() }
543+
fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item> { item }
542544

543545
fn visit_expansion(&mut self, _invoc: Mark, _expansion: &Expansion) {}
544546
fn add_macro(&mut self, _scope: Mark, _def: ast::MacroDef, _export: bool) {}

src/libsyntax_ext/deriving/custom.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ impl MultiItemModifier for CustomDerive {
7373
// Mark attributes as known, and used.
7474
MarkAttrs(&self.attrs).visit_item(&item);
7575

76-
let input = __internal::new_token_stream(item.clone());
76+
let input = __internal::new_token_stream(ecx.resolver.eliminate_crate_var(item.clone()));
7777
let res = __internal::set_parse_sess(&ecx.parse_sess, || {
7878
let inner = self.inner;
7979
panic::catch_unwind(panic::AssertUnwindSafe(|| inner(input)))

0 commit comments

Comments
 (0)