]> git.lizzy.rs Git - rust.git/blob - src/librustc_resolve/build_reduced_graph.rs
Auto merge of #45013 - chrisvittal:mir_pretty_printing_pr, r=nikomatsakis
[rust.git] / src / librustc_resolve / build_reduced_graph.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Reduced graph building
12 //!
13 //! Here we build the "reduced graph": the graph of the module tree without
14 //! any imports resolved.
15
16 use macros::{InvocationData, LegacyScope};
17 use resolve_imports::ImportDirective;
18 use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
19 use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, ToNameBinding};
20 use {Resolver, ResolverArenas};
21 use Namespace::{self, TypeNS, ValueNS, MacroNS};
22 use {resolve_error, resolve_struct_error, ResolutionError};
23
24 use rustc::middle::cstore::LoadedMacro;
25 use rustc::hir::def::*;
26 use rustc::hir::def_id::{BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
27 use rustc::ty;
28
29 use std::cell::Cell;
30 use std::rc::Rc;
31
32 use syntax::ast::{Name, Ident};
33 use syntax::attr;
34
35 use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind};
36 use syntax::ast::{Mutability, StmtKind, TraitItem, TraitItemKind};
37 use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
38 use syntax::codemap::respan;
39 use syntax::ext::base::SyntaxExtension;
40 use syntax::ext::base::Determinacy::Undetermined;
41 use syntax::ext::hygiene::Mark;
42 use syntax::ext::tt::macro_rules;
43 use syntax::parse::token;
44 use syntax::symbol::keywords;
45 use syntax::symbol::Symbol;
46 use syntax::visit::{self, Visitor};
47
48 use syntax_pos::{Span, DUMMY_SP};
49
50 impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) {
51     fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
52         arenas.alloc_name_binding(NameBinding {
53             kind: NameBindingKind::Module(self.0),
54             vis: self.1,
55             span: self.2,
56             expansion: self.3,
57         })
58     }
59 }
60
61 impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark) {
62     fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
63         arenas.alloc_name_binding(NameBinding {
64             kind: NameBindingKind::Def(self.0),
65             vis: self.1,
66             span: self.2,
67             expansion: self.3,
68         })
69     }
70 }
71
72 #[derive(Default, PartialEq, Eq)]
73 struct LegacyMacroImports {
74     import_all: Option<Span>,
75     imports: Vec<(Name, Span)>,
76     reexports: Vec<(Name, Span)>,
77 }
78
79 impl<'a> Resolver<'a> {
80     /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
81     /// otherwise, reports an error.
82     pub fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
83         where T: ToNameBinding<'a>,
84     {
85         let binding = def.to_name_binding(self.arenas);
86         if let Err(old_binding) = self.try_define(parent, ident, ns, binding) {
87             self.report_conflict(parent, ident, ns, old_binding, &binding);
88         }
89     }
90
91     fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
92         // If any statements are items, we need to create an anonymous module
93         block.stmts.iter().any(|statement| match statement.node {
94             StmtKind::Item(_) | StmtKind::Mac(_) => true,
95             _ => false,
96         })
97     }
98
99     fn insert_field_names(&mut self, def_id: DefId, field_names: Vec<Name>) {
100         if !field_names.is_empty() {
101             self.field_names.insert(def_id, field_names);
102         }
103     }
104
105     /// Constructs the reduced graph for one item.
106     fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
107         let parent = self.current_module;
108         let ident = item.ident;
109         let sp = item.span;
110         let vis = self.resolve_visibility(&item.vis);
111
112         match item.node {
113             ItemKind::Use(ref view_path) => {
114                 // Extract and intern the module part of the path. For
115                 // globs and lists, the path is found directly in the AST;
116                 // for simple paths we have to munge the path a little.
117                 let mut module_path: Vec<_> = match view_path.node {
118                     ViewPathSimple(_, ref full_path) => {
119                         full_path.segments
120                                  .split_last()
121                                  .unwrap()
122                                  .1
123                                  .iter()
124                                  .map(|seg| respan(seg.span, seg.identifier))
125                                  .collect()
126                     }
127
128                     ViewPathGlob(ref module_ident_path) |
129                     ViewPathList(ref module_ident_path, _) => {
130                         module_ident_path.segments
131                                          .iter()
132                                          .map(|seg| respan(seg.span, seg.identifier))
133                                          .collect()
134                     }
135                 };
136
137                 // This can be removed once warning cycle #36888 is complete.
138                 if module_path.len() >= 2 &&
139                     module_path[0].node.name == keywords::CrateRoot.name() &&
140                     token::Ident(module_path[1].node).is_path_segment_keyword()
141                 {
142                     module_path.remove(0);
143                 }
144
145                 // Build up the import directives.
146                 let is_prelude = attr::contains_name(&item.attrs, "prelude_import");
147
148                 match view_path.node {
149                     ViewPathSimple(mut binding, ref full_path) => {
150                         let mut source = full_path.segments.last().unwrap().identifier;
151                         let source_name = source.name;
152                         if source_name == "mod" || source_name == "self" {
153                             resolve_error(self,
154                                           view_path.span,
155                                           ResolutionError::SelfImportsOnlyAllowedWithin);
156                         } else if source_name == keywords::DollarCrate.name() &&
157                                   full_path.segments.len() == 1 {
158                             let crate_root = self.resolve_crate_root(source.ctxt);
159                             let crate_name = match crate_root.kind {
160                                 ModuleKind::Def(_, name) => name,
161                                 ModuleKind::Block(..) => unreachable!(),
162                             };
163                             source.name = crate_name;
164                             if binding.name == keywords::DollarCrate.name() {
165                                 binding.name = crate_name;
166                             }
167
168                             self.session.struct_span_warn(item.span, "`$crate` may not be imported")
169                                 .note("`use $crate;` was erroneously allowed and \
170                                        will become a hard error in a future release")
171                                 .emit();
172                         }
173
174                         let subclass = SingleImport {
175                             target: binding,
176                             source,
177                             result: self.per_ns(|_, _| Cell::new(Err(Undetermined))),
178                             type_ns_only: false,
179                         };
180                         self.add_import_directive(
181                             module_path, subclass, view_path.span, item.id, vis, expansion,
182                         );
183                     }
184                     ViewPathList(_, ref source_items) => {
185                         // Make sure there's at most one `mod` import in the list.
186                         let mod_spans = source_items.iter().filter_map(|item| {
187                             if item.node.name.name == keywords::SelfValue.name() {
188                                 Some(item.span)
189                             } else {
190                                 None
191                             }
192                         }).collect::<Vec<Span>>();
193
194                         if mod_spans.len() > 1 {
195                             let mut e = resolve_struct_error(self,
196                                           mod_spans[0],
197                                           ResolutionError::SelfImportCanOnlyAppearOnceInTheList);
198                             for other_span in mod_spans.iter().skip(1) {
199                                 e.span_note(*other_span, "another `self` import appears here");
200                             }
201                             e.emit();
202                         }
203
204                         for source_item in source_items {
205                             let node = source_item.node;
206                             let (module_path, ident, rename, type_ns_only) = {
207                                 if node.name.name != keywords::SelfValue.name() {
208                                     let rename = node.rename.unwrap_or(node.name);
209                                     (module_path.clone(),
210                                      respan(source_item.span, node.name),
211                                      rename,
212                                      false)
213                                 } else {
214                                     let ident = *module_path.last().unwrap();
215                                     if ident.node.name == keywords::CrateRoot.name() {
216                                         resolve_error(
217                                             self,
218                                             source_item.span,
219                                             ResolutionError::
220                                             SelfImportOnlyInImportListWithNonEmptyPrefix
221                                         );
222                                         continue;
223                                     }
224                                     let module_path = module_path.split_last().unwrap().1;
225                                     let rename = node.rename.unwrap_or(ident.node);
226                                     (module_path.to_vec(), ident, rename, true)
227                                 }
228                             };
229                             let subclass = SingleImport {
230                                 target: rename,
231                                 source: ident.node,
232                                 result: self.per_ns(|_, _| Cell::new(Err(Undetermined))),
233                                 type_ns_only,
234                             };
235                             let id = source_item.node.id;
236                             self.add_import_directive(
237                                 module_path, subclass, source_item.span, id, vis, expansion,
238                             );
239                         }
240                     }
241                     ViewPathGlob(_) => {
242                         let subclass = GlobImport {
243                             is_prelude,
244                             max_vis: Cell::new(ty::Visibility::Invisible),
245                         };
246                         self.add_import_directive(
247                             module_path, subclass, view_path.span, item.id, vis, expansion,
248                         );
249                     }
250                 }
251             }
252
253             ItemKind::ExternCrate(_) => {
254                 self.crate_loader.process_item(item, &self.definitions);
255
256                 // n.b. we don't need to look at the path option here, because cstore already did
257                 let crate_id = self.cstore.extern_mod_stmt_cnum_untracked(item.id).unwrap();
258                 let module =
259                     self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
260                 self.populate_module_if_necessary(module);
261                 let used = self.process_legacy_macro_imports(item, module, expansion);
262                 let binding =
263                     (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas);
264                 let directive = self.arenas.alloc_import_directive(ImportDirective {
265                     id: item.id,
266                     parent,
267                     imported_module: Cell::new(Some(module)),
268                     subclass: ImportDirectiveSubclass::ExternCrate,
269                     span: item.span,
270                     module_path: Vec::new(),
271                     vis: Cell::new(vis),
272                     expansion,
273                     used: Cell::new(used),
274                 });
275                 self.potentially_unused_imports.push(directive);
276                 let imported_binding = self.import(binding, directive);
277                 self.define(parent, ident, TypeNS, imported_binding);
278             }
279
280             ItemKind::GlobalAsm(..) => {}
281
282             ItemKind::Mod(..) if item.ident == keywords::Invalid.ident() => {} // Crate root
283
284             ItemKind::Mod(..) => {
285                 let def_id = self.definitions.local_def_id(item.id);
286                 let module_kind = ModuleKind::Def(Def::Mod(def_id), ident.name);
287                 let module = self.arenas.alloc_module(ModuleData {
288                     no_implicit_prelude: parent.no_implicit_prelude || {
289                         attr::contains_name(&item.attrs, "no_implicit_prelude")
290                     },
291                     ..ModuleData::new(Some(parent), module_kind, def_id, expansion, item.span)
292                 });
293                 self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
294                 self.module_map.insert(def_id, module);
295
296                 // Descend into the module.
297                 self.current_module = module;
298             }
299
300             ItemKind::ForeignMod(..) => self.crate_loader.process_item(item, &self.definitions),
301
302             // These items live in the value namespace.
303             ItemKind::Static(_, m, _) => {
304                 let mutbl = m == Mutability::Mutable;
305                 let def = Def::Static(self.definitions.local_def_id(item.id), mutbl);
306                 self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
307             }
308             ItemKind::Const(..) => {
309                 let def = Def::Const(self.definitions.local_def_id(item.id));
310                 self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
311             }
312             ItemKind::Fn(..) => {
313                 let def = Def::Fn(self.definitions.local_def_id(item.id));
314                 self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
315             }
316
317             // These items live in the type namespace.
318             ItemKind::Ty(..) => {
319                 let def = Def::TyAlias(self.definitions.local_def_id(item.id));
320                 self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
321             }
322
323             ItemKind::Enum(ref enum_definition, _) => {
324                 let def = Def::Enum(self.definitions.local_def_id(item.id));
325                 let module_kind = ModuleKind::Def(def, ident.name);
326                 let module = self.new_module(parent,
327                                              module_kind,
328                                              parent.normal_ancestor_id,
329                                              expansion,
330                                              item.span);
331                 self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
332
333                 for variant in &(*enum_definition).variants {
334                     self.build_reduced_graph_for_variant(variant, module, vis, expansion);
335                 }
336             }
337
338             // These items live in both the type and value namespaces.
339             ItemKind::Struct(ref struct_def, _) => {
340                 // Define a name in the type namespace.
341                 let def = Def::Struct(self.definitions.local_def_id(item.id));
342                 self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
343
344                 // Record field names for error reporting.
345                 let mut ctor_vis = vis;
346                 let field_names = struct_def.fields().iter().filter_map(|field| {
347                     let field_vis = self.resolve_visibility(&field.vis);
348                     if ctor_vis.is_at_least(field_vis, &*self) {
349                         ctor_vis = field_vis;
350                     }
351                     field.ident.map(|ident| ident.name)
352                 }).collect();
353                 let item_def_id = self.definitions.local_def_id(item.id);
354                 self.insert_field_names(item_def_id, field_names);
355
356                 // If this is a tuple or unit struct, define a name
357                 // in the value namespace as well.
358                 if !struct_def.is_struct() {
359                     let ctor_def = Def::StructCtor(self.definitions.local_def_id(struct_def.id()),
360                                                    CtorKind::from_ast(struct_def));
361                     self.define(parent, ident, ValueNS, (ctor_def, ctor_vis, sp, expansion));
362                     self.struct_constructors.insert(def.def_id(), (ctor_def, ctor_vis));
363                 }
364             }
365
366             ItemKind::Union(ref vdata, _) => {
367                 let def = Def::Union(self.definitions.local_def_id(item.id));
368                 self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
369
370                 // Record field names for error reporting.
371                 let field_names = vdata.fields().iter().filter_map(|field| {
372                     self.resolve_visibility(&field.vis);
373                     field.ident.map(|ident| ident.name)
374                 }).collect();
375                 let item_def_id = self.definitions.local_def_id(item.id);
376                 self.insert_field_names(item_def_id, field_names);
377             }
378
379             ItemKind::DefaultImpl(..) | ItemKind::Impl(..) => {}
380
381             ItemKind::Trait(..) => {
382                 let def_id = self.definitions.local_def_id(item.id);
383
384                 // Add all the items within to a new module.
385                 let module_kind = ModuleKind::Def(Def::Trait(def_id), ident.name);
386                 let module = self.new_module(parent,
387                                              module_kind,
388                                              parent.normal_ancestor_id,
389                                              expansion,
390                                              item.span);
391                 self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
392                 self.current_module = module;
393             }
394             ItemKind::MacroDef(..) | ItemKind::Mac(_) => unreachable!(),
395         }
396     }
397
398     // Constructs the reduced graph for one variant. Variants exist in the
399     // type and value namespaces.
400     fn build_reduced_graph_for_variant(&mut self,
401                                        variant: &Variant,
402                                        parent: Module<'a>,
403                                        vis: ty::Visibility,
404                                        expansion: Mark) {
405         let ident = variant.node.name;
406         let def_id = self.definitions.local_def_id(variant.node.data.id());
407
408         // Define a name in the type namespace.
409         let def = Def::Variant(def_id);
410         self.define(parent, ident, TypeNS, (def, vis, variant.span, expansion));
411
412         // Define a constructor name in the value namespace.
413         // Braced variants, unlike structs, generate unusable names in
414         // value namespace, they are reserved for possible future use.
415         let ctor_kind = CtorKind::from_ast(&variant.node.data);
416         let ctor_def = Def::VariantCtor(def_id, ctor_kind);
417         self.define(parent, ident, ValueNS, (ctor_def, vis, variant.span, expansion));
418     }
419
420     /// Constructs the reduced graph for one foreign item.
421     fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expansion: Mark) {
422         let def = match item.node {
423             ForeignItemKind::Fn(..) => {
424                 Def::Fn(self.definitions.local_def_id(item.id))
425             }
426             ForeignItemKind::Static(_, m) => {
427                 Def::Static(self.definitions.local_def_id(item.id), m)
428             }
429         };
430         let parent = self.current_module;
431         let vis = self.resolve_visibility(&item.vis);
432         self.define(parent, item.ident, ValueNS, (def, vis, item.span, expansion));
433     }
434
435     fn build_reduced_graph_for_block(&mut self, block: &Block, expansion: Mark) {
436         let parent = self.current_module;
437         if self.block_needs_anonymous_module(block) {
438             let module = self.new_module(parent,
439                                          ModuleKind::Block(block.id),
440                                          parent.normal_ancestor_id,
441                                          expansion,
442                                          block.span);
443             self.block_map.insert(block.id, module);
444             self.current_module = module; // Descend into the block.
445         }
446     }
447
448     /// Builds the reduced graph for a single item in an external crate.
449     fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'a>, child: Export) {
450         let ident = child.ident;
451         let def = child.def;
452         let def_id = def.def_id();
453         let vis = self.cstore.visibility_untracked(def_id);
454         let span = child.span;
455         let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene
456         match def {
457             Def::Mod(..) | Def::Enum(..) => {
458                 let module = self.new_module(parent,
459                                              ModuleKind::Def(def, ident.name),
460                                              def_id,
461                                              expansion,
462                                              span);
463                 self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
464             }
465             Def::Variant(..) | Def::TyAlias(..) => {
466                 self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
467             }
468             Def::Fn(..) | Def::Static(..) | Def::Const(..) | Def::VariantCtor(..) => {
469                 self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion));
470             }
471             Def::StructCtor(..) => {
472                 self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion));
473
474                 if let Some(struct_def_id) =
475                         self.cstore.def_key(def_id).parent
476                             .map(|index| DefId { krate: def_id.krate, index: index }) {
477                     self.struct_constructors.insert(struct_def_id, (def, vis));
478                 }
479             }
480             Def::Trait(..) => {
481                 let module_kind = ModuleKind::Def(def, ident.name);
482                 let module = self.new_module(parent,
483                                              module_kind,
484                                              parent.normal_ancestor_id,
485                                              expansion,
486                                              span);
487                 self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
488
489                 for child in self.cstore.item_children_untracked(def_id, self.session) {
490                     let ns = if let Def::AssociatedTy(..) = child.def { TypeNS } else { ValueNS };
491                     self.define(module, child.ident, ns,
492                                 (child.def, ty::Visibility::Public, DUMMY_SP, expansion));
493
494                     if self.cstore.associated_item_cloned_untracked(child.def.def_id())
495                            .method_has_self_argument {
496                         self.has_self.insert(child.def.def_id());
497                     }
498                 }
499                 module.populated.set(true);
500             }
501             Def::Struct(..) | Def::Union(..) => {
502                 self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
503
504                 // Record field names for error reporting.
505                 let field_names = self.cstore.struct_field_names_untracked(def_id);
506                 self.insert_field_names(def_id, field_names);
507             }
508             Def::Macro(..) => {
509                 self.define(parent, ident, MacroNS, (def, vis, DUMMY_SP, expansion));
510             }
511             _ => bug!("unexpected definition: {:?}", def)
512         }
513     }
514
515     pub fn get_module(&mut self, def_id: DefId) -> Module<'a> {
516         if def_id.krate == LOCAL_CRATE {
517             return self.module_map[&def_id]
518         }
519
520         let macros_only = self.cstore.dep_kind_untracked(def_id.krate).macros_only();
521         if let Some(&module) = self.extern_module_map.get(&(def_id, macros_only)) {
522             return module;
523         }
524
525         let (name, parent) = if def_id.index == CRATE_DEF_INDEX {
526             (self.cstore.crate_name_untracked(def_id.krate).as_str(), None)
527         } else {
528             let def_key = self.cstore.def_key(def_id);
529             (def_key.disambiguated_data.data.get_opt_name().unwrap(),
530              Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id })))
531         };
532
533         let kind = ModuleKind::Def(Def::Mod(def_id), Symbol::intern(&name));
534         let module =
535             self.arenas.alloc_module(ModuleData::new(parent, kind, def_id, Mark::root(), DUMMY_SP));
536         self.extern_module_map.insert((def_id, macros_only), module);
537         module
538     }
539
540     pub fn macro_def_scope(&mut self, expansion: Mark) -> Module<'a> {
541         let def_id = self.macro_defs[&expansion];
542         if let Some(id) = self.definitions.as_local_node_id(def_id) {
543             self.local_macro_def_scopes[&id]
544         } else if def_id.krate == BUILTIN_MACROS_CRATE {
545             // FIXME(jseyfried): This happens when `include!()`ing a `$crate::` path, c.f, #40469.
546             self.graph_root
547         } else {
548             let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap();
549             self.get_module(module_def_id)
550         }
551     }
552
553     pub fn get_macro(&mut self, def: Def) -> Rc<SyntaxExtension> {
554         let def_id = match def {
555             Def::Macro(def_id, ..) => def_id,
556             _ => panic!("Expected Def::Macro(..)"),
557         };
558         if let Some(ext) = self.macro_map.get(&def_id) {
559             return ext.clone();
560         }
561
562         let macro_def = match self.cstore.load_macro_untracked(def_id, &self.session) {
563             LoadedMacro::MacroDef(macro_def) => macro_def,
564             LoadedMacro::ProcMacro(ext) => return ext,
565         };
566
567         let ext = Rc::new(macro_rules::compile(&self.session.parse_sess,
568                                                &self.session.features,
569                                                &macro_def));
570         self.macro_map.insert(def_id, ext.clone());
571         ext
572     }
573
574     /// Ensures that the reduced graph rooted at the given external module
575     /// is built, building it if it is not.
576     pub fn populate_module_if_necessary(&mut self, module: Module<'a>) {
577         if module.populated.get() { return }
578         let def_id = module.def_id().unwrap();
579         for child in self.cstore.item_children_untracked(def_id, self.session) {
580             self.build_reduced_graph_for_external_crate_def(module, child);
581         }
582         module.populated.set(true)
583     }
584
585     fn legacy_import_macro(&mut self,
586                            name: Name,
587                            binding: &'a NameBinding<'a>,
588                            span: Span,
589                            allow_shadowing: bool) {
590         if self.global_macros.insert(name, binding).is_some() && !allow_shadowing {
591             let msg = format!("`{}` is already in scope", name);
592             let note =
593                 "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";
594             self.session.struct_span_err(span, &msg).note(note).emit();
595         }
596     }
597
598     // This returns true if we should consider the underlying `extern crate` to be used.
599     fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, expansion: Mark)
600                                     -> bool {
601         let allow_shadowing = expansion == Mark::root();
602         let legacy_imports = self.legacy_macro_imports(&item.attrs);
603         let mut used = legacy_imports != LegacyMacroImports::default();
604
605         // `#[macro_use]` and `#[macro_reexport]` are only allowed at the crate root.
606         if self.current_module.parent.is_some() && used {
607             span_err!(self.session, item.span, E0468,
608                       "an `extern crate` loading macros must be at the crate root");
609         } else if !self.use_extern_macros && !used &&
610                   self.cstore.dep_kind_untracked(module.def_id().unwrap().krate)
611                       .macros_only() {
612             let msg = "proc macro crates and `#[no_link]` crates have no effect without \
613                        `#[macro_use]`";
614             self.session.span_warn(item.span, msg);
615             used = true; // Avoid the normal unused extern crate warning
616         }
617
618         let (graph_root, arenas) = (self.graph_root, self.arenas);
619         let macro_use_directive = |span| arenas.alloc_import_directive(ImportDirective {
620             id: item.id,
621             parent: graph_root,
622             imported_module: Cell::new(Some(module)),
623             subclass: ImportDirectiveSubclass::MacroUse,
624             span,
625             module_path: Vec::new(),
626             vis: Cell::new(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))),
627             expansion,
628             used: Cell::new(false),
629         });
630
631         if let Some(span) = legacy_imports.import_all {
632             let directive = macro_use_directive(span);
633             self.potentially_unused_imports.push(directive);
634             module.for_each_child(|ident, ns, binding| if ns == MacroNS {
635                 let imported_binding = self.import(binding, directive);
636                 self.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing);
637             });
638         } else {
639             for (name, span) in legacy_imports.imports {
640                 let ident = Ident::with_empty_ctxt(name);
641                 let result = self.resolve_ident_in_module(module, ident, MacroNS,
642                                                           false, false, span);
643                 if let Ok(binding) = result {
644                     let directive = macro_use_directive(span);
645                     self.potentially_unused_imports.push(directive);
646                     let imported_binding = self.import(binding, directive);
647                     self.legacy_import_macro(name, imported_binding, span, allow_shadowing);
648                 } else {
649                     span_err!(self.session, span, E0469, "imported macro not found");
650                 }
651             }
652         }
653         for (name, span) in legacy_imports.reexports {
654             self.cstore.export_macros_untracked(module.def_id().unwrap().krate);
655             let ident = Ident::with_empty_ctxt(name);
656             let result = self.resolve_ident_in_module(module, ident, MacroNS, false, false, span);
657             if let Ok(binding) = result {
658                 self.macro_exports.push(Export { ident: ident, def: binding.def(), span: span });
659             } else {
660                 span_err!(self.session, span, E0470, "reexported macro not found");
661             }
662         }
663         used
664     }
665
666     // does this attribute list contain "macro_use"?
667     fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool {
668         for attr in attrs {
669             if attr.check_name("macro_escape") {
670                 let msg = "macro_escape is a deprecated synonym for macro_use";
671                 let mut err = self.session.struct_span_warn(attr.span, msg);
672                 if let ast::AttrStyle::Inner = attr.style {
673                     err.help("consider an outer attribute, #[macro_use] mod ...").emit();
674                 } else {
675                     err.emit();
676                 }
677             } else if !attr.check_name("macro_use") {
678                 continue;
679             }
680
681             if !attr.is_word() {
682                 self.session.span_err(attr.span, "arguments to macro_use are not allowed here");
683             }
684             return true;
685         }
686
687         false
688     }
689
690     fn legacy_macro_imports(&mut self, attrs: &[ast::Attribute]) -> LegacyMacroImports {
691         let mut imports = LegacyMacroImports::default();
692         for attr in attrs {
693             if attr.check_name("macro_use") {
694                 match attr.meta_item_list() {
695                     Some(names) => for attr in names {
696                         if let Some(word) = attr.word() {
697                             imports.imports.push((word.name(), attr.span()));
698                         } else {
699                             span_err!(self.session, attr.span(), E0466, "bad macro import");
700                         }
701                     },
702                     None => imports.import_all = Some(attr.span),
703                 }
704             } else if attr.check_name("macro_reexport") {
705                 let bad_macro_reexport = |this: &mut Self, span| {
706                     span_err!(this.session, span, E0467, "bad macro reexport");
707                 };
708                 if let Some(names) = attr.meta_item_list() {
709                     for attr in names {
710                         if let Some(word) = attr.word() {
711                             imports.reexports.push((word.name(), attr.span()));
712                         } else {
713                             bad_macro_reexport(self, attr.span());
714                         }
715                     }
716                 } else {
717                     bad_macro_reexport(self, attr.span());
718                 }
719             }
720         }
721         imports
722     }
723 }
724
725 pub struct BuildReducedGraphVisitor<'a, 'b: 'a> {
726     pub resolver: &'a mut Resolver<'b>,
727     pub legacy_scope: LegacyScope<'b>,
728     pub expansion: Mark,
729 }
730
731 impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
732     fn visit_invoc(&mut self, id: ast::NodeId) -> &'b InvocationData<'b> {
733         let mark = id.placeholder_to_mark();
734         self.resolver.current_module.unresolved_invocations.borrow_mut().insert(mark);
735         let invocation = self.resolver.invocations[&mark];
736         invocation.module.set(self.resolver.current_module);
737         invocation.legacy_scope.set(self.legacy_scope);
738         invocation
739     }
740 }
741
742 macro_rules! method {
743     ($visit:ident: $ty:ty, $invoc:path, $walk:ident) => {
744         fn $visit(&mut self, node: &'a $ty) {
745             if let $invoc(..) = node.node {
746                 self.visit_invoc(node.id);
747             } else {
748                 visit::$walk(self, node);
749             }
750         }
751     }
752 }
753
754 impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
755     method!(visit_impl_item: ast::ImplItem, ast::ImplItemKind::Macro, walk_impl_item);
756     method!(visit_expr:      ast::Expr,     ast::ExprKind::Mac,       walk_expr);
757     method!(visit_pat:       ast::Pat,      ast::PatKind::Mac,        walk_pat);
758     method!(visit_ty:        ast::Ty,       ast::TyKind::Mac,         walk_ty);
759
760     fn visit_item(&mut self, item: &'a Item) {
761         let macro_use = match item.node {
762             ItemKind::MacroDef(..) => {
763                 self.resolver.define_macro(item, self.expansion, &mut self.legacy_scope);
764                 return
765             }
766             ItemKind::Mac(..) => {
767                 self.legacy_scope = LegacyScope::Expansion(self.visit_invoc(item.id));
768                 return
769             }
770             ItemKind::Mod(..) => self.resolver.contains_macro_use(&item.attrs),
771             _ => false,
772         };
773
774         let (parent, legacy_scope) = (self.resolver.current_module, self.legacy_scope);
775         self.resolver.build_reduced_graph_for_item(item, self.expansion);
776         visit::walk_item(self, item);
777         self.resolver.current_module = parent;
778         if !macro_use {
779             self.legacy_scope = legacy_scope;
780         }
781     }
782
783     fn visit_stmt(&mut self, stmt: &'a ast::Stmt) {
784         if let ast::StmtKind::Mac(..) = stmt.node {
785             self.legacy_scope = LegacyScope::Expansion(self.visit_invoc(stmt.id));
786         } else {
787             visit::walk_stmt(self, stmt);
788         }
789     }
790
791     fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
792         self.resolver.build_reduced_graph_for_foreign_item(foreign_item, self.expansion);
793         visit::walk_foreign_item(self, foreign_item);
794     }
795
796     fn visit_block(&mut self, block: &'a Block) {
797         let (parent, legacy_scope) = (self.resolver.current_module, self.legacy_scope);
798         self.resolver.build_reduced_graph_for_block(block, self.expansion);
799         visit::walk_block(self, block);
800         self.resolver.current_module = parent;
801         self.legacy_scope = legacy_scope;
802     }
803
804     fn visit_trait_item(&mut self, item: &'a TraitItem) {
805         let parent = self.resolver.current_module;
806
807         if let TraitItemKind::Macro(_) = item.node {
808             self.visit_invoc(item.id);
809             return
810         }
811
812         // Add the item to the trait info.
813         let item_def_id = self.resolver.definitions.local_def_id(item.id);
814         let (def, ns) = match item.node {
815             TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS),
816             TraitItemKind::Method(ref sig, _) => {
817                 if sig.decl.has_self() {
818                     self.resolver.has_self.insert(item_def_id);
819                 }
820                 (Def::Method(item_def_id), ValueNS)
821             }
822             TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS),
823             TraitItemKind::Macro(_) => bug!(),  // handled above
824         };
825
826         let vis = ty::Visibility::Public;
827         self.resolver.define(parent, item.ident, ns, (def, vis, item.span, self.expansion));
828
829         self.resolver.current_module = parent.parent.unwrap(); // nearest normal ancestor
830         visit::walk_trait_item(self, item);
831         self.resolver.current_module = parent;
832     }
833 }