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_, diff --git a/src/test/compile-fail/issue-6936.rs b/src/test/compile-fail/issue-6936.rs new file mode 100644 index 00000000000..f5c879a07ee --- /dev/null +++ b/src/test/compile-fail/issue-6936.rs @@ -0,0 +1,44 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct T; + +mod t1 { + type Foo = ::T; + mod Foo {} //~ ERROR: duplicate definition of type or module `Foo` +} + +mod t2 { + type Foo = ::T; + struct Foo; //~ ERROR: duplicate definition of type or module `Foo` +} + +mod t3 { + type Foo = ::T; + enum Foo {} //~ ERROR: duplicate definition of type or module `Foo` +} + +mod t4 { + type Foo = ::T; + fn Foo() {} // ok +} + +mod t5 { + type Bar = T; + mod Bar {} //~ ERROR: duplicate definition of type or module `Bar` +} + +mod t6 { + type Foo = ::T; + impl Foo {} // ok +} + + +fn main() {}