about summary refs log tree commit diff
path: root/src/librustc_resolve
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-16 14:25:45 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-18 18:25:55 -0800
commit2549cbec9dfe02cdc93a3cf3bfe9638e5a4c2948 (patch)
treeadc17d5a487ce8a29f354e0d24391f0121a53882 /src/librustc_resolve
parent46366faf613685eeeacf896ee9d284b28d4a3046 (diff)
rustc_resolve: Do not allow mods to shadow types
This commit modifies resolve to prevent conflicts with typedef names in the same
method that conflits are prevented with enum names. This is a breaking change
due to the differing semantics in resolve, and any errors generated on behalf of
this change require that a conflicting typedef, module, or structure to be
renamed so they do not conflict.

[breaking-change]
Closes #6936
Diffstat (limited to 'src/librustc_resolve')
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs41
-rw-r--r--src/librustc_resolve/lib.rs4
2 files changed, 29 insertions, 16 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 56b05f9e726..21eec383df4 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -321,9 +321,19 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             // These items live in the type namespace.
             ItemTy(..) => {
                 let name_bindings =
-                    self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp);
+                    self.add_child(name, parent, ForbidDuplicateTypesAndModules,
+                                   sp);
 
-                name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
+                name_bindings.define_type(DefTy(local_def(item.id), false), sp,
+                                          modifiers);
+
+                let parent_link = self.get_parent_link(parent, name);
+                name_bindings.set_module_kind(parent_link,
+                                              Some(local_def(item.id)),
+                                              TypeModuleKind,
+                                              false,
+                                              is_public,
+                                              sp);
                 parent.clone()
             }
 
@@ -423,21 +433,19 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                         return parent.clone();
                     }
                 };
-
                 // Create the module and add all methods.
-                let parent_opt = parent.children.borrow().get(&mod_name).cloned();
-                let new_parent = match parent_opt {
+                let child_opt = parent.children.borrow().get(&mod_name)
+                                       .and_then(|m| m.get_module_if_available());
+                let new_parent = match child_opt {
                     // It already exists
-                    Some(ref child) if child.get_module_if_available()
-                        .is_some() &&
-                        (child.get_module().kind.get() == ImplModuleKind ||
-                         child.get_module().kind.get() == TraitModuleKind) => {
-                            child.get_module()
-                        }
-                    Some(ref child) if child.get_module_if_available()
-                        .is_some() &&
-                        child.get_module().kind.get() ==
-                        EnumModuleKind => child.get_module(),
+                    Some(ref child) if (child.kind.get() == ImplModuleKind ||
+                                        child.kind.get() == TraitModuleKind) => {
+                        child.clone()
+                    }
+                    Some(ref child) if child.kind.get() == EnumModuleKind ||
+                                       child.kind.get() == TypeModuleKind => {
+                        child.clone()
+                    }
                     // Create the module
                     _ => {
                         let name_bindings =
@@ -859,7 +867,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
         let kind = match def {
             DefTy(_, true) => EnumModuleKind,
-            DefStruct(..) | DefTy(..) => ImplModuleKind,
+            DefTy(_, false) => TypeModuleKind,
+            DefStruct(..) => ImplModuleKind,
             _ => NormalModuleKind
         };
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 8c1e847748c..153333c6782 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -459,6 +459,7 @@ enum ModuleKind {
     TraitModuleKind,
     ImplModuleKind,
     EnumModuleKind,
+    TypeModuleKind,
     AnonymousModuleKind,
 }
 
@@ -2240,6 +2241,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         TraitModuleKind |
                         ImplModuleKind |
                         EnumModuleKind |
+                        TypeModuleKind |
                         AnonymousModuleKind => {
                             search_module = parent_module_node.upgrade().unwrap();
                         }
@@ -2337,6 +2339,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         TraitModuleKind |
                         ImplModuleKind |
                         EnumModuleKind |
+                        TypeModuleKind |
                         AnonymousModuleKind => module_ = new_module,
                     }
                 }
@@ -2353,6 +2356,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             TraitModuleKind |
             ImplModuleKind |
             EnumModuleKind |
+            TypeModuleKind |
             AnonymousModuleKind => {
                 match self.get_nearest_normal_module_parent(module_.clone()) {
                     None => module_,