Skip to content

Commit 634ecf0

Browse files
committed
Merge ModuleData and ModuleS.
1 parent b3a81ee commit 634ecf0

File tree

3 files changed

+80
-159
lines changed

3 files changed

+80
-159
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ use {NameBinding, NameBindingKind, ToNameBinding};
2020
use Resolver;
2121
use {resolve_error, resolve_struct_error, ResolutionError};
2222

23+
use rustc::middle::cstore::LoadedMacro;
2324
use rustc::hir::def::*;
2425
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
2526
use rustc::hir::map::DefPathData;
2627
use rustc::ty;
2728

2829
use std::cell::Cell;
30+
use std::rc::Rc;
2931

3032
use syntax::ast::Name;
3133
use syntax::attr;
@@ -34,6 +36,9 @@ use syntax::parse::token;
3436
use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind};
3537
use syntax::ast::{Mutability, StmtKind, TraitItem, TraitItemKind};
3638
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
39+
use syntax::ext::base::{MultiItemModifier, Resolver as SyntaxResolver};
40+
use syntax::ext::hygiene::Mark;
41+
use syntax::feature_gate::{self, emit_feature_err};
3742
use syntax::parse::token::keywords;
3843
use syntax::visit::{self, Visitor};
3944

@@ -73,8 +78,6 @@ impl<'b> Resolver<'b> {
7378

7479
/// Constructs the reduced graph for one item.
7580
fn build_reduced_graph_for_item(&mut self, item: &Item) {
76-
self.crate_loader.process_item(item, &self.definitions);
77-
7881
let parent = self.current_module;
7982
let name = item.ident.name;
8083
let sp = item.span;
@@ -182,8 +185,20 @@ impl<'b> Resolver<'b> {
182185
}
183186

184187
ItemKind::ExternCrate(_) => {
185-
// n.b. we don't need to look at the path option here, because cstore already
186-
// did
188+
// We need to error on `#[macro_use] extern crate` when it isn't at the
189+
// crate root, because `$crate` won't work properly.
190+
let is_crate_root = self.current_module.parent.is_none();
191+
for def in self.crate_loader.load_macros(item, is_crate_root) {
192+
match def {
193+
LoadedMacro::Def(def) => self.add_macro(Mark::root(), def),
194+
LoadedMacro::CustomDerive(name, ext) => {
195+
self.insert_custom_derive(&name, ext, item.span);
196+
}
197+
}
198+
}
199+
self.crate_loader.process_item(item, &self.definitions);
200+
201+
// n.b. we don't need to look at the path option here, because cstore already did
187202
if let Some(crate_id) = self.session.cstore.extern_mod_stmt_cnum(item.id) {
188203
let def_id = DefId {
189204
krate: crate_id,
@@ -209,6 +224,7 @@ impl<'b> Resolver<'b> {
209224
attr::contains_name(&item.attrs, "no_implicit_prelude")
210225
},
211226
normal_ancestor_id: Some(item.id),
227+
macros_escape: self.contains_macro_use(&item.attrs),
212228
..ModuleS::new(Some(parent), ModuleKind::Def(def, name))
213229
});
214230
self.define(parent, name, TypeNS, (module, sp, vis));
@@ -218,7 +234,7 @@ impl<'b> Resolver<'b> {
218234
self.current_module = module;
219235
}
220236

221-
ItemKind::ForeignMod(..) => {}
237+
ItemKind::ForeignMod(..) => self.crate_loader.process_item(item, &self.definitions),
222238

223239
// These items live in the value namespace.
224240
ItemKind::Static(_, m, _) => {
@@ -472,6 +488,41 @@ impl<'b> Resolver<'b> {
472488
}
473489
module.populated.set(true)
474490
}
491+
492+
// does this attribute list contain "macro_use"?
493+
fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool {
494+
for attr in attrs {
495+
if attr.check_name("macro_escape") {
496+
let msg = "macro_escape is a deprecated synonym for macro_use";
497+
let mut err = self.session.struct_span_warn(attr.span, msg);
498+
if let ast::AttrStyle::Inner = attr.node.style {
499+
err.help("consider an outer attribute, #[macro_use] mod ...").emit();
500+
} else {
501+
err.emit();
502+
}
503+
} else if !attr.check_name("macro_use") {
504+
continue;
505+
}
506+
507+
if !attr.is_word() {
508+
self.session.span_err(attr.span, "arguments to macro_use are not allowed here");
509+
}
510+
return true;
511+
}
512+
513+
false
514+
}
515+
516+
fn insert_custom_derive(&mut self, name: &str, ext: Rc<MultiItemModifier>, sp: Span) {
517+
if !self.session.features.borrow().rustc_macro {
518+
let sess = &self.session.parse_sess;
519+
let msg = "loading custom derive macro crates is experimentally supported";
520+
emit_feature_err(sess, "rustc_macro", sp, feature_gate::GateIssue::Language, msg);
521+
}
522+
if self.derive_modes.insert(token::intern(name), ext).is_some() {
523+
self.session.span_err(sp, &format!("cannot shadow existing derive mode `{}`", name));
524+
}
525+
}
475526
}
476527

477528
pub struct BuildReducedGraphVisitor<'a, 'b: 'a> {
@@ -480,7 +531,7 @@ pub struct BuildReducedGraphVisitor<'a, 'b: 'a> {
480531

481532
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
482533
fn visit_invoc(&mut self, id: ast::NodeId) {
483-
self.resolver.expansion_data.get_mut(&id.as_u32()).unwrap().module2 =
534+
self.resolver.expansion_data.get_mut(&id.as_u32()).unwrap().module =
484535
self.resolver.current_module;
485536
}
486537
}

src/librustc_resolve/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ use syntax::ext::base::MultiItemModifier;
5757
use syntax::ext::hygiene::Mark;
5858
use syntax::ast::{self, FloatTy};
5959
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, IntTy, UintTy};
60+
use syntax::ext::base::SyntaxExtension;
6061
use syntax::parse::token::{self, keywords};
6162
use syntax::util::lev_distance::find_best_match_for_name;
6263

