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.
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.
11 //! Reduced graph building
13 //! Here we build the "reduced graph": the graph of the module tree without
14 //! any imports resolved.
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}
;
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}
;
32 use syntax
::ast
::{Name, Ident}
;
35 use syntax
::ast
::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId}
;
36 use syntax
::ast
::{Mutability, StmtKind, TraitItem, TraitItemKind, Variant}
;
37 use syntax
::codemap
::respan
;
38 use syntax
::ext
::base
::SyntaxExtension
;
39 use syntax
::ext
::base
::Determinacy
::Undetermined
;
40 use syntax
::ext
::hygiene
::Mark
;
41 use syntax
::ext
::tt
::macro_rules
;
42 use syntax
::parse
::token
::{self, Token}
;
43 use syntax
::std_inject
::injected_crate_name
;
44 use syntax
::symbol
::keywords
;
45 use syntax
::symbol
::Symbol
;
46 use syntax
::visit
::{self, Visitor}
;
48 use syntax_pos
::{Span, DUMMY_SP}
;
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),
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),
72 #[derive(Default, PartialEq, Eq)]
73 struct LegacyMacroImports
{
74 import_all
: Option
<Span
>,
75 imports
: Vec
<(Name
, Span
)>,
76 reexports
: Vec
<(Name
, Span
)>,
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
>,
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
);
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,
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
);
105 fn build_reduced_graph_for_use_tree(&mut self,
106 use_tree
: &ast
::UseTree
,
113 let is_prelude
= attr
::contains_name(&item
.attrs
, "prelude_import");
114 let path
= &use_tree
.prefix
;
116 let mut module_path
: Vec
<_
> = prefix
.segments
.iter()
117 .chain(path
.segments
.iter())
118 .map(|seg
| respan(seg
.span
, seg
.identifier
))
121 match use_tree
.kind
{
122 ast
::UseTreeKind
::Simple(mut ident
) => {
123 let mut source
= module_path
.pop().unwrap().node
;
124 let mut type_ns_only
= false;
127 // Correctly handle `self`
128 if source
.name
== keywords
::SelfValue
.name() {
131 let last_segment
= *module_path
.last().unwrap();
132 if last_segment
.node
.name
== keywords
::CrateRoot
.name() {
137 SelfImportOnlyInImportListWithNonEmptyPrefix
142 // Replace `use foo::self;` with `use foo;`
143 let _
= module_path
.pop();
144 source
= last_segment
.node
;
145 if ident
.name
== keywords
::SelfValue
.name() {
146 ident
= last_segment
.node
;
151 if source
.name
== keywords
::SelfValue
.name() {
154 ResolutionError
::SelfImportsOnlyAllowedWithin
);
157 // Disallow `use $crate;`
158 if source
.name
== keywords
::DollarCrate
.name() && path
.segments
.len() == 1 {
159 let crate_root
= self.resolve_crate_root(source
.ctxt
, true);
160 let crate_name
= match crate_root
.kind
{
161 ModuleKind
::Def(_
, name
) => name
,
162 ModuleKind
::Block(..) => unreachable
!(),
164 source
.name
= crate_name
;
165 if ident
.name
== keywords
::DollarCrate
.name() {
166 ident
.name
= crate_name
;
169 self.session
.struct_span_warn(item
.span
, "`$crate` may not be imported")
170 .note("`use $crate;` was erroneously allowed and \
171 will become a hard error in a future release")
176 let subclass
= SingleImport
{
179 result
: self.per_ns(|_
, _
| Cell
::new(Err(Undetermined
))),
182 self.add_import_directive(
183 module_path
, subclass
, use_tree
.span
, id
, vis
, expansion
,
186 ast
::UseTreeKind
::Glob
=> {
187 let subclass
= GlobImport
{
189 max_vis
: Cell
::new(ty
::Visibility
::Invisible
),
191 self.add_import_directive(
192 module_path
, subclass
, use_tree
.span
, id
, vis
, expansion
,
195 ast
::UseTreeKind
::Nested(ref items
) => {
196 let prefix
= ast
::Path
{
197 segments
: module_path
.iter()
198 .map(|s
| ast
::PathSegment
{
207 // Ensure there is at most one `self` in the list
208 let self_spans
= items
.iter().filter_map(|&(ref use_tree
, _
)| {
209 if let ast
::UseTreeKind
::Simple(ident
) = use_tree
.kind
{
210 if ident
.name
== keywords
::SelfValue
.name() {
211 return Some(use_tree
.span
);
216 }).collect
::<Vec
<_
>>();
217 if self_spans
.len() > 1 {
218 let mut e
= resolve_struct_error(self,
220 ResolutionError
::SelfImportCanOnlyAppearOnceInTheList
);
222 for other_span
in self_spans
.iter().skip(1) {
223 e
.span_label(*other_span
, "another `self` import appears here");
229 for &(ref tree
, id
) in items
{
230 self.build_reduced_graph_for_use_tree(
231 tree
, id
, vis
, &prefix
, true, item
, expansion
238 /// Constructs the reduced graph for one item.
239 fn build_reduced_graph_for_item(&mut self, item
: &Item
, expansion
: Mark
) {
240 let parent
= self.current_module
;
241 let ident
= item
.ident
;
243 let vis
= self.resolve_visibility(&item
.vis
);
246 ItemKind
::Use(ref use_tree
) => {
247 // Just an empty prefix to start out
248 let prefix
= ast
::Path
{
253 self.build_reduced_graph_for_use_tree(
254 use_tree
, item
.id
, vis
, &prefix
, false, item
, expansion
,
258 ItemKind
::ExternCrate(as_name
) => {
259 self.crate_loader
.process_item(item
, &self.definitions
);
261 // n.b. we don't need to look at the path option here, because cstore already did
262 let crate_id
= self.cstore
.extern_mod_stmt_cnum_untracked(item
.id
).unwrap();
264 self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }
);
265 self.populate_module_if_necessary(module
);
266 if injected_crate_name().map_or(false, |name
| item
.ident
.name
== name
) {
267 self.injected_crate
= Some(module
);
270 let used
= self.process_legacy_macro_imports(item
, module
, expansion
);
272 (module
, ty
::Visibility
::Public
, sp
, expansion
).to_name_binding(self.arenas
);
273 let directive
= self.arenas
.alloc_import_directive(ImportDirective
{
276 imported_module
: Cell
::new(Some(module
)),
277 subclass
: ImportDirectiveSubclass
::ExternCrate(as_name
),
279 module_path
: Vec
::new(),
282 used
: Cell
::new(used
),
284 self.potentially_unused_imports
.push(directive
);
285 let imported_binding
= self.import(binding
, directive
);
286 self.define(parent
, ident
, TypeNS
, imported_binding
);
289 ItemKind
::GlobalAsm(..) => {}
291 ItemKind
::Mod(..) if item
.ident
== keywords
::Invalid
.ident() => {}
// Crate root
293 ItemKind
::Mod(..) => {
294 let def_id
= self.definitions
.local_def_id(item
.id
);
295 let module_kind
= ModuleKind
::Def(Def
::Mod(def_id
), ident
.name
);
296 let module
= self.arenas
.alloc_module(ModuleData
{
297 no_implicit_prelude
: parent
.no_implicit_prelude
|| {
298 attr
::contains_name(&item
.attrs
, "no_implicit_prelude")
300 ..ModuleData
::new(Some(parent
), module_kind
, def_id
, expansion
, item
.span
)
302 self.define(parent
, ident
, TypeNS
, (module
, vis
, sp
, expansion
));
303 self.module_map
.insert(def_id
, module
);
305 // Descend into the module.
306 self.current_module
= module
;
309 ItemKind
::ForeignMod(..) => self.crate_loader
.process_item(item
, &self.definitions
),
311 // These items live in the value namespace.
312 ItemKind
::Static(_
, m
, _
) => {
313 let mutbl
= m
== Mutability
::Mutable
;
314 let def
= Def
::Static(self.definitions
.local_def_id(item
.id
), mutbl
);
315 self.define(parent
, ident
, ValueNS
, (def
, vis
, sp
, expansion
));
317 ItemKind
::Const(..) => {
318 let def
= Def
::Const(self.definitions
.local_def_id(item
.id
));
319 self.define(parent
, ident
, ValueNS
, (def
, vis
, sp
, expansion
));
321 ItemKind
::Fn(..) => {
322 let def
= Def
::Fn(self.definitions
.local_def_id(item
.id
));
323 self.define(parent
, ident
, ValueNS
, (def
, vis
, sp
, expansion
));
326 // These items live in the type namespace.
327 ItemKind
::Ty(..) => {
328 let def
= Def
::TyAlias(self.definitions
.local_def_id(item
.id
));
329 self.define(parent
, ident
, TypeNS
, (def
, vis
, sp
, expansion
));
332 ItemKind
::Enum(ref enum_definition
, _
) => {
333 let def
= Def
::Enum(self.definitions
.local_def_id(item
.id
));
334 let module_kind
= ModuleKind
::Def(def
, ident
.name
);
335 let module
= self.new_module(parent
,
337 parent
.normal_ancestor_id
,
340 self.define(parent
, ident
, TypeNS
, (module
, vis
, sp
, expansion
));
342 for variant
in &(*enum_definition
).variants
{
343 self.build_reduced_graph_for_variant(variant
, module
, vis
, expansion
);
347 ItemKind
::TraitAlias(..) => {
348 let def
= Def
::TraitAlias(self.definitions
.local_def_id(item
.id
));
349 self.define(parent
, ident
, TypeNS
, (def
, vis
, sp
, expansion
));
352 // These items live in both the type and value namespaces.
353 ItemKind
::Struct(ref struct_def
, _
) => {
354 // Define a name in the type namespace.
355 let def_id
= self.definitions
.local_def_id(item
.id
);
356 let def
= Def
::Struct(def_id
);
357 self.define(parent
, ident
, TypeNS
, (def
, vis
, sp
, expansion
));
359 let mut ctor_vis
= vis
;
361 let has_non_exhaustive
= attr
::contains_name(&item
.attrs
, "non_exhaustive");
363 // If the structure is marked as non_exhaustive then lower the visibility
364 // to within the crate.
365 if has_non_exhaustive
&& vis
== ty
::Visibility
::Public
{
366 ctor_vis
= ty
::Visibility
::Restricted(DefId
::local(CRATE_DEF_INDEX
));
369 // Record field names for error reporting.
370 let field_names
= struct_def
.fields().iter().filter_map(|field
| {
371 let field_vis
= self.resolve_visibility(&field
.vis
);
372 if ctor_vis
.is_at_least(field_vis
, &*self) {
373 ctor_vis
= field_vis
;
375 field
.ident
.map(|ident
| ident
.name
)
377 let item_def_id
= self.definitions
.local_def_id(item
.id
);
378 self.insert_field_names(item_def_id
, field_names
);
380 // If this is a tuple or unit struct, define a name
381 // in the value namespace as well.
382 if !struct_def
.is_struct() {
383 let ctor_def
= Def
::StructCtor(self.definitions
.local_def_id(struct_def
.id()),
384 CtorKind
::from_ast(struct_def
));
385 self.define(parent
, ident
, ValueNS
, (ctor_def
, ctor_vis
, sp
, expansion
));
386 self.struct_constructors
.insert(def
.def_id(), (ctor_def
, ctor_vis
));
390 ItemKind
::Union(ref vdata
, _
) => {
391 let def
= Def
::Union(self.definitions
.local_def_id(item
.id
));
392 self.define(parent
, ident
, TypeNS
, (def
, vis
, sp
, expansion
));
394 // Record field names for error reporting.
395 let field_names
= vdata
.fields().iter().filter_map(|field
| {
396 self.resolve_visibility(&field
.vis
);
397 field
.ident
.map(|ident
| ident
.name
)
399 let item_def_id
= self.definitions
.local_def_id(item
.id
);
400 self.insert_field_names(item_def_id
, field_names
);
403 ItemKind
::Impl(..) => {}
405 ItemKind
::Trait(..) => {
406 let def_id
= self.definitions
.local_def_id(item
.id
);
408 // Add all the items within to a new module.
409 let module_kind
= ModuleKind
::Def(Def
::Trait(def_id
), ident
.name
);
410 let module
= self.new_module(parent
,
412 parent
.normal_ancestor_id
,
415 self.define(parent
, ident
, TypeNS
, (module
, vis
, sp
, expansion
));
416 self.current_module
= module
;
419 ItemKind
::MacroDef(..) | ItemKind
::Mac(_
) => unreachable
!(),
423 // Constructs the reduced graph for one variant. Variants exist in the
424 // type and value namespaces.
425 fn build_reduced_graph_for_variant(&mut self,
430 let ident
= variant
.node
.name
;
431 let def_id
= self.definitions
.local_def_id(variant
.node
.data
.id());
433 // Define a name in the type namespace.
434 let def
= Def
::Variant(def_id
);
435 self.define(parent
, ident
, TypeNS
, (def
, vis
, variant
.span
, expansion
));
437 // Define a constructor name in the value namespace.
438 // Braced variants, unlike structs, generate unusable names in
439 // value namespace, they are reserved for possible future use.
440 let ctor_kind
= CtorKind
::from_ast(&variant
.node
.data
);
441 let ctor_def
= Def
::VariantCtor(def_id
, ctor_kind
);
443 self.define(parent
, ident
, ValueNS
, (ctor_def
, vis
, variant
.span
, expansion
));
446 /// Constructs the reduced graph for one foreign item.
447 fn build_reduced_graph_for_foreign_item(&mut self, item
: &ForeignItem
, expansion
: Mark
) {
448 let (def
, ns
) = match item
.node
{
449 ForeignItemKind
::Fn(..) => {
450 (Def
::Fn(self.definitions
.local_def_id(item
.id
)), ValueNS
)
452 ForeignItemKind
::Static(_
, m
) => {
453 (Def
::Static(self.definitions
.local_def_id(item
.id
), m
), ValueNS
)
455 ForeignItemKind
::Ty
=> {
456 (Def
::TyForeign(self.definitions
.local_def_id(item
.id
)), TypeNS
)
459 let parent
= self.current_module
;
460 let vis
= self.resolve_visibility(&item
.vis
);
461 self.define(parent
, item
.ident
, ns
, (def
, vis
, item
.span
, expansion
));
464 fn build_reduced_graph_for_block(&mut self, block
: &Block
, expansion
: Mark
) {
465 let parent
= self.current_module
;
466 if self.block_needs_anonymous_module(block
) {
467 let module
= self.new_module(parent
,
468 ModuleKind
::Block(block
.id
),
469 parent
.normal_ancestor_id
,
472 self.block_map
.insert(block
.id
, module
);
473 self.current_module
= module
; // Descend into the block.
477 /// Builds the reduced graph for a single item in an external crate.
478 fn build_reduced_graph_for_external_crate_def(&mut self, parent
: Module
<'a
>, child
: Export
) {
479 let Export { ident, def, vis, span, .. }
= child
;
480 let def_id
= def
.def_id();
481 let expansion
= Mark
::root(); // FIXME(jseyfried) intercrate hygiene
483 Def
::Mod(..) | Def
::Enum(..) => {
484 let module
= self.new_module(parent
,
485 ModuleKind
::Def(def
, ident
.name
),
489 self.define(parent
, ident
, TypeNS
, (module
, vis
, DUMMY_SP
, expansion
));
491 Def
::Variant(..) | Def
::TyAlias(..) | Def
::TyForeign(..) => {
492 self.define(parent
, ident
, TypeNS
, (def
, vis
, DUMMY_SP
, expansion
));
494 Def
::Fn(..) | Def
::Static(..) | Def
::Const(..) | Def
::VariantCtor(..) => {
495 self.define(parent
, ident
, ValueNS
, (def
, vis
, DUMMY_SP
, expansion
));
497 Def
::StructCtor(..) => {
498 self.define(parent
, ident
, ValueNS
, (def
, vis
, DUMMY_SP
, expansion
));
500 if let Some(struct_def_id
) =
501 self.cstore
.def_key(def_id
).parent
502 .map(|index
| DefId { krate: def_id.krate, index: index }
) {
503 self.struct_constructors
.insert(struct_def_id
, (def
, vis
));
507 let module_kind
= ModuleKind
::Def(def
, ident
.name
);
508 let module
= self.new_module(parent
,
510 parent
.normal_ancestor_id
,
513 self.define(parent
, ident
, TypeNS
, (module
, vis
, DUMMY_SP
, expansion
));
515 for child
in self.cstore
.item_children_untracked(def_id
, self.session
) {
516 let ns
= if let Def
::AssociatedTy(..) = child
.def { TypeNS }
else { ValueNS }
;
517 self.define(module
, child
.ident
, ns
,
518 (child
.def
, ty
::Visibility
::Public
, DUMMY_SP
, expansion
));
520 if self.cstore
.associated_item_cloned_untracked(child
.def
.def_id())
521 .method_has_self_argument
{
522 self.has_self
.insert(child
.def
.def_id());
525 module
.populated
.set(true);
527 Def
::Struct(..) | Def
::Union(..) => {
528 self.define(parent
, ident
, TypeNS
, (def
, vis
, DUMMY_SP
, expansion
));
530 // Record field names for error reporting.
531 let field_names
= self.cstore
.struct_field_names_untracked(def_id
);
532 self.insert_field_names(def_id
, field_names
);
535 self.define(parent
, ident
, MacroNS
, (def
, vis
, DUMMY_SP
, expansion
));
537 _
=> bug
!("unexpected definition: {:?}", def
)
541 pub fn get_module(&mut self, def_id
: DefId
) -> Module
<'a
> {
542 if def_id
.krate
== LOCAL_CRATE
{
543 return self.module_map
[&def_id
]
546 let macros_only
= self.cstore
.dep_kind_untracked(def_id
.krate
).macros_only();
547 if let Some(&module
) = self.extern_module_map
.get(&(def_id
, macros_only
)) {
551 let (name
, parent
) = if def_id
.index
== CRATE_DEF_INDEX
{
552 (self.cstore
.crate_name_untracked(def_id
.krate
).as_str(), None
)
554 let def_key
= self.cstore
.def_key(def_id
);
555 (def_key
.disambiguated_data
.data
.get_opt_name().unwrap(),
556 Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id }
)))
559 let kind
= ModuleKind
::Def(Def
::Mod(def_id
), Symbol
::intern(&name
));
561 self.arenas
.alloc_module(ModuleData
::new(parent
, kind
, def_id
, Mark
::root(), DUMMY_SP
));
562 self.extern_module_map
.insert((def_id
, macros_only
), module
);
566 pub fn macro_def_scope(&mut self, expansion
: Mark
) -> Module
<'a
> {
567 let def_id
= self.macro_defs
[&expansion
];
568 if let Some(id
) = self.definitions
.as_local_node_id(def_id
) {
569 self.local_macro_def_scopes
[&id
]
570 } else if def_id
.krate
== BUILTIN_MACROS_CRATE
{
571 self.injected_crate
.unwrap_or(self.graph_root
)
573 let module_def_id
= ty
::DefIdTree
::parent(&*self, def_id
).unwrap();
574 self.get_module(module_def_id
)
578 pub fn get_macro(&mut self, def
: Def
) -> Rc
<SyntaxExtension
> {
579 let def_id
= match def
{
580 Def
::Macro(def_id
, ..) => def_id
,
581 _
=> panic
!("Expected Def::Macro(..)"),
583 if let Some(ext
) = self.macro_map
.get(&def_id
) {
587 let macro_def
= match self.cstore
.load_macro_untracked(def_id
, &self.session
) {
588 LoadedMacro
::MacroDef(macro_def
) => macro_def
,
589 LoadedMacro
::ProcMacro(ext
) => return ext
,
592 let ext
= Rc
::new(macro_rules
::compile(&self.session
.parse_sess
,
593 &self.session
.features
,
595 self.macro_map
.insert(def_id
, ext
.clone());
599 /// Ensures that the reduced graph rooted at the given external module
600 /// is built, building it if it is not.
601 pub fn populate_module_if_necessary(&mut self, module
: Module
<'a
>) {
602 if module
.populated
.get() { return }
603 let def_id
= module
.def_id().unwrap();
604 for child
in self.cstore
.item_children_untracked(def_id
, self.session
) {
605 self.build_reduced_graph_for_external_crate_def(module
, child
);
607 module
.populated
.set(true)
610 fn legacy_import_macro(&mut self,
612 binding
: &'a NameBinding
<'a
>,
614 allow_shadowing
: bool
) {
615 if self.global_macros
.insert(name
, binding
).is_some() && !allow_shadowing
{
616 let msg
= format
!("`{}` is already in scope", name
);
618 "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";
619 self.session
.struct_span_err(span
, &msg
).note(note
).emit();
623 // This returns true if we should consider the underlying `extern crate` to be used.
624 fn process_legacy_macro_imports(&mut self, item
: &Item
, module
: Module
<'a
>, expansion
: Mark
)
626 let allow_shadowing
= expansion
== Mark
::root();
627 let legacy_imports
= self.legacy_macro_imports(&item
.attrs
);
628 let mut used
= legacy_imports
!= LegacyMacroImports
::default();
630 // `#[macro_use]` and `#[macro_reexport]` are only allowed at the crate root.
631 if self.current_module
.parent
.is_some() && used
{
632 span_err
!(self.session
, item
.span
, E0468
,
633 "an `extern crate` loading macros must be at the crate root");
634 } else if !self.use_extern_macros
&& !used
&&
635 self.cstore
.dep_kind_untracked(module
.def_id().unwrap().krate
)
637 let msg
= "proc macro crates and `#[no_link]` crates have no effect without \
639 self.session
.span_warn(item
.span
, msg
);
640 used
= true; // Avoid the normal unused extern crate warning
643 let (graph_root
, arenas
) = (self.graph_root
, self.arenas
);
644 let macro_use_directive
= |span
| arenas
.alloc_import_directive(ImportDirective
{
647 imported_module
: Cell
::new(Some(module
)),
648 subclass
: ImportDirectiveSubclass
::MacroUse
,
650 module_path
: Vec
::new(),
651 vis
: Cell
::new(ty
::Visibility
::Restricted(DefId
::local(CRATE_DEF_INDEX
))),
653 used
: Cell
::new(false),
656 if let Some(span
) = legacy_imports
.import_all
{
657 let directive
= macro_use_directive(span
);
658 self.potentially_unused_imports
.push(directive
);
659 module
.for_each_child(|ident
, ns
, binding
| if ns
== MacroNS
{
660 let imported_binding
= self.import(binding
, directive
);
661 self.legacy_import_macro(ident
.name
, imported_binding
, span
, allow_shadowing
);
664 for (name
, span
) in legacy_imports
.imports
{
665 let ident
= Ident
::with_empty_ctxt(name
);
666 let result
= self.resolve_ident_in_module(module
, ident
, MacroNS
,
668 if let Ok(binding
) = result
{
669 let directive
= macro_use_directive(span
);
670 self.potentially_unused_imports
.push(directive
);
671 let imported_binding
= self.import(binding
, directive
);
672 self.legacy_import_macro(name
, imported_binding
, span
, allow_shadowing
);
674 span_err
!(self.session
, span
, E0469
, "imported macro not found");
678 for (name
, span
) in legacy_imports
.reexports
{
679 self.cstore
.export_macros_untracked(module
.def_id().unwrap().krate
);
680 let ident
= Ident
::with_empty_ctxt(name
);
681 let result
= self.resolve_ident_in_module(module
, ident
, MacroNS
, false, false, span
);
682 if let Ok(binding
) = result
{
683 let (def
, vis
) = (binding
.def(), binding
.vis
);
684 self.macro_exports
.push(Export { ident, def, vis, span, is_import: true }
);
686 span_err
!(self.session
, span
, E0470
, "re-exported macro not found");
692 // does this attribute list contain "macro_use"?
693 fn contains_macro_use(&mut self, attrs
: &[ast
::Attribute
]) -> bool
{
695 if attr
.check_name("macro_escape") {
696 let msg
= "macro_escape is a deprecated synonym for macro_use";
697 let mut err
= self.session
.struct_span_warn(attr
.span
, msg
);
698 if let ast
::AttrStyle
::Inner
= attr
.style
{
699 err
.help("consider an outer attribute, #[macro_use] mod ...").emit();
703 } else if !attr
.check_name("macro_use") {
708 self.session
.span_err(attr
.span
, "arguments to macro_use are not allowed here");
716 fn legacy_macro_imports(&mut self, attrs
: &[ast
::Attribute
]) -> LegacyMacroImports
{
717 let mut imports
= LegacyMacroImports
::default();
719 if attr
.check_name("macro_use") {
720 match attr
.meta_item_list() {
721 Some(names
) => for attr
in names
{
722 if let Some(word
) = attr
.word() {
723 imports
.imports
.push((word
.name(), attr
.span()));
725 span_err
!(self.session
, attr
.span(), E0466
, "bad macro import");
728 None
=> imports
.import_all
= Some(attr
.span
),
730 } else if attr
.check_name("macro_reexport") {
731 let bad_macro_reexport
= |this
: &mut Self, span
| {
732 span_err
!(this
.session
, span
, E0467
, "bad macro re-export");
734 if let Some(names
) = attr
.meta_item_list() {
736 if let Some(word
) = attr
.word() {
737 imports
.reexports
.push((word
.name(), attr
.span()));
739 bad_macro_reexport(self, attr
.span());
743 bad_macro_reexport(self, attr
.span());
751 pub struct BuildReducedGraphVisitor
<'a
, 'b
: 'a
> {
752 pub resolver
: &'a
mut Resolver
<'b
>,
753 pub legacy_scope
: LegacyScope
<'b
>,
757 impl<'a
, 'b
> BuildReducedGraphVisitor
<'a
, 'b
> {
758 fn visit_invoc(&mut self, id
: ast
::NodeId
) -> &'b InvocationData
<'b
> {
759 let mark
= id
.placeholder_to_mark();
760 self.resolver
.current_module
.unresolved_invocations
.borrow_mut().insert(mark
);
761 let invocation
= self.resolver
.invocations
[&mark
];
762 invocation
.module
.set(self.resolver
.current_module
);
763 invocation
.legacy_scope
.set(self.legacy_scope
);
768 macro_rules
! method
{
769 ($visit
:ident
: $ty
:ty
, $invoc
:path
, $walk
:ident
) => {
770 fn $
visit(&mut self, node
: &'a $ty
) {
771 if let $
invoc(..) = node
.node
{
772 self.visit_invoc(node
.id
);
774 visit
::$
walk(self, node
);
780 impl<'a
, 'b
> Visitor
<'a
> for BuildReducedGraphVisitor
<'a
, 'b
> {
781 method
!(visit_impl_item
: ast
::ImplItem
, ast
::ImplItemKind
::Macro
, walk_impl_item
);
782 method
!(visit_expr
: ast
::Expr
, ast
::ExprKind
::Mac
, walk_expr
);
783 method
!(visit_pat
: ast
::Pat
, ast
::PatKind
::Mac
, walk_pat
);
784 method
!(visit_ty
: ast
::Ty
, ast
::TyKind
::Mac
, walk_ty
);
786 fn visit_item(&mut self, item
: &'a Item
) {
787 let macro_use
= match item
.node
{
788 ItemKind
::MacroDef(..) => {
789 self.resolver
.define_macro(item
, self.expansion
, &mut self.legacy_scope
);
792 ItemKind
::Mac(..) => {
793 self.legacy_scope
= LegacyScope
::Expansion(self.visit_invoc(item
.id
));
796 ItemKind
::Mod(..) => self.resolver
.contains_macro_use(&item
.attrs
),
800 let (parent
, legacy_scope
) = (self.resolver
.current_module
, self.legacy_scope
);
801 self.resolver
.build_reduced_graph_for_item(item
, self.expansion
);
802 visit
::walk_item(self, item
);
803 self.resolver
.current_module
= parent
;
805 self.legacy_scope
= legacy_scope
;
809 fn visit_stmt(&mut self, stmt
: &'a ast
::Stmt
) {
810 if let ast
::StmtKind
::Mac(..) = stmt
.node
{
811 self.legacy_scope
= LegacyScope
::Expansion(self.visit_invoc(stmt
.id
));
813 visit
::walk_stmt(self, stmt
);
817 fn visit_foreign_item(&mut self, foreign_item
: &'a ForeignItem
) {
818 self.resolver
.build_reduced_graph_for_foreign_item(foreign_item
, self.expansion
);
819 visit
::walk_foreign_item(self, foreign_item
);
822 fn visit_block(&mut self, block
: &'a Block
) {
823 let (parent
, legacy_scope
) = (self.resolver
.current_module
, self.legacy_scope
);
824 self.resolver
.build_reduced_graph_for_block(block
, self.expansion
);
825 visit
::walk_block(self, block
);
826 self.resolver
.current_module
= parent
;
827 self.legacy_scope
= legacy_scope
;
830 fn visit_trait_item(&mut self, item
: &'a TraitItem
) {
831 let parent
= self.resolver
.current_module
;
833 if let TraitItemKind
::Macro(_
) = item
.node
{
834 self.visit_invoc(item
.id
);
838 // Add the item to the trait info.
839 let item_def_id
= self.resolver
.definitions
.local_def_id(item
.id
);
840 let (def
, ns
) = match item
.node
{
841 TraitItemKind
::Const(..) => (Def
::AssociatedConst(item_def_id
), ValueNS
),
842 TraitItemKind
::Method(ref sig
, _
) => {
843 if sig
.decl
.has_self() {
844 self.resolver
.has_self
.insert(item_def_id
);
846 (Def
::Method(item_def_id
), ValueNS
)
848 TraitItemKind
::Type(..) => (Def
::AssociatedTy(item_def_id
), TypeNS
),
849 TraitItemKind
::Macro(_
) => bug
!(), // handled above
852 let vis
= ty
::Visibility
::Public
;
853 self.resolver
.define(parent
, item
.ident
, ns
, (def
, vis
, item
.span
, self.expansion
));
855 self.resolver
.current_module
= parent
.parent
.unwrap(); // nearest normal ancestor
856 visit
::walk_trait_item(self, item
);
857 self.resolver
.current_module
= parent
;
860 fn visit_token(&mut self, t
: Token
) {
861 if let Token
::Interpolated(nt
) = t
{
863 token
::NtExpr(ref expr
) => {
864 if let ast
::ExprKind
::Mac(..) = expr
.node
{
865 self.visit_invoc(expr
.id
);