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, ParentScope, LegacyScope}
;
17 use resolve_imports
::ImportDirective
;
18 use resolve_imports
::ImportDirectiveSubclass
::{self, GlobImport, SingleImport}
;
19 use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding}
;
20 use {ModuleOrUniformRoot, PerNS, Resolver, ResolverArenas, ExternPreludeEntry}
;
21 use Namespace
::{self, TypeNS, ValueNS, MacroNS}
;
22 use {resolve_error, resolve_struct_error, ResolutionError}
;
24 use rustc
::hir
::def
::*;
25 use rustc
::hir
::def_id
::{CrateNum, CRATE_DEF_INDEX, LOCAL_CRATE, DefId}
;
27 use rustc
::middle
::cstore
::CrateStore
;
28 use rustc_metadata
::cstore
::LoadedMacro
;
32 use rustc_data_structures
::sync
::Lrc
;
34 use syntax
::ast
::{Name, Ident}
;
37 use syntax
::ast
::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId}
;
38 use syntax
::ast
::{MetaItemKind, Mutability, StmtKind, TraitItem, TraitItemKind, Variant}
;
39 use syntax
::ext
::base
::{MacroKind, SyntaxExtension}
;
40 use syntax
::ext
::base
::Determinacy
::Undetermined
;
41 use syntax
::ext
::hygiene
::Mark
;
42 use syntax
::ext
::tt
::macro_rules
;
43 use syntax
::feature_gate
::is_builtin_attr
;
44 use syntax
::parse
::token
::{self, Token}
;
45 use syntax
::std_inject
::injected_crate_name
;
46 use syntax
::symbol
::keywords
;
47 use syntax
::visit
::{self, Visitor}
;
49 use syntax_pos
::{Span, DUMMY_SP}
;
51 impl<'a
> ToNameBinding
<'a
> for (Module
<'a
>, ty
::Visibility
, Span
, Mark
) {
52 fn to_name_binding(self, arenas
: &'a ResolverArenas
<'a
>) -> &'a NameBinding
<'a
> {
53 arenas
.alloc_name_binding(NameBinding
{
54 kind
: NameBindingKind
::Module(self.0),
62 impl<'a
> ToNameBinding
<'a
> for (Def
, ty
::Visibility
, Span
, Mark
) {
63 fn to_name_binding(self, arenas
: &'a ResolverArenas
<'a
>) -> &'a NameBinding
<'a
> {
64 arenas
.alloc_name_binding(NameBinding
{
65 kind
: NameBindingKind
::Def(self.0, false),
73 pub(crate) struct IsMacroExport
;
75 impl<'a
> ToNameBinding
<'a
> for (Def
, ty
::Visibility
, Span
, Mark
, IsMacroExport
) {
76 fn to_name_binding(self, arenas
: &'a ResolverArenas
<'a
>) -> &'a NameBinding
<'a
> {
77 arenas
.alloc_name_binding(NameBinding
{
78 kind
: NameBindingKind
::Def(self.0, true),
86 impl<'a
, 'cl
> Resolver
<'a
, 'cl
> {
87 /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
88 /// otherwise, reports an error.
89 pub fn define
<T
>(&mut self, parent
: Module
<'a
>, ident
: Ident
, ns
: Namespace
, def
: T
)
90 where T
: ToNameBinding
<'a
>,
92 let binding
= def
.to_name_binding(self.arenas
);
93 if let Err(old_binding
) = self.try_define(parent
, ident
, ns
, binding
) {
94 self.report_conflict(parent
, ident
, ns
, old_binding
, &binding
);
98 fn block_needs_anonymous_module(&mut self, block
: &Block
) -> bool
{
99 // If any statements are items, we need to create an anonymous module
100 block
.stmts
.iter().any(|statement
| match statement
.node
{
101 StmtKind
::Item(_
) | StmtKind
::Mac(_
) => true,
106 fn insert_field_names(&mut self, def_id
: DefId
, field_names
: Vec
<Name
>) {
107 if !field_names
.is_empty() {
108 self.field_names
.insert(def_id
, field_names
);
112 fn build_reduced_graph_for_use_tree(
114 // This particular use tree
115 use_tree
: &ast
::UseTree
,
117 parent_prefix
: &[Segment
],
119 // The whole `use` item
120 parent_scope
: ParentScope
<'a
>,
125 debug
!("build_reduced_graph_for_use_tree(parent_prefix={:?}, use_tree={:?}, nested={})",
126 parent_prefix
, use_tree
, nested
);
128 let mut prefix_iter
= parent_prefix
.iter().cloned()
129 .chain(use_tree
.prefix
.segments
.iter().map(|seg
| seg
.into())).peekable();
131 // On 2015 edition imports are resolved as crate-relative by default,
132 // so prefixes are prepended with crate root segment if necessary.
133 // The root is prepended lazily, when the first non-empty prefix or terminating glob
134 // appears, so imports in braced groups can have roots prepended independently.
135 // 2015 identifiers used on global 2018 edition enter special "virtual 2015 mode", don't
136 // get crate root prepended, but get special treatment during in-scope resolution instead.
137 let is_glob
= if let ast
::UseTreeKind
::Glob
= use_tree
.kind { true }
else { false }
;
138 let crate_root
= match prefix_iter
.peek() {
139 Some(seg
) if !seg
.ident
.is_path_segment_keyword() &&
140 seg
.ident
.span
.rust_2015() && self.session
.rust_2015() => {
141 Some(seg
.ident
.span
.ctxt())
143 None
if is_glob
&& use_tree
.span
.rust_2015() => {
144 Some(use_tree
.span
.ctxt())
147 }.map(|ctxt
| Segment
::from_ident(Ident
::new(
148 keywords
::CrateRoot
.name(), use_tree
.prefix
.span
.shrink_to_lo().with_ctxt(ctxt
)
151 let prefix
= crate_root
.into_iter().chain(prefix_iter
).collect
::<Vec
<_
>>();
152 debug
!("build_reduced_graph_for_use_tree: prefix={:?}", prefix
);
154 let empty_for_self
= |prefix
: &[Segment
]| {
156 prefix
.len() == 1 && prefix
[0].ident
.name
== keywords
::CrateRoot
.name()
158 match use_tree
.kind
{
159 ast
::UseTreeKind
::Simple(rename
, ..) => {
160 let mut ident
= use_tree
.ident();
161 let mut module_path
= prefix
;
162 let mut source
= module_path
.pop().unwrap();
163 let mut type_ns_only
= false;
166 // Correctly handle `self`
167 if source
.ident
.name
== keywords
::SelfValue
.name() {
170 if empty_for_self(&module_path
) {
175 SelfImportOnlyInImportListWithNonEmptyPrefix
180 // Replace `use foo::self;` with `use foo;`
181 source
= module_path
.pop().unwrap();
182 if rename
.is_none() {
183 ident
= source
.ident
;
188 if source
.ident
.name
== keywords
::SelfValue
.name() {
191 ResolutionError
::SelfImportsOnlyAllowedWithin
);
194 // Disallow `use $crate;`
195 if source
.ident
.name
== keywords
::DollarCrate
.name() && module_path
.is_empty() {
196 let crate_root
= self.resolve_crate_root(source
.ident
);
197 let crate_name
= match crate_root
.kind
{
198 ModuleKind
::Def(_
, name
) => name
,
199 ModuleKind
::Block(..) => unreachable
!(),
201 // HACK(eddyb) unclear how good this is, but keeping `$crate`
202 // in `source` breaks `src/test/compile-fail/import-crate-var.rs`,
203 // while the current crate doesn't have a valid `crate_name`.
204 if crate_name
!= keywords
::Invalid
.name() {
205 // `crate_name` should not be interpreted as relative.
206 module_path
.push(Segment
{
208 name
: keywords
::CrateRoot
.name(),
209 span
: source
.ident
.span
,
211 id
: Some(self.session
.next_node_id()),
213 source
.ident
.name
= crate_name
;
215 if rename
.is_none() {
216 ident
.name
= crate_name
;
219 self.session
.struct_span_warn(item
.span
, "`$crate` may not be imported")
220 .note("`use $crate;` was erroneously allowed and \
221 will become a hard error in a future release")
226 if ident
.name
== keywords
::Crate
.name() {
227 self.session
.span_err(ident
.span
,
228 "crate root imports need to be explicitly named: \
229 `use crate as name;`");
232 let subclass
= SingleImport
{
234 source
: source
.ident
,
236 type_ns
: Cell
::new(Err(Undetermined
)),
237 value_ns
: Cell
::new(Err(Undetermined
)),
238 macro_ns
: Cell
::new(Err(Undetermined
)),
242 self.add_import_directive(
253 ast
::UseTreeKind
::Glob
=> {
254 let subclass
= GlobImport
{
255 is_prelude
: attr
::contains_name(&item
.attrs
, "prelude_import"),
256 max_vis
: Cell
::new(ty
::Visibility
::Invisible
),
258 self.add_import_directive(
269 ast
::UseTreeKind
::Nested(ref items
) => {
270 // Ensure there is at most one `self` in the list
271 let self_spans
= items
.iter().filter_map(|&(ref use_tree
, _
)| {
272 if let ast
::UseTreeKind
::Simple(..) = use_tree
.kind
{
273 if use_tree
.ident().name
== keywords
::SelfValue
.name() {
274 return Some(use_tree
.span
);
279 }).collect
::<Vec
<_
>>();
280 if self_spans
.len() > 1 {
281 let mut e
= resolve_struct_error(self,
283 ResolutionError
::SelfImportCanOnlyAppearOnceInTheList
);
285 for other_span
in self_spans
.iter().skip(1) {
286 e
.span_label(*other_span
, "another `self` import appears here");
292 for &(ref tree
, id
) in items
{
293 self.build_reduced_graph_for_use_tree(
294 // This particular use tree
295 tree
, id
, &prefix
, true,
296 // The whole `use` item
297 parent_scope
.clone(), item
, vis
, root_span
,
301 // Empty groups `a::b::{}` are turned into synthetic `self` imports
302 // `a::b::c::{self as _}`, so that their prefixes are correctly
303 // resolved and checked for privacy/stability/etc.
304 if items
.is_empty() && !empty_for_self(&prefix
) {
305 let new_span
= prefix
[prefix
.len() - 1].ident
.span
;
306 let tree
= ast
::UseTree
{
307 prefix
: ast
::Path
::from_ident(
308 Ident
::new(keywords
::SelfValue
.name(), new_span
)
310 kind
: ast
::UseTreeKind
::Simple(
311 Some(Ident
::new(keywords
::Underscore
.name().gensymed(), new_span
)),
317 self.build_reduced_graph_for_use_tree(
318 // This particular use tree
319 &tree
, id
, &prefix
, true,
320 // The whole `use` item
321 parent_scope
.clone(), item
, ty
::Visibility
::Invisible
, root_span
,
328 /// Constructs the reduced graph for one item.
329 fn build_reduced_graph_for_item(&mut self, item
: &Item
, parent_scope
: ParentScope
<'a
>) {
330 let parent
= parent_scope
.module
;
331 let expansion
= parent_scope
.expansion
;
332 let ident
= item
.ident
;
334 let vis
= self.resolve_visibility(&item
.vis
);
337 ItemKind
::Use(ref use_tree
) => {
338 self.build_reduced_graph_for_use_tree(
339 // This particular use tree
340 use_tree
, item
.id
, &[], false,
341 // The whole `use` item
342 parent_scope
, item
, vis
, use_tree
.span
,
346 ItemKind
::ExternCrate(orig_name
) => {
347 let crate_id
= self.crate_loader
.process_extern_crate(item
, &self.definitions
);
349 self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }
);
350 self.populate_module_if_necessary(module
);
351 if injected_crate_name().map_or(false, |name
| ident
.name
== name
) {
352 self.injected_crate
= Some(module
);
355 let used
= self.process_legacy_macro_imports(item
, module
, &parent_scope
);
357 (module
, ty
::Visibility
::Public
, sp
, expansion
).to_name_binding(self.arenas
);
358 let directive
= self.arenas
.alloc_import_directive(ImportDirective
{
362 imported_module
: Cell
::new(Some(ModuleOrUniformRoot
::Module(module
))),
363 subclass
: ImportDirectiveSubclass
::ExternCrate
{
367 root_span
: item
.span
,
369 module_path
: Vec
::new(),
371 used
: Cell
::new(used
),
373 self.potentially_unused_imports
.push(directive
);
374 let imported_binding
= self.import(binding
, directive
);
375 if ptr
::eq(self.current_module
, self.graph_root
) {
376 if let Some(entry
) = self.extern_prelude
.get(&ident
.modern()) {
377 if expansion
!= Mark
::root() && orig_name
.is_some() &&
378 entry
.extern_crate_item
.is_none() {
379 self.session
.span_err(item
.span
, "macro-expanded `extern crate` items \
380 cannot shadow names passed with \
384 let entry
= self.extern_prelude
.entry(ident
.modern())
385 .or_insert(ExternPreludeEntry
{
386 extern_crate_item
: None
,
387 introduced_by_item
: true,
389 entry
.extern_crate_item
= Some(imported_binding
);
390 if orig_name
.is_some() {
391 entry
.introduced_by_item
= true;
394 self.define(parent
, ident
, TypeNS
, imported_binding
);
397 ItemKind
::GlobalAsm(..) => {}
399 ItemKind
::Mod(..) if ident
== keywords
::Invalid
.ident() => {}
// Crate root
401 ItemKind
::Mod(..) => {
402 let def_id
= self.definitions
.local_def_id(item
.id
);
403 let module_kind
= ModuleKind
::Def(Def
::Mod(def_id
), ident
.name
);
404 let module
= self.arenas
.alloc_module(ModuleData
{
405 no_implicit_prelude
: parent
.no_implicit_prelude
|| {
406 attr
::contains_name(&item
.attrs
, "no_implicit_prelude")
408 ..ModuleData
::new(Some(parent
), module_kind
, def_id
, expansion
, item
.span
)
410 self.define(parent
, ident
, TypeNS
, (module
, vis
, sp
, expansion
));
411 self.module_map
.insert(def_id
, module
);
413 // Descend into the module.
414 self.current_module
= module
;
417 // Handled in `rustc_metadata::{native_libs,link_args}`
418 ItemKind
::ForeignMod(..) => {}
420 // These items live in the value namespace.
421 ItemKind
::Static(_
, m
, _
) => {
422 let mutbl
= m
== Mutability
::Mutable
;
423 let def
= Def
::Static(self.definitions
.local_def_id(item
.id
), mutbl
);
424 self.define(parent
, ident
, ValueNS
, (def
, vis
, sp
, expansion
));
426 ItemKind
::Const(..) => {
427 let def
= Def
::Const(self.definitions
.local_def_id(item
.id
));
428 self.define(parent
, ident
, ValueNS
, (def
, vis
, sp
, expansion
));
430 ItemKind
::Fn(..) => {
431 let def
= Def
::Fn(self.definitions
.local_def_id(item
.id
));
432 self.define(parent
, ident
, ValueNS
, (def
, vis
, sp
, expansion
));
434 // Functions introducing procedural macros reserve a slot
435 // in the macro namespace as well (see #52225).
436 if attr
::contains_name(&item
.attrs
, "proc_macro") ||
437 attr
::contains_name(&item
.attrs
, "proc_macro_attribute") {
438 let def
= Def
::Macro(def
.def_id(), MacroKind
::ProcMacroStub
);
439 self.define(parent
, ident
, MacroNS
, (def
, vis
, sp
, expansion
));
441 if let Some(attr
) = attr
::find_by_name(&item
.attrs
, "proc_macro_derive") {
442 if let Some(trait_attr
) =
443 attr
.meta_item_list().and_then(|list
| list
.get(0).cloned()) {
444 if let Some(ident
) = trait_attr
.name().map(Ident
::with_empty_ctxt
) {
445 let sp
= trait_attr
.span
;
446 let def
= Def
::Macro(def
.def_id(), MacroKind
::ProcMacroStub
);
447 self.define(parent
, ident
, MacroNS
, (def
, vis
, sp
, expansion
));
453 // These items live in the type namespace.
454 ItemKind
::Ty(..) => {
455 let def
= Def
::TyAlias(self.definitions
.local_def_id(item
.id
));
456 self.define(parent
, ident
, TypeNS
, (def
, vis
, sp
, expansion
));
459 ItemKind
::Existential(_
, _
) => {
460 let def
= Def
::Existential(self.definitions
.local_def_id(item
.id
));
461 self.define(parent
, ident
, TypeNS
, (def
, vis
, sp
, expansion
));
464 ItemKind
::Enum(ref enum_definition
, _
) => {
465 let def
= Def
::Enum(self.definitions
.local_def_id(item
.id
));
466 let module_kind
= ModuleKind
::Def(def
, ident
.name
);
467 let module
= self.new_module(parent
,
469 parent
.normal_ancestor_id
,
472 self.define(parent
, ident
, TypeNS
, (module
, vis
, sp
, expansion
));
474 for variant
in &(*enum_definition
).variants
{
475 self.build_reduced_graph_for_variant(variant
, module
, vis
, expansion
);
479 ItemKind
::TraitAlias(..) => {
480 let def
= Def
::TraitAlias(self.definitions
.local_def_id(item
.id
));
481 self.define(parent
, ident
, TypeNS
, (def
, vis
, sp
, expansion
));
484 // These items live in both the type and value namespaces.
485 ItemKind
::Struct(ref struct_def
, _
) => {
486 // Define a name in the type namespace.
487 let def_id
= self.definitions
.local_def_id(item
.id
);
488 let def
= Def
::Struct(def_id
);
489 self.define(parent
, ident
, TypeNS
, (def
, vis
, sp
, expansion
));
491 let mut ctor_vis
= vis
;
493 let has_non_exhaustive
= attr
::contains_name(&item
.attrs
, "non_exhaustive");
495 // If the structure is marked as non_exhaustive then lower the visibility
496 // to within the crate.
497 if has_non_exhaustive
&& vis
== ty
::Visibility
::Public
{
498 ctor_vis
= ty
::Visibility
::Restricted(DefId
::local(CRATE_DEF_INDEX
));
501 // Record field names for error reporting.
502 let field_names
= struct_def
.fields().iter().filter_map(|field
| {
503 let field_vis
= self.resolve_visibility(&field
.vis
);
504 if ctor_vis
.is_at_least(field_vis
, &*self) {
505 ctor_vis
= field_vis
;
507 field
.ident
.map(|ident
| ident
.name
)
509 let item_def_id
= self.definitions
.local_def_id(item
.id
);
510 self.insert_field_names(item_def_id
, field_names
);
512 // If this is a tuple or unit struct, define a name
513 // in the value namespace as well.
514 if !struct_def
.is_struct() {
515 let ctor_def
= Def
::StructCtor(self.definitions
.local_def_id(struct_def
.id()),
516 CtorKind
::from_ast(struct_def
));
517 self.define(parent
, ident
, ValueNS
, (ctor_def
, ctor_vis
, sp
, expansion
));
518 self.struct_constructors
.insert(def
.def_id(), (ctor_def
, ctor_vis
));
522 ItemKind
::Union(ref vdata
, _
) => {
523 let def
= Def
::Union(self.definitions
.local_def_id(item
.id
));
524 self.define(parent
, ident
, TypeNS
, (def
, vis
, sp
, expansion
));
526 // Record field names for error reporting.
527 let field_names
= vdata
.fields().iter().filter_map(|field
| {
528 self.resolve_visibility(&field
.vis
);
529 field
.ident
.map(|ident
| ident
.name
)
531 let item_def_id
= self.definitions
.local_def_id(item
.id
);
532 self.insert_field_names(item_def_id
, field_names
);
535 ItemKind
::Impl(..) => {}
537 ItemKind
::Trait(..) => {
538 let def_id
= self.definitions
.local_def_id(item
.id
);
540 // Add all the items within to a new module.
541 let module_kind
= ModuleKind
::Def(Def
::Trait(def_id
), ident
.name
);
542 let module
= self.new_module(parent
,
544 parent
.normal_ancestor_id
,
547 self.define(parent
, ident
, TypeNS
, (module
, vis
, sp
, expansion
));
548 self.current_module
= module
;
551 ItemKind
::MacroDef(..) | ItemKind
::Mac(_
) => unreachable
!(),
555 // Constructs the reduced graph for one variant. Variants exist in the
556 // type and value namespaces.
557 fn build_reduced_graph_for_variant(&mut self,
562 let ident
= variant
.node
.ident
;
563 let def_id
= self.definitions
.local_def_id(variant
.node
.data
.id());
565 // Define a name in the type namespace.
566 let def
= Def
::Variant(def_id
);
567 self.define(parent
, ident
, TypeNS
, (def
, vis
, variant
.span
, expansion
));
569 // Define a constructor name in the value namespace.
570 // Braced variants, unlike structs, generate unusable names in
571 // value namespace, they are reserved for possible future use.
572 let ctor_kind
= CtorKind
::from_ast(&variant
.node
.data
);
573 let ctor_def
= Def
::VariantCtor(def_id
, ctor_kind
);
575 self.define(parent
, ident
, ValueNS
, (ctor_def
, vis
, variant
.span
, expansion
));
578 /// Constructs the reduced graph for one foreign item.
579 fn build_reduced_graph_for_foreign_item(&mut self, item
: &ForeignItem
, expansion
: Mark
) {
580 let (def
, ns
) = match item
.node
{
581 ForeignItemKind
::Fn(..) => {
582 (Def
::Fn(self.definitions
.local_def_id(item
.id
)), ValueNS
)
584 ForeignItemKind
::Static(_
, m
) => {
585 (Def
::Static(self.definitions
.local_def_id(item
.id
), m
), ValueNS
)
587 ForeignItemKind
::Ty
=> {
588 (Def
::ForeignTy(self.definitions
.local_def_id(item
.id
)), TypeNS
)
590 ForeignItemKind
::Macro(_
) => unreachable
!(),
592 let parent
= self.current_module
;
593 let vis
= self.resolve_visibility(&item
.vis
);
594 self.define(parent
, item
.ident
, ns
, (def
, vis
, item
.span
, expansion
));
597 fn build_reduced_graph_for_block(&mut self, block
: &Block
, expansion
: Mark
) {
598 let parent
= self.current_module
;
599 if self.block_needs_anonymous_module(block
) {
600 let module
= self.new_module(parent
,
601 ModuleKind
::Block(block
.id
),
602 parent
.normal_ancestor_id
,
605 self.block_map
.insert(block
.id
, module
);
606 self.current_module
= module
; // Descend into the block.
610 /// Builds the reduced graph for a single item in an external crate.
611 fn build_reduced_graph_for_external_crate_def(&mut self, parent
: Module
<'a
>, child
: Export
) {
612 let Export { ident, def, vis, span, .. }
= child
;
613 let def_id
= def
.def_id();
614 let expansion
= Mark
::root(); // FIXME(jseyfried) intercrate hygiene
616 Def
::Mod(..) | Def
::Enum(..) => {
617 let module
= self.new_module(parent
,
618 ModuleKind
::Def(def
, ident
.name
),
622 self.define(parent
, ident
, TypeNS
, (module
, vis
, DUMMY_SP
, expansion
));
624 Def
::Variant(..) | Def
::TyAlias(..) | Def
::ForeignTy(..) => {
625 self.define(parent
, ident
, TypeNS
, (def
, vis
, DUMMY_SP
, expansion
));
627 Def
::Fn(..) | Def
::Static(..) | Def
::Const(..) | Def
::VariantCtor(..) => {
628 self.define(parent
, ident
, ValueNS
, (def
, vis
, DUMMY_SP
, expansion
));
630 Def
::StructCtor(..) => {
631 self.define(parent
, ident
, ValueNS
, (def
, vis
, DUMMY_SP
, expansion
));
633 if let Some(struct_def_id
) =
634 self.cstore
.def_key(def_id
).parent
635 .map(|index
| DefId { krate: def_id.krate, index: index }
) {
636 self.struct_constructors
.insert(struct_def_id
, (def
, vis
));
640 let module_kind
= ModuleKind
::Def(def
, ident
.name
);
641 let module
= self.new_module(parent
,
643 parent
.normal_ancestor_id
,
646 self.define(parent
, ident
, TypeNS
, (module
, vis
, DUMMY_SP
, expansion
));
648 for child
in self.cstore
.item_children_untracked(def_id
, self.session
) {
649 let ns
= if let Def
::AssociatedTy(..) = child
.def { TypeNS }
else { ValueNS }
;
650 self.define(module
, child
.ident
, ns
,
651 (child
.def
, ty
::Visibility
::Public
, DUMMY_SP
, expansion
));
653 if self.cstore
.associated_item_cloned_untracked(child
.def
.def_id())
654 .method_has_self_argument
{
655 self.has_self
.insert(child
.def
.def_id());
658 module
.populated
.set(true);
660 Def
::Struct(..) | Def
::Union(..) => {
661 self.define(parent
, ident
, TypeNS
, (def
, vis
, DUMMY_SP
, expansion
));
663 // Record field names for error reporting.
664 let field_names
= self.cstore
.struct_field_names_untracked(def_id
);
665 self.insert_field_names(def_id
, field_names
);
668 self.define(parent
, ident
, MacroNS
, (def
, vis
, DUMMY_SP
, expansion
));
670 _
=> bug
!("unexpected definition: {:?}", def
)
674 pub fn get_module(&mut self, def_id
: DefId
) -> Module
<'a
> {
675 if def_id
.krate
== LOCAL_CRATE
{
676 return self.module_map
[&def_id
]
679 let macros_only
= self.cstore
.dep_kind_untracked(def_id
.krate
).macros_only();
680 if let Some(&module
) = self.extern_module_map
.get(&(def_id
, macros_only
)) {
684 let (name
, parent
) = if def_id
.index
== CRATE_DEF_INDEX
{
685 (self.cstore
.crate_name_untracked(def_id
.krate
).as_interned_str(), None
)
687 let def_key
= self.cstore
.def_key(def_id
);
688 (def_key
.disambiguated_data
.data
.get_opt_name().unwrap(),
689 Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id }
)))
692 let kind
= ModuleKind
::Def(Def
::Mod(def_id
), name
.as_symbol());
694 self.arenas
.alloc_module(ModuleData
::new(parent
, kind
, def_id
, Mark
::root(), DUMMY_SP
));
695 self.extern_module_map
.insert((def_id
, macros_only
), module
);
699 pub fn macro_def_scope(&mut self, expansion
: Mark
) -> Module
<'a
> {
700 let def_id
= self.macro_defs
[&expansion
];
701 if let Some(id
) = self.definitions
.as_local_node_id(def_id
) {
702 self.local_macro_def_scopes
[&id
]
703 } else if def_id
.krate
== CrateNum
::BuiltinMacros
{
704 self.injected_crate
.unwrap_or(self.graph_root
)
706 let module_def_id
= ty
::DefIdTree
::parent(&*self, def_id
).unwrap();
707 self.get_module(module_def_id
)
711 pub fn get_macro(&mut self, def
: Def
) -> Lrc
<SyntaxExtension
> {
712 let def_id
= match def
{
713 Def
::Macro(def_id
, ..) => def_id
,
714 Def
::NonMacroAttr(attr_kind
) => return Lrc
::new(SyntaxExtension
::NonMacroAttr
{
715 mark_used
: attr_kind
== NonMacroAttrKind
::Tool
,
717 _
=> panic
!("expected `Def::Macro` or `Def::NonMacroAttr`"),
719 if let Some(ext
) = self.macro_map
.get(&def_id
) {
723 let macro_def
= match self.cstore
.load_macro_untracked(def_id
, &self.session
) {
724 LoadedMacro
::MacroDef(macro_def
) => macro_def
,
725 LoadedMacro
::ProcMacro(ext
) => return ext
,
728 let ext
= Lrc
::new(macro_rules
::compile(&self.session
.parse_sess
,
729 &self.session
.features_untracked(),
731 self.cstore
.crate_edition_untracked(def_id
.krate
)));
732 self.macro_map
.insert(def_id
, ext
.clone());
736 /// Ensures that the reduced graph rooted at the given external module
737 /// is built, building it if it is not.
738 pub fn populate_module_if_necessary(&mut self, module
: Module
<'a
>) {
739 if module
.populated
.get() { return }
740 let def_id
= module
.def_id().unwrap();
741 for child
in self.cstore
.item_children_untracked(def_id
, self.session
) {
742 self.build_reduced_graph_for_external_crate_def(module
, child
);
744 module
.populated
.set(true)
747 fn legacy_import_macro(&mut self,
749 binding
: &'a NameBinding
<'a
>,
751 allow_shadowing
: bool
) {
752 if self.macro_use_prelude
.insert(name
, binding
).is_some() && !allow_shadowing
{
753 let msg
= format
!("`{}` is already in scope", name
);
755 "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";
756 self.session
.struct_span_err(span
, &msg
).note(note
).emit();
760 // This returns true if we should consider the underlying `extern crate` to be used.
761 fn process_legacy_macro_imports(&mut self, item
: &Item
, module
: Module
<'a
>,
762 parent_scope
: &ParentScope
<'a
>) -> bool
{
763 let mut import_all
= None
;
764 let mut single_imports
= Vec
::new();
765 for attr
in &item
.attrs
{
766 if attr
.check_name("macro_use") {
767 if self.current_module
.parent
.is_some() {
768 span_err
!(self.session
, item
.span
, E0468
,
769 "an `extern crate` loading macros must be at the crate root");
771 let ill_formed
= |span
| span_err
!(self.session
, span
, E0466
, "bad macro import");
773 Some(meta
) => match meta
.node
{
774 MetaItemKind
::Word
=> {
775 import_all
= Some(meta
.span
);
778 MetaItemKind
::List(nested_metas
) => for nested_meta
in nested_metas
{
779 match nested_meta
.word() {
780 Some(word
) => single_imports
.push((word
.name(), word
.span
)),
781 None
=> ill_formed(nested_meta
.span
),
784 MetaItemKind
::NameValue(..) => ill_formed(meta
.span
),
786 None
=> ill_formed(attr
.span()),
791 let arenas
= self.arenas
;
792 let macro_use_directive
= |span
| arenas
.alloc_import_directive(ImportDirective
{
795 parent_scope
: parent_scope
.clone(),
796 imported_module
: Cell
::new(Some(ModuleOrUniformRoot
::Module(module
))),
797 subclass
: ImportDirectiveSubclass
::MacroUse
,
800 module_path
: Vec
::new(),
801 vis
: Cell
::new(ty
::Visibility
::Restricted(DefId
::local(CRATE_DEF_INDEX
))),
802 used
: Cell
::new(false),
805 let allow_shadowing
= parent_scope
.expansion
== Mark
::root();
806 if let Some(span
) = import_all
{
807 let directive
= macro_use_directive(span
);
808 self.potentially_unused_imports
.push(directive
);
809 module
.for_each_child(|ident
, ns
, binding
| if ns
== MacroNS
{
810 let imported_binding
= self.import(binding
, directive
);
811 self.legacy_import_macro(ident
.name
, imported_binding
, span
, allow_shadowing
);
814 for (name
, span
) in single_imports
.iter().cloned() {
815 let ident
= Ident
::with_empty_ctxt(name
);
816 let result
= self.resolve_ident_in_module(
817 ModuleOrUniformRoot
::Module(module
),
824 if let Ok(binding
) = result
{
825 let directive
= macro_use_directive(span
);
826 self.potentially_unused_imports
.push(directive
);
827 let imported_binding
= self.import(binding
, directive
);
828 self.legacy_import_macro(name
, imported_binding
, span
, allow_shadowing
);
830 span_err
!(self.session
, span
, E0469
, "imported macro not found");
834 import_all
.is_some() || !single_imports
.is_empty()
837 // does this attribute list contain "macro_use"?
838 fn contains_macro_use(&mut self, attrs
: &[ast
::Attribute
]) -> bool
{
840 if attr
.check_name("macro_escape") {
841 let msg
= "macro_escape is a deprecated synonym for macro_use";
842 let mut err
= self.session
.struct_span_warn(attr
.span
, msg
);
843 if let ast
::AttrStyle
::Inner
= attr
.style
{
844 err
.help("consider an outer attribute, #[macro_use] mod ...").emit();
848 } else if !attr
.check_name("macro_use") {
853 self.session
.span_err(attr
.span
, "arguments to macro_use are not allowed here");
862 pub struct BuildReducedGraphVisitor
<'a
, 'b
: 'a
, 'c
: 'b
> {
863 pub resolver
: &'a
mut Resolver
<'b
, 'c
>,
864 pub current_legacy_scope
: LegacyScope
<'b
>,
868 impl<'a
, 'b
, 'cl
> BuildReducedGraphVisitor
<'a
, 'b
, 'cl
> {
869 fn visit_invoc(&mut self, id
: ast
::NodeId
) -> &'b InvocationData
<'b
> {
870 let mark
= id
.placeholder_to_mark();
871 self.resolver
.current_module
.unresolved_invocations
.borrow_mut().insert(mark
);
872 let invocation
= self.resolver
.invocations
[&mark
];
873 invocation
.module
.set(self.resolver
.current_module
);
874 invocation
.parent_legacy_scope
.set(self.current_legacy_scope
);
879 macro_rules
! method
{
880 ($visit
:ident
: $ty
:ty
, $invoc
:path
, $walk
:ident
) => {
881 fn $
visit(&mut self, node
: &'a $ty
) {
882 if let $
invoc(..) = node
.node
{
883 self.visit_invoc(node
.id
);
885 visit
::$
walk(self, node
);
891 impl<'a
, 'b
, 'cl
> Visitor
<'a
> for BuildReducedGraphVisitor
<'a
, 'b
, 'cl
> {
892 method
!(visit_impl_item
: ast
::ImplItem
, ast
::ImplItemKind
::Macro
, walk_impl_item
);
893 method
!(visit_expr
: ast
::Expr
, ast
::ExprKind
::Mac
, walk_expr
);
894 method
!(visit_pat
: ast
::Pat
, ast
::PatKind
::Mac
, walk_pat
);
895 method
!(visit_ty
: ast
::Ty
, ast
::TyKind
::Mac
, walk_ty
);
897 fn visit_item(&mut self, item
: &'a Item
) {
898 let macro_use
= match item
.node
{
899 ItemKind
::MacroDef(..) => {
900 self.resolver
.define_macro(item
, self.expansion
, &mut self.current_legacy_scope
);
903 ItemKind
::Mac(..) => {
904 self.current_legacy_scope
= LegacyScope
::Invocation(self.visit_invoc(item
.id
));
907 ItemKind
::Mod(..) => self.resolver
.contains_macro_use(&item
.attrs
),
911 let orig_current_module
= self.resolver
.current_module
;
912 let orig_current_legacy_scope
= self.current_legacy_scope
;
913 let parent_scope
= ParentScope
{
914 module
: self.resolver
.current_module
,
915 expansion
: self.expansion
,
916 legacy
: self.current_legacy_scope
,
919 self.resolver
.build_reduced_graph_for_item(item
, parent_scope
);
920 visit
::walk_item(self, item
);
921 self.resolver
.current_module
= orig_current_module
;
923 self.current_legacy_scope
= orig_current_legacy_scope
;
927 fn visit_stmt(&mut self, stmt
: &'a ast
::Stmt
) {
928 if let ast
::StmtKind
::Mac(..) = stmt
.node
{
929 self.current_legacy_scope
= LegacyScope
::Invocation(self.visit_invoc(stmt
.id
));
931 visit
::walk_stmt(self, stmt
);
935 fn visit_foreign_item(&mut self, foreign_item
: &'a ForeignItem
) {
936 if let ForeignItemKind
::Macro(_
) = foreign_item
.node
{
937 self.visit_invoc(foreign_item
.id
);
941 self.resolver
.build_reduced_graph_for_foreign_item(foreign_item
, self.expansion
);
942 visit
::walk_foreign_item(self, foreign_item
);
945 fn visit_block(&mut self, block
: &'a Block
) {
946 let orig_current_module
= self.resolver
.current_module
;
947 let orig_current_legacy_scope
= self.current_legacy_scope
;
948 self.resolver
.build_reduced_graph_for_block(block
, self.expansion
);
949 visit
::walk_block(self, block
);
950 self.resolver
.current_module
= orig_current_module
;
951 self.current_legacy_scope
= orig_current_legacy_scope
;
954 fn visit_trait_item(&mut self, item
: &'a TraitItem
) {
955 let parent
= self.resolver
.current_module
;
957 if let TraitItemKind
::Macro(_
) = item
.node
{
958 self.visit_invoc(item
.id
);
962 // Add the item to the trait info.
963 let item_def_id
= self.resolver
.definitions
.local_def_id(item
.id
);
964 let (def
, ns
) = match item
.node
{
965 TraitItemKind
::Const(..) => (Def
::AssociatedConst(item_def_id
), ValueNS
),
966 TraitItemKind
::Method(ref sig
, _
) => {
967 if sig
.decl
.has_self() {
968 self.resolver
.has_self
.insert(item_def_id
);
970 (Def
::Method(item_def_id
), ValueNS
)
972 TraitItemKind
::Type(..) => (Def
::AssociatedTy(item_def_id
), TypeNS
),
973 TraitItemKind
::Macro(_
) => bug
!(), // handled above
976 let vis
= ty
::Visibility
::Public
;
977 self.resolver
.define(parent
, item
.ident
, ns
, (def
, vis
, item
.span
, self.expansion
));
979 self.resolver
.current_module
= parent
.parent
.unwrap(); // nearest normal ancestor
980 visit
::walk_trait_item(self, item
);
981 self.resolver
.current_module
= parent
;
984 fn visit_token(&mut self, t
: Token
) {
985 if let Token
::Interpolated(nt
) = t
{
986 if let token
::NtExpr(ref expr
) = nt
.0 {
987 if let ast
::ExprKind
::Mac(..) = expr
.node
{
988 self.visit_invoc(expr
.id
);
994 fn visit_attribute(&mut self, attr
: &'a ast
::Attribute
) {
995 if !attr
.is_sugared_doc
&& is_builtin_attr(attr
) {
996 let parent_scope
= ParentScope
{
997 module
: self.resolver
.current_module
.nearest_item_scope(),
998 expansion
: self.expansion
,
999 legacy
: self.current_legacy_scope
,
1000 // Let's hope discerning built-in attributes from derive helpers is not necessary
1001 derives
: Vec
::new(),
1003 parent_scope
.module
.builtin_attrs
.borrow_mut().push((
1004 attr
.path
.segments
[0].ident
, parent_scope
1007 visit
::walk_attribute(self, attr
);