@@ -72,9 +73,9 @@ use syntax_pos::{Span, DUMMY_SP};
7273
use errors::DiagnosticBuilder;
7374

7475
use std::cell::{Cell, RefCell};
75-
use std::rc::Rc;
7676
use std::fmt;
7777
use std::mem::replace;
78+
use std::rc::Rc;
7879

7980
use resolve_imports::{ImportDirective, NameResolution};
8081

@@ -786,6 +787,9 @@ pub struct ModuleS<'a> {
786787
// access the children must be preceded with a
787788
// `populate_module_if_necessary` call.
788789
populated: Cell<bool>,
790+
791+
macros: RefCell<FnvHashMap<Name, Rc<SyntaxExtension>>>,
792+
macros_escape: bool,
789793
}
790794

791795
pub type Module<'a> = &'a ModuleS<'a>;
@@ -803,6 +807,8 @@ impl<'a> ModuleS<'a> {
803807
globs: RefCell::new((Vec::new())),
804808
traits: RefCell::new(None),
805809
populated: Cell::new(true),
810+
macros: RefCell::new(FnvHashMap()),
811+
macros_escape: false,
806812
}
807813
}
808814

src/librustc_resolve/macros.rs

Lines changed: 16 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -12,63 +12,41 @@ use {Module, Resolver};
1212
use build_reduced_graph::BuildReducedGraphVisitor;
1313
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefIndex};
1414
use rustc::hir::map::DefCollector;
15-
use rustc::middle::cstore::LoadedMacro;
16-
use rustc::util::nodemap::FnvHashMap;
17-
use std::cell::RefCell;
18-
use std::mem;
1915
use std::rc::Rc;
20-
use syntax::ast::{self, Name};
16+
use syntax::ast;
2117
use syntax::errors::DiagnosticBuilder;
2218
use syntax::ext::base::{self, MultiModifier, MultiDecorator, MultiItemModifier};
23-
use syntax::ext::base::{NormalTT, Resolver as SyntaxResolver, SyntaxExtension};
19+
use syntax::ext::base::{NormalTT, SyntaxExtension};
2420
use syntax::ext::expand::{Expansion, Invocation, InvocationKind};
2521
use syntax::ext::hygiene::Mark;
2622
use syntax::ext::tt::macro_rules;
27-
use syntax::feature_gate::{self, emit_feature_err};
28-
use syntax::parse::token::{self, intern};
23+
use syntax::parse::token::intern;
2924
use syntax::util::lev_distance::find_best_match_for_name;
30-
use syntax::visit::{self, Visitor};
31-
use syntax_pos::Span;
3225

3326
#[derive(Clone)]
3427
pub struct ExpansionData<'a> {
35-
module: Rc<ModuleData>,
28+
pub module: Module<'a>,
3629
def_index: DefIndex,
37-
pub module2: Module<'a>,
3830
}
3931

