//! Here we build the "reduced graph": the graph of the module tree without
//! any imports resolved.
-use macros::{InvocationData, LegacyScope};
+use macros::{InvocationData, ParentScope, LegacyScope};
use resolve_imports::ImportDirective;
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, ToNameBinding};
-use {ModuleOrUniformRoot, PerNS, Resolver, ResolverArenas};
+use {ModuleOrUniformRoot, PerNS, Resolver, ResolverArenas, ExternPreludeEntry};
use Namespace::{self, TypeNS, ValueNS, MacroNS};
use {resolve_error, resolve_struct_error, ResolutionError};
use rustc::hir::def::*;
-use rustc::hir::def_id::{BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
+use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
use rustc::ty;
use rustc::middle::cstore::CrateStore;
use rustc_metadata::cstore::LoadedMacro;
use std::cell::Cell;
+use std::ptr;
use rustc_data_structures::sync::Lrc;
use syntax::ast::{Name, Ident};
let prefix_iter = || parent_prefix.iter().cloned()
.chain(use_tree.prefix.segments.iter().map(|seg| seg.ident));
- let prefix_start = prefix_iter().nth(0);
+ let prefix_start = prefix_iter().next();
let starts_with_non_keyword = prefix_start.map_or(false, |ident| {
!ident.is_path_segment_keyword()
});
let module =
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
self.populate_module_if_necessary(module);
- if injected_crate_name().map_or(false, |name| item.ident.name == name) {
+ if injected_crate_name().map_or(false, |name| ident.name == name) {
self.injected_crate = Some(module);
}
let used = self.process_legacy_macro_imports(item, module, expansion);
let binding =
(module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas);
+ if ptr::eq(self.current_module, self.graph_root) {
+ if let Some(entry) = self.extern_prelude.get(&ident.modern()) {
+ if expansion != Mark::root() && orig_name.is_some() &&
+ entry.extern_crate_item.is_none() {
+ self.session.span_err(item.span, "macro-expanded `extern crate` items \
+ cannot shadow names passed with \
+ `--extern`");
+ }
+ }
+ let entry = self.extern_prelude.entry(ident.modern())
+ .or_insert(ExternPreludeEntry {
+ extern_crate_item: None,
+ introduced_by_item: true,
+ });
+ entry.extern_crate_item = Some(binding);
+ if orig_name.is_some() {
+ entry.introduced_by_item = true;
+ }
+ }
let directive = self.arenas.alloc_import_directive(ImportDirective {
root_id: item.id,
id: item.id,
parent,
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
- subclass: ImportDirectiveSubclass::ExternCrate(orig_name),
+ subclass: ImportDirectiveSubclass::ExternCrate {
+ source: orig_name,
+ target: ident,
+ },
root_span: item.span,
span: item.span,
module_path: Vec::new(),
ItemKind::GlobalAsm(..) => {}
- ItemKind::Mod(..) if item.ident == keywords::Invalid.ident() => {} // Crate root
+ ItemKind::Mod(..) if ident == keywords::Invalid.ident() => {} // Crate root
ItemKind::Mod(..) => {
let def_id = self.definitions.local_def_id(item.id);
let def_id = self.macro_defs[&expansion];
if let Some(id) = self.definitions.as_local_node_id(def_id) {
self.local_macro_def_scopes[&id]
- } else if def_id.krate == BUILTIN_MACROS_CRATE {
+ } else if def_id.krate == CrateNum::BuiltinMacros {
self.injected_crate.unwrap_or(self.graph_root)
} else {
let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap();
fn visit_token(&mut self, t: Token) {
if let Token::Interpolated(nt) = t {
- match nt.0 {
- token::NtExpr(ref expr) => {
- if let ast::ExprKind::Mac(..) = expr.node {
- self.visit_invoc(expr.id);
- }
+ if let token::NtExpr(ref expr) = nt.0 {
+ if let ast::ExprKind::Mac(..) = expr.node {
+ self.visit_invoc(expr.id);
}
- _ => {}
}
}
}
fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
if !attr.is_sugared_doc && is_builtin_attr(attr) {
- self.resolver.current_module.builtin_attrs.borrow_mut().push((
- attr.path.segments[0].ident, self.expansion, self.current_legacy_scope
+ let parent_scope = ParentScope {
+ module: self.resolver.current_module.nearest_item_scope(),
+ expansion: self.expansion,
+ legacy: self.current_legacy_scope,
+ // Let's hope discerning built-in attributes from derive helpers is not necessary
+ derives: Vec::new(),
+ };
+ parent_scope.module.builtin_attrs.borrow_mut().push((
+ attr.path.segments[0].ident, parent_scope
));
}
visit::walk_attribute(self, attr);