]> git.lizzy.rs Git - rust.git/commitdiff
Fix cross-crate resolution of half-items created by export shadowing
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Wed, 14 Sep 2016 21:51:46 +0000 (00:51 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Tue, 4 Oct 2016 19:20:37 +0000 (22:20 +0300)
15 files changed:
src/librustc/hir/def.rs
src/librustc_metadata/csearch.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_typeck/check/method/suggest.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/visit_lib.rs
src/test/compile-fail/auxiliary/namespace-mix-new.rs [new file with mode: 0644]
src/test/compile-fail/auxiliary/namespace-mix-old.rs [new file with mode: 0644]
src/test/compile-fail/namespace-mix-new.rs [new file with mode: 0644]
src/test/compile-fail/namespace-mix-old.rs [new file with mode: 0644]

index eede353de06aabf4c2087eaba492a512ddb361d5..94ce6e2f7f774b389d4be3fa987cd960831e1ec3 100644 (file)
@@ -100,8 +100,8 @@ pub fn kind_name(&self) -> &'static str {
 
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
 pub struct Export {
-    pub name: ast::Name,    // The name of the target.
-    pub def_id: DefId, // The definition of the target.
+    pub name: ast::Name, // The name of the target.
+    pub def: Def, // The definition of the target.
 }
 
 impl CtorKind {
index 16a5b5402fbe30fc431939cf614f5774dcf32bc1..10bafa4ee1d68d6de677c00159ce5ceb8c7650c7 100644 (file)
@@ -149,7 +149,7 @@ fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId> {
         self.dep_graph.read(DepNode::MetaData(def_id));
         let mut result = vec![];
         self.get_crate_data(def_id.krate)
-            .each_child_of_item(def_id.index, |child| result.push(child.def_id));
+            .each_child_of_item(def_id.index, |child| result.push(child.def.def_id()));
         result
     }
 
@@ -566,7 +566,7 @@ fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>
 
             let mut bfs_queue = &mut VecDeque::new();
             let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
-                let child = child.def_id;
+                let child = child.def.def_id();
 
                 if self.visibility(child) != ty::Visibility::Public {
                     return;
index 3e4a2542b270bc9f7b7bd3c22e56142b2f2dac21..59a33fcbbcdd5695a0e2afe41923cb70dc82c71a 100644 (file)
@@ -670,10 +670,12 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
                     // FIXME(eddyb) Don't encode these in children.
                     EntryKind::ForeignMod => {
                         for child_index in child.children.decode(self) {
-                            callback(def::Export {
-                                def_id: self.local_def_id(child_index),
-                                name: self.item_name(&self.entry(child_index))
-                            });
+                            if let Some(def) = self.get_def(child_index) {
+                                callback(def::Export {
+                                    def: def,
+                                    name: self.item_name(&self.entry(child_index))
+                                });
+                            }
                         }
                         continue;
                     }
@@ -683,11 +685,26 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
                 }
 
                 let def_key = child.def_key.decode(self);
-                if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
-                    callback(def::Export {
-                        def_id: self.local_def_id(child_index),
-                        name: name
-                    });
+                if let (Some(def), Some(name)) = (self.get_def(child_index),
+                                                  def_key.disambiguated_data.data.get_opt_name()) {
+                    callback(def::Export { def: def, name: name });
+                    // For non-reexport structs and variants add their constructors to children.
+                    // Reexport lists automatically contain constructors when necessary.
+                    match def {
+                        Def::Struct(..) => {
+                            if let Some(ctor_def_id) = self.get_struct_ctor_def_id(child_index) {
+                                let vkind = self.get_variant_kind(child_index).unwrap();
+                                let ctor_def = Def::StructCtor(ctor_def_id, vkind.ctor_kind());
+                                callback(def::Export { def: ctor_def, name: name });
+                            }
+                        }
+                        Def::Variant(def_id) => {
+                            let vkind = self.get_variant_kind(child_index).unwrap();
+                            let ctor_def = Def::VariantCtor(def_id, vkind.ctor_kind());
+                            callback(def::Export { def: ctor_def, name: name });
+                        }
+                        _ => {}
+                    }
                 }
             }
         }