4032
impl<'a> ExpansionData<'a> {
4133
pub fn root(graph_root: Module<'a>) -> Self {
4234
ExpansionData {
43-
module: Default::default(),
35+
module: graph_root,
4436
def_index: CRATE_DEF_INDEX,
45-
module2: graph_root,
4637
}
4738
}
4839
}
4940

50-
// FIXME(jseyfried): merge with `::ModuleS`.
51-
#[derive(Default)]
52-
struct ModuleData {
53-
parent: Option<Rc<ModuleData>>,
54-
macros: RefCell<FnvHashMap<Name, Rc<SyntaxExtension>>>,
55-
macros_escape: bool,
56-
}
57-
5841
impl<'a> base::Resolver for Resolver<'a> {
5942
fn next_node_id(&mut self) -> ast::NodeId {
6043
self.session.next_node_id()
6144
}
6245

6346
fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion) {
64-
let expansion_data = self.expansion_data[&mark.as_u32()].clone();
65-
self.current_module = expansion_data.module2;
66-
let mut visitor =
67-
ExpansionVisitor { current_module: expansion_data.module, resolver: self };
68-
69-
visitor.collect_def_ids(mark, expansion);
70-
expansion.visit_with(&mut visitor);
71-
expansion.visit_with(&mut BuildReducedGraphVisitor { resolver: visitor.resolver });
47+
self.collect_def_ids(mark, expansion);
48+
self.current_module = self.expansion_data[&mark.as_u32()].module;
49+
expansion.visit_with(&mut BuildReducedGraphVisitor { resolver: self });
7250
}
7351

7452
fn add_macro(&mut self, scope: Mark, mut def: ast::MacroDef) {
@@ -90,9 +68,9 @@ impl<'a> base::Resolver for Resolver<'a> {
9068
self.macro_names.insert(ident.name);
9169
}
9270

93-
let mut module = self.expansion_data[&scope.as_u32()].module.clone();
71+
let mut module = self.expansion_data[&scope.as_u32()].module;
9472
while module.macros_escape {
95-
module = module.parent.clone().unwrap();
73+
module = module.parent.unwrap();
9674
}
9775
module.macros.borrow_mut().insert(ident.name, ext);
9876
}
@@ -132,12 +110,12 @@ impl<'a> base::Resolver for Resolver<'a> {
132110
InvocationKind::Attr { ref attr, .. } => (intern(&*attr.name()), attr.span),
133111
};
134112

