]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_resolve/build_reduced_graph.rs
Prohibit macro-expanded `extern crate` items shadowing crates passed with `--extern`
[rust.git] / src / librustc_resolve / build_reduced_graph.rs
index 5222dd27d34d61b83f153eedc674cb0983685ea8..aa7bfeae5f48b034013c64a9e089fb4f80b5e52c 100644 (file)
@@ -17,7 +17,7 @@
 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};
 
@@ -28,6 +28,7 @@
 use rustc_metadata::cstore::LoadedMacro;
 
 use std::cell::Cell;
+use std::ptr;
 use rustc_data_structures::sync::Lrc;
 
 use syntax::ast::{Name, Ident};
@@ -437,13 +438,32 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
                 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,
@@ -468,7 +488,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
 
             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);