index 4d18462848e5d84c6f1b5ea608b43fd3c6fb1f70..8774e55011ed6497fee15d430b0ff3b706f581d2 100644 (file)
@@ -406,7 +406,8 @@ fn encode_field(&mut self,
 
     fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId))
                           -> Entry<'tcx> {
-        let variant = self.tcx.lookup_adt_def(adt_def_id).struct_variant();
+        let tcx = self.tcx;
+        let variant = tcx.lookup_adt_def(adt_def_id).struct_variant();
 
         let data = VariantData {
             kind: variant.kind,
@@ -414,9 +415,12 @@ fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId))
             struct_ctor: Some(def_id.index)
         };
 
+        let struct_id = tcx.map.as_local_node_id(adt_def_id).unwrap();
+        let struct_vis = &tcx.map.expect_item(struct_id).vis;
+
         Entry {
             kind: EntryKind::Struct(self.lazy(&data)),
-            visibility: ty::Visibility::Public,
+            visibility: struct_vis.simplify(),
             def_key: self.encode_def_key(def_id),
             attributes: LazySeq::empty(),
             children: LazySeq::empty(),
index 6b2076cb0585cfc3fc6bd2799023270aed0a1145..a6a1326b719bfa841f827e4851792d016eae8ef6 100644 (file)
@@ -286,7 +286,7 @@ fn visit_mod(&mut self, m: &hir::Mod, _sp: Span, id: ast::NodeId) {
         if self.prev_level.is_some() {
             if let Some(exports) = self.export_map.get(&id) {
                 for export in exports {
-                    if let Some(node_id) = self.tcx.map.as_local_node_id(export.def_id) {
+                    if let Some(node_id) = self.tcx.map.as_local_node_id(export.def.def_id()) {
                         self.update(node_id, Some(AccessLevel::Exported));
                     }
                 }
index 1e53bb1b96325548982307eb00f481c2d1ccb90c..b6afacf05e2d0b43f8bc79688bb3703e94af0adb 100644 (file)
@@ -24,7 +24,6 @@
 use rustc::middle::cstore::LoadedMacroKind;
 use rustc::hir::def::*;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
-use rustc::hir::map::DefPathData;
 use rustc::ty;
 
 use std::cell::Cell;
@@ -398,15 +397,9 @@ fn build_reduced_graph_for_block(&mut self, block: &Block) {
     /// Builds the reduced graph for a single item in an external crate.
     fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>,
                                                   child: Export) {
-        let def_id = child.def_id;
         let name = child.name;
-
-        let def = if let Some(def) = self.session.cstore.describe_def(def_id) {
-            def
-        } else {
-            return;
-        };
-
+        let def = child.def;
+        let def_id = def.def_id();
         let vis = if parent.is_trait() {
             ty::Visibility::Public
         } else {
@@ -424,14 +417,15 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>,
                 debug!("(building reduced graph for external crate) building variant {}", name);
                 // All variants are defined in both type and value namespaces as future-proofing.
                 let vkind = self.session.cstore.variant_kind(def_id).unwrap();
-                let ctor_def = Def::VariantCtor(def_id, vkind.ctor_kind());
                 let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
-                let _ = self.try_define(parent, name, ValueNS, (ctor_def, DUMMY_SP, vis));
                 if vkind == ty::VariantKind::Struct {
                     // Not adding fields for variants as they are not accessed with a self receiver
                     self.structs.insert(def_id, Vec::new());
                 }
             }
+            Def::VariantCtor(..) => {
+                let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
+            }
             Def::Fn(..) |
             Def::Static(..) |
             Def::Const(..) |
@@ -468,23 +462,18 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>,
                 debug!("(building reduced graph for external crate) building type {}", name);
                 let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
             }
-            Def::Struct(..)
-                if self.session.cstore.def_key(def_id).disambiguated_data.data !=
-                   DefPathData::StructCtor
-                => {
+            Def::Struct(..) => {
                 debug!("(building reduced graph for external crate) building type and value for {}",
                        name);
                 let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
-                if let Some(ctor_def_id) = self.session.cstore.struct_ctor_def_id(def_id) {
-                    let vkind = self.session.cstore.variant_kind(def_id).unwrap();
-                    let ctor_def = Def::StructCtor(ctor_def_id, vkind.ctor_kind());
-                    let _ = self.try_define(parent, name, ValueNS, (ctor_def, DUMMY_SP, vis));
-                }
 
                 // Record the def ID and fields of this struct.
                 let fields = self.session.cstore.struct_field_names(def_id);
                 self.structs.insert(def_id, fields);
             }
+            Def::StructCtor(..) => {
+                let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
+            }
             Def::Union(_) => {
                 let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
 
@@ -492,9 +481,6 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>,
                 let fields = self.session.cstore.struct_field_names(def_id);
                 self.structs.insert(def_id, fields);
             }
-            Def::Struct(..) => {}
-            Def::VariantCtor(..) |
-            Def::StructCtor(..) |
             Def::Local(..) |
             Def::PrimTy(..) |
             Def::TyParam(..) |
index 1fc9c45de930647b9021aa88e75f6e6749819451..4689c4ded5c0a4aaec56e47266575f531eb4d4ee 100644 (file)
@@ -797,7 +797,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
                (binding.is_import() || binding.is_extern_crate()) {
                 let def = binding.def();
                 if def != Def::Err {
-                    reexports.push(Export { name: name, def_id: def.def_id() });
+                    reexports.push(Export { name: name, def: def });
                 }
             }
 
index 34bcd2ba046e91cbaaa967be0b26e5d3fb9e39b2..4fd1341f09b727f62ee33f6605252b1754320e5f 100644 (file)
@@ -461,7 +461,7 @@ fn handle_external_def(ccx: &CrateCtxt,
                         return;
                     }
                     for child in ccx.tcx.sess.cstore.item_children(def_id) {
-                        handle_external_def(ccx, traits, external_mods, child.def_id)
+                        handle_external_def(ccx, traits, external_mods, child.def.def_id())
                     }
                 }
                 _ => {}
index 208a5d810922aa62a725b7f37446e37a20d108e1..68bc5d57e7b4d65c73887ed657f08409b9b74094 100644 (file)
@@ -498,9 +498,10 @@ fn fill_in<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
         // visit each node at most once.
         let mut visited = FnvHashSet();
         for item in tcx.sess.cstore.item_children(did) {
-            if tcx.sess.cstore.visibility(item.def_id) == ty::Visibility::Public {
-                if !visited.insert(item.def_id) { continue }
-                if let Some(def) = tcx.sess.cstore.describe_def(item.def_id) {
+            let def_id = item.def.def_id();
+            if tcx.sess.cstore.visibility(def_id) == ty::Visibility::Public {
+                if !visited.insert(def_id) { continue }
+                if let Some(def) = tcx.sess.cstore.describe_def(def_id) {
                     if let Some(i) = try_inline_def(cx, tcx, def) {
                         items.extend(i)
                     }
index cf20572510b5c81eb49cda40bc89cf369976d6da..3a13e17d293d7977115c147c2466a03fb2b8c625 100644 (file)
@@ -237,7 +237,7 @@ fn clean(&self, cx: &DocContext) -> ExternalCrate {
         let root = DefId { krate: self.0, index: CRATE_DEF_INDEX };
         cx.tcx_opt().map(|tcx| {
             for item in tcx.sess.cstore.item_children(root) {
-                let attrs = inline::load_attrs(cx, tcx, item.def_id);
+                let attrs = inline::load_attrs(cx, tcx, item.def.def_id());
                 PrimitiveType::find(&attrs).map(|prim| primitives.push(prim));
             }
         });
index 285b47fe60abf54290b11a5ddf90ba420c7db9c4..1e262bb490635074f1858128a0f83440d8ef96f0 100644 (file)
@@ -66,7 +66,7 @@ fn update(&mut self, did: DefId, level: Option<AccessLevel>) -> Option<AccessLev
 
     pub fn visit_mod(&mut self, def_id: DefId) {
         for item in self.cstore.item_children(def_id) {
-            self.visit_item(item.def_id);
+            self.visit_item(item.def.def_id());
         }
     }
 
diff --git a/src/test/compile-fail/auxiliary/namespace-mix-new.rs b/src/test/compile-fail/auxiliary/namespace-mix-new.rs
new file mode 100644 (file)
index 0000000..88e8b0d
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(item_like_imports, relaxed_adts)]
+
+pub mod c {
+    pub struct S {}
+    pub struct TS();
+    pub struct US;
+    pub enum E {
+        V {},
+        TV(),
+        UV,
+    }
+
+    pub struct Item;
+}
+
+pub mod xm1 {
+    pub use ::c::*;
+    pub type S = ::c::Item;
+}
+pub mod xm2 {
+    pub use ::c::*;
+    pub const S: ::c::Item = ::c::Item;
+}
+
+pub mod xm3 {
+    pub use ::c::*;
+    pub type TS = ::c::Item;
+}
+pub mod xm4 {
+    pub use ::c::*;
+    pub const TS: ::c::Item = ::c::Item;
+}
+
+pub mod xm5 {
+    pub use ::c::*;
+    pub type US = ::c::Item;
+}
+pub mod xm6 {
+    pub use ::c::*;
+    pub const US: ::c::Item = ::c::Item;
+}
+
+pub mod xm7 {
+    pub use ::c::E::*;
+    pub type V = ::c::Item;
+}
+pub mod xm8 {
+    pub use ::c::E::*;
+    pub const V: ::c::Item = ::c::Item;
+}
+
+pub mod xm9 {
+    pub use ::c::E::*;
+    pub type TV = ::c::Item;
+}
+pub mod xmA {
+    pub use ::c::E::*;
+    pub const TV: ::c::Item = ::c::Item;
+}
+
+pub mod xmB {
+    pub use ::c::E::*;
+    pub type UV = ::c::Item;
+}
+pub mod xmC {
+    pub use ::c::E::*;
+    pub const UV: ::c::Item = ::c::Item;
+}
diff --git a/src/test/compile-fail/auxiliary/namespace-mix-old.rs b/src/test/compile-fail/auxiliary/namespace-mix-old.rs
new file mode 100644 (file)
index 0000000..7bbba71
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// FIXME: Remove when `item_like_imports` is stabilized.
+
+#![feature(relaxed_adts)]
+
+pub mod c {
+    pub struct S {}
+    pub struct TS();
+    pub struct US;
+    pub enum E {
+        V {},
+        TV(),
+        UV,
+    }
+
+    pub struct Item;
+}
+
+pub mod proxy {
+    pub use c::*;
+    pub use c::E::*;
+}
+
+pub mod xm1 {
+    pub use ::proxy::*;
+    pub type S = ::c::Item;
+}
+pub mod xm2 {
+    pub use ::proxy::*;
+    pub const S: ::c::Item = ::c::Item;
+}
+
+pub mod xm3 {
+    pub use ::proxy::*;
+    pub type TS = ::c::Item;
+}
+pub mod xm4 {
+    pub use ::proxy::*;
+    pub const TS: ::c::Item = ::c::Item;
+}
+
+pub mod xm5 {
+    pub use ::proxy::*;
+    pub type US = ::c::Item;
+}
+pub mod xm6 {
+    pub use ::proxy::*;
+    pub const US: ::c::Item = ::c::Item;
+}
+
+pub mod xm7 {
+    pub use ::proxy::*;
+    pub type V = ::c::Item;
+}
+pub mod xm8 {
+    pub use ::proxy::*;
+    pub const V: ::c::Item = ::c::Item;
+}
+
+pub mod xm9 {
+    pub use ::proxy::*;
+    pub type TV = ::c::Item;
+}
+pub mod xmA {
+    pub use ::proxy::*;
+    pub const TV: ::c::Item = ::c::Item;
+}
+
+pub mod xmB {
+    pub use ::proxy::*;
+    pub type UV = ::c::Item;
+}
+pub mod xmC {
+    pub use ::proxy::*;
+    pub const UV: ::c::Item = ::c::Item;
+}
diff --git a/src/test/compile-fail/namespace-mix-new.rs b/src/test/compile-fail/namespace-mix-new.rs
new file mode 100644 (file)
index 0000000..0abe8bd
--- /dev/null
@@ -0,0 +1,167 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:namespace-mix-new.rs
+
+#![feature(item_like_imports, relaxed_adts)]
+
+extern crate namespace_mix_new;
+use namespace_mix_new::*;
+
+mod c {
+    pub struct S {}
+    pub struct TS();
+    pub struct US;
+    pub enum E {
+        V {},
+        TV(),
+        UV,
+    }
+
+    pub struct Item;
+}
+
+// Use something emitting the type argument name, e.g. unsatisfied bound.
+trait Impossible {}
+fn check<T: Impossible>(_: T) {}
+
+mod m1 {
+    pub use ::c::*;
+    pub type S = ::c::Item;
+}
+mod m2 {
+    pub use ::c::*;
+    pub const S: ::c::Item = ::c::Item;
+}
+
+fn f12() {
+    check(m1::S{}); //~ ERROR c::Item
+    check(m1::S); //~ ERROR unresolved name
+    check(m2::S{}); //~ ERROR c::S
+    check(m2::S); //~ ERROR c::Item
+}
+fn xf12() {
+    check(xm1::S{}); //~ ERROR c::Item
+    check(xm1::S); //~ ERROR unresolved name
+    check(xm2::S{}); //~ ERROR c::S
+    check(xm2::S); //~ ERROR c::Item
+}
+
+mod m3 {
+    pub use ::c::*;
+    pub type TS = ::c::Item;
+}
+mod m4 {
+    pub use ::c::*;
+    pub const TS: ::c::Item = ::c::Item;
+}
+
+fn f34() {
+    check(m3::TS{}); //~ ERROR c::Item
+    check(m3::TS); //~ ERROR c::TS
+    check(m4::TS{}); //~ ERROR c::TS
+    check(m4::TS); //~ ERROR c::Item
+}
+fn xf34() {
+    check(xm3::TS{}); //~ ERROR c::Item
+    check(xm3::TS); //~ ERROR c::TS
+    check(xm4::TS{}); //~ ERROR c::TS
+    check(xm4::TS); //~ ERROR c::Item
+}
+
+mod m5 {
+    pub use ::c::*;
+    pub type US = ::c::Item;
+}
+mod m6 {
+    pub use ::c::*;
+    pub const US: ::c::Item = ::c::Item;
+}
+
+fn f56() {
+    check(m5::US{}); //~ ERROR c::Item
+    check(m5::US); //~ ERROR c::US
+    check(m6::US{}); //~ ERROR c::US
+    check(m6::US); //~ ERROR c::Item
+}
+fn xf56() {
+    check(xm5::US{}); //~ ERROR c::Item
+    check(xm5::US); //~ ERROR c::US
+    check(xm6::US{}); //~ ERROR c::US
+    check(xm6::US); //~ ERROR c::Item
+}
+
+mod m7 {
+    pub use ::c::E::*;
+    pub type V = ::c::Item;
+}
+mod m8 {
+    pub use ::c::E::*;
+    pub const V: ::c::Item = ::c::Item;
+}
+
+fn f78() {
+    check(m7::V{}); //~ ERROR c::Item
+    check(m7::V); //~ ERROR name of a struct or struct variant
+    check(m8::V{}); //~ ERROR c::E
+    check(m8::V); //~ ERROR c::Item
+}
+fn xf78() {
+    check(xm7::V{}); //~ ERROR c::Item
+    check(xm7::V); //~ ERROR name of a struct or struct variant
+    check(xm8::V{}); //~ ERROR c::E
+    check(xm8::V); //~ ERROR c::Item
+}
+
+mod m9 {
+    pub use ::c::E::*;
+    pub type TV = ::c::Item;
+}
+mod mA {
+    pub use ::c::E::*;
+    pub const TV: ::c::Item = ::c::Item;
+}
+
+fn f9A() {
+    check(m9::TV{}); //~ ERROR c::Item
+    check(m9::TV); //~ ERROR c::E
+    check(mA::TV{}); //~ ERROR c::E
+    check(mA::TV); //~ ERROR c::Item
+}
+fn xf9A() {
+    check(xm9::TV{}); //~ ERROR c::Item
+    check(xm9::TV); //~ ERROR c::E
+    check(xmA::TV{}); //~ ERROR c::E
+    check(xmA::TV); //~ ERROR c::Item
+}
+
+mod mB {
+    pub use ::c::E::*;
+    pub type UV = ::c::Item;
+}
+mod mC {
+    pub use ::c::E::*;
+    pub const UV: ::c::Item = ::c::Item;
+}
+
+fn fBC() {
+    check(mB::UV{}); //~ ERROR c::Item
+    check(mB::UV); //~ ERROR c::E
+    check(mC::UV{}); //~ ERROR c::E
+    check(mC::UV); //~ ERROR c::Item
+}
+fn xfBC() {
+    check(xmB::UV{}); //~ ERROR c::Item
+    check(xmB::UV); //~ ERROR c::E
+    check(xmC::UV{}); //~ ERROR c::E
+    check(xmC::UV); //~ ERROR c::Item
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/namespace-mix-old.rs b/src/test/compile-fail/namespace-mix-old.rs
new file mode 100644 (file)
index 0000000..ad67664
--- /dev/null
@@ -0,0 +1,174 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// FIXME: Remove when `item_like_imports` is stabilized.
+
+// aux-build:namespace-mix-old.rs
+
+#![feature(relaxed_adts)]
+
+extern crate namespace_mix_old;
+use namespace_mix_old::{xm1, xm2, xm3, xm4, xm5, xm6, xm7, xm8, xm9, xmA, xmB, xmC};
+
+mod c {
+    pub struct S {}
+    pub struct TS();
+    pub struct US;
+    pub enum E {
+        V {},
+        TV(),
+        UV,
+    }
+
+    pub struct Item;
+}
+
+mod proxy {
+    pub use c::*;
+    pub use c::E::*;
+}
+
+// Use something emitting the type argument name, e.g. unsatisfied bound.
+trait Impossible {}
+fn check<T: Impossible>(_: T) {}
+
+mod m1 {
+    pub use ::proxy::*;
+    pub type S = ::c::Item;
+}
+mod m2 {
+    pub use ::proxy::*;
+    pub const S: ::c::Item = ::c::Item;
+}
+
+fn f12() {
+    check(m1::S{}); //~ ERROR c::Item
+    check(m1::S); //~ ERROR unresolved name
+    check(m2::S{}); //~ ERROR c::S
+    check(m2::S); //~ ERROR c::Item
+}
+fn xf12() {
+    check(xm1::S{}); //~ ERROR c::Item
+    check(xm1::S); //~ ERROR unresolved name
+    check(xm2::S{}); //~ ERROR c::S
+    check(xm2::S); //~ ERROR c::Item
+}
+
+mod m3 {
+    pub use ::proxy::*;
+    pub type TS = ::c::Item;
+}
+mod m4 {
+    pub use ::proxy::*;
+    pub const TS: ::c::Item = ::c::Item;
+}
+
+fn f34() {
+    check(m3::TS{}); //~ ERROR c::Item
+    check(m3::TS); //~ ERROR c::TS
+    check(m4::TS{}); //~ ERROR c::TS
+    check(m4::TS); //~ ERROR c::Item
+}
+fn xf34() {
+    check(xm3::TS{}); //~ ERROR c::Item
+    check(xm3::TS); //~ ERROR c::TS
+    check(xm4::TS{}); //~ ERROR c::TS
+    check(xm4::TS); //~ ERROR c::Item
+}
+
+mod m5 {
+    pub use ::proxy::*;
+    pub type US = ::c::Item;
+}
+mod m6 {
+    pub use ::proxy::*;
+    pub const US: ::c::Item = ::c::Item;
+}
+
+fn f56() {
+    check(m5::US{}); //~ ERROR c::Item
+    check(m5::US); //~ ERROR c::US
+    check(m6::US{}); //~ ERROR c::US
+    check(m6::US); //~ ERROR c::Item
+}
+fn xf56() {
+    check(xm5::US{}); //~ ERROR c::Item
+    check(xm5::US); //~ ERROR c::US
+    check(xm6::US{}); //~ ERROR c::US
+    check(xm6::US); //~ ERROR c::Item
+}
+
+mod m7 {
+    pub use ::proxy::*;
+    pub type V = ::c::Item;
+}
+mod m8 {
+    pub use ::proxy::*;
+    pub const V: ::c::Item = ::c::Item;
+}
+
+fn f78() {
+    check(m7::V{}); //~ ERROR c::Item
+    check(m7::V); //~ ERROR name of a struct or struct variant
+    check(m8::V{}); //~ ERROR c::E
+    check(m8::V); //~ ERROR c::Item
+}
+fn xf78() {
+    check(xm7::V{}); //~ ERROR c::Item
+    check(xm7::V); //~ ERROR name of a struct or struct variant
+    check(xm8::V{}); //~ ERROR c::E
+    check(xm8::V); //~ ERROR c::Item
+}
+
+mod m9 {
+    pub use ::proxy::*;
+    pub type TV = ::c::Item;
+}
+mod mA {
+    pub use ::proxy::*;
+    pub const TV: ::c::Item = ::c::Item;
+}
+
+fn f9A() {
+    check(m9::TV{}); //~ ERROR c::Item
+    check(m9::TV); //~ ERROR c::E
+    check(mA::TV{}); //~ ERROR c::E
+    check(mA::TV); //~ ERROR c::Item
+}
+fn xf9A() {
+    check(xm9::TV{}); //~ ERROR c::Item
+    check(xm9::TV); //~ ERROR c::E
+    check(xmA::TV{}); //~ ERROR c::E
+    check(xmA::TV); //~ ERROR c::Item
+}
+
+mod mB {
+    pub use ::proxy::*;
+    pub type UV = ::c::Item;
+}
+mod mC {
+    pub use ::proxy::*;
+    pub const UV: ::c::Item = ::c::Item;
+}
+
+fn fBC() {
+    check(mB::UV{}); //~ ERROR c::Item
+    check(mB::UV); //~ ERROR c::E
+    check(mC::UV{}); //~ ERROR c::E
+    check(mC::UV); //~ ERROR c::Item
+}
+fn xfBC() {
+    check(xmB::UV{}); //~ ERROR c::Item
+    check(xmB::UV); //~ ERROR c::E
+    check(xmC::UV{}); //~ ERROR c::E
+    check(xmC::UV); //~ ERROR c::Item
+}
+
+fn main() {}