135-
let mut module = self.expansion_data[&scope.as_u32()].module.clone();
113+
let mut module = self.expansion_data[&scope.as_u32()].module;
136114
loop {
137115
if let Some(ext) = module.macros.borrow().get(&name) {
138116
return Some(ext.clone());
139117
}
140-
match module.parent.clone() {
118+
match module.parent {
141119
Some(parent) => module = parent,
142120
None => break,
143121
}
@@ -166,133 +144,19 @@ impl<'a> Resolver<'a> {
166144
}
167145
}
168146

169-
fn insert_custom_derive(&mut self, name: &str, ext: Rc<MultiItemModifier>, sp: Span) {
170-
if !self.session.features.borrow().rustc_macro {
171-
let sess = &self.session.parse_sess;
172-
let msg = "loading custom derive macro crates is experimentally supported";
173-
emit_feature_err(sess, "rustc_macro", sp, feature_gate::GateIssue::Language, msg);
174-
}
175-
if self.derive_modes.insert(token::intern(name), ext).is_some() {
176-
self.session.span_err(sp, &format!("cannot shadow existing derive mode `{}`", name));
177-
}
178-
}
179-
}
180-
181-
struct ExpansionVisitor<'b, 'a: 'b> {
182-
resolver: &'b mut Resolver<'a>,
183-
current_module: Rc<ModuleData>,
184-
}
185-
186-
impl<'a, 'b> ExpansionVisitor<'a, 'b> {
187-
fn visit_invoc(&mut self, id: ast::NodeId) {
188-
self.resolver.expansion_data.get_mut(&id.as_u32()).unwrap().module =
189-
self.current_module.clone();
190-
}
191-
192-
// does this attribute list contain "macro_use"?
193-
fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool {
194-
for attr in attrs {
195-
if attr.check_name("macro_escape") {
196-
let msg = "macro_escape is a deprecated synonym for macro_use";
197-
let mut err = self.resolver.session.struct_span_warn(attr.span, msg);
198-
if let ast::AttrStyle::Inner = attr.node.style {
199-
err.help("consider an outer attribute, #[macro_use] mod ...").emit();
200-
} else {
201-
err.emit();
202-
}
203-
} else if !attr.check_name("macro_use") {
204-
continue;
205-
}
206-
207-
if !attr.is_word() {
208-
self.resolver.session.span_err(attr.span,
209-
"arguments to macro_use are not allowed here");
210-
}
211-
return true;
212-
}
213-
214-
false
215-
}
216-
217147
fn collect_def_ids(&mut self, mark: Mark, expansion: &Expansion) {
218-
let expansion_data = &mut self.resolver.expansion_data;
219-
let module = &self.current_module;
220-
let module2 = self.resolver.current_module;
148+
let expansion_data = &mut self.expansion_data;
149+
let module = self.current_module;
221150
let def_index = expansion_data[&mark.as_u32()].def_index;
222151
let visit_macro_invoc = &mut |id: ast::NodeId, def_index| {
223152
expansion_data.insert(id.as_u32(), ExpansionData {
224153
def_index: def_index,
225-
module: module.clone(),
226-
module2: module2,
154+
module: module,
227155
});
228156
};
229157

230-
let mut def_collector = DefCollector::new(&mut self.resolver.definitions);
158+
let mut def_collector = DefCollector::new(&mut self.definitions);
231159
def_collector.visit_macro_invoc = Some(visit_macro_invoc);
232160
def_collector.with_parent(def_index, |def_collector| expansion.visit_with(def_collector));
233161
}
234162
}
235-
236-
macro_rules! method {
237-
($visit:ident: $ty:ty, $invoc:path, $walk:ident) => {
238-
fn $visit(&mut self, node: &$ty) {
239-
match node.node {
240-
$invoc(..) => self.visit_invoc(node.id),
241-
_ => visit::$walk(self, node),
242-
}
243-
}
244-
}
245-
}
246-
247-
impl<'a, 'b> Visitor for ExpansionVisitor<'a, 'b> {
248-
method!(visit_trait_item: ast::TraitItem, ast::TraitItemKind::Macro, walk_trait_item);
249-
method!(visit_impl_item: ast::ImplItem, ast::ImplItemKind::Macro, walk_impl_item);
250-
method!(visit_stmt: ast::Stmt, ast::StmtKind::Mac, walk_stmt);
251-
method!(visit_expr: ast::Expr, ast::ExprKind::Mac, walk_expr);
252-
method!(visit_pat: ast::Pat, ast::PatKind::Mac, walk_pat);
253-
method!(visit_ty: ast::Ty, ast::TyKind::Mac, walk_ty);
254-
255-
fn visit_item(&mut self, item: &ast::Item) {
256-
match item.node {
257-
ast::ItemKind::Mac(..) if item.id == ast::DUMMY_NODE_ID => {} // Scope placeholder
258-
ast::ItemKind::Mac(..) => self.visit_invoc(item.id),
259-
ast::ItemKind::Mod(..) => {
260-
let module_data = ModuleData {
261-
parent: Some(self.current_module.clone()),
262-
macros: RefCell::new(FnvHashMap()),
263-
macros_escape: self.contains_macro_use(&item.attrs),
264-
};
265-
let orig_module = mem::replace(&mut self.current_module, Rc::new(module_data));
266-
visit::walk_item(self, item);
267-
self.current_module = orig_module;
268-
}
269-
ast::ItemKind::ExternCrate(..) => {
270-
// We need to error on `#[macro_use] extern crate` when it isn't at the
271-
// crate root, because `$crate` won't work properly.
272-
// FIXME(jseyfried): This will be nicer once `ModuleData` is merged with `ModuleS`.
273-
let is_crate_root = self.current_module.parent.as_ref().unwrap().parent.is_none();
274-
for def in self.resolver.crate_loader.load_macros(item, is_crate_root) {
275-
match def {
276-
LoadedMacro::Def(def) => self.resolver.add_macro(Mark::root(), def),
277-
LoadedMacro::CustomDerive(name, ext) => {
278-
self.resolver.insert_custom_derive(&name, ext, item.span);
279-
}
280-
}
281-
}
282-
visit::walk_item(self, item);
283-
}
284-
_ => visit::walk_item(self, item),
285-
}
286-
}
287-
288-
fn visit_block(&mut self, block: &ast::Block) {
289-
let module_data = ModuleData {
290-
parent: Some(self.current_module.clone()),
291-
macros: RefCell::new(FnvHashMap()),
292-
macros_escape: false,
293-
};
294-
let orig_module = mem::replace(&mut self.current_module, Rc::new(module_data));
295-
visit::walk_block(self, block);
296-
self.current_module = orig_module;
297-
}
298-
}

0 commit comments

Comments
 (0)