From 3c9443b6e58c2c1a7bd9e6e2a74e183c33c98ebc Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 4 Jul 2014 17:59:55 -0700 Subject: [PATCH] librustc: Disallow modules and types from having the same name. This will break code that looks like: struct Foo { ... } mod Foo { ... } Change this code to: struct Foo { ... } impl Foo { ... } Or rename the module. Closes #15205. [breaking-change] --- src/librustc/middle/resolve.rs | 33 ++++++++++++------- .../dup-struct-enum-struct-variant.rs | 4 +-- .../enum-and-module-in-same-scope.rs | 19 +++++++++++ src/test/compile-fail/issue-3099-a.rs | 2 +- src/test/compile-fail/issue-3099-b.rs | 2 +- 5 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 src/test/compile-fail/enum-and-module-in-same-scope.rs diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index b7b4618a790..69d095c5db4 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -307,7 +307,7 @@ enum BareIdentifierPatternResolution { #[deriving(PartialEq)] enum DuplicateCheckingMode { ForbidDuplicateModules, - ForbidDuplicateTypes, + ForbidDuplicateTypesAndModules, ForbidDuplicateValues, ForbidDuplicateTypesAndValues, OverwriteDuplicates @@ -792,10 +792,9 @@ impl PrimitiveTypeTable { fn namespace_error_to_str(ns: NamespaceError) -> &'static str { match ns { - NoError => "", - ModuleError => "module", - TypeError => "type", - ValueError => "value", + NoError => "", + ModuleError | TypeError => "type or module", + ValueError => "value", } } @@ -1033,9 +1032,12 @@ impl<'a> Resolver<'a> { } Some(TypeNS) } - ForbidDuplicateTypes => { + ForbidDuplicateTypesAndModules => { match child.def_for_namespace(TypeNS) { - Some(DefMod(_)) | None => {} + None => {} + Some(_) if child.get_module_if_available() + .map(|m| m.kind.get()) == + Some(ImplModuleKind) => {} Some(_) => duplicate_type = TypeError } Some(TypeNS) @@ -1177,7 +1179,10 @@ impl<'a> Resolver<'a> { // These items live in the type namespace. ItemTy(..) => { let name_bindings = - self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp); + self.add_child(ident, + parent.clone(), + ForbidDuplicateTypesAndModules, + sp); name_bindings.define_type (DefTy(local_def(item.id)), sp, is_public); @@ -1186,7 +1191,10 @@ impl<'a> Resolver<'a> { ItemEnum(ref enum_definition, _) => { let name_bindings = - self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp); + self.add_child(ident, + parent.clone(), + ForbidDuplicateTypesAndModules, + sp); name_bindings.define_type (DefTy(local_def(item.id)), sp, is_public); @@ -1206,7 +1214,7 @@ impl<'a> Resolver<'a> { // Adding to both Type and Value namespaces or just Type? let (forbid, ctor_id) = match struct_def.ctor_id { Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)), - None => (ForbidDuplicateTypes, None) + None => (ForbidDuplicateTypesAndModules, None) }; let name_bindings = self.add_child(ident, parent.clone(), forbid, sp); @@ -1327,7 +1335,10 @@ impl<'a> Resolver<'a> { ItemTrait(_, _, _, ref methods) => { let name_bindings = - self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp); + self.add_child(ident, + parent.clone(), + ForbidDuplicateTypesAndModules, + sp); // Add all the methods within to a new module. let parent_link = self.get_parent_link(parent.clone(), ident); diff --git a/src/test/compile-fail/dup-struct-enum-struct-variant.rs b/src/test/compile-fail/dup-struct-enum-struct-variant.rs index 064a3b9b168..47b576b2b85 100644 --- a/src/test/compile-fail/dup-struct-enum-struct-variant.rs +++ b/src/test/compile-fail/dup-struct-enum-struct-variant.rs @@ -11,9 +11,9 @@ #![feature(struct_variant)] enum Foo { C { a: int, b: int } } -struct C { a: int, b: int } //~ ERROR error: duplicate definition of type `C` +struct C { a: int, b: int } //~ ERROR error: duplicate definition of type or module `C` struct A { x: int } -enum Bar { A { x: int } } //~ ERROR error: duplicate definition of type `A` +enum Bar { A { x: int } } //~ ERROR error: duplicate definition of type or module `A` fn main() {} diff --git a/src/test/compile-fail/enum-and-module-in-same-scope.rs b/src/test/compile-fail/enum-and-module-in-same-scope.rs new file mode 100644 index 00000000000..7464764666c --- /dev/null +++ b/src/test/compile-fail/enum-and-module-in-same-scope.rs @@ -0,0 +1,19 @@ +// Copyright 2014 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. + +mod Foo { + pub static X: int = 42; +} + +enum Foo { //~ ERROR duplicate definition of type or module `Foo` + X +} + +fn main() {} diff --git a/src/test/compile-fail/issue-3099-a.rs b/src/test/compile-fail/issue-3099-a.rs index 1b11fcac8a3..316199b6730 100644 --- a/src/test/compile-fail/issue-3099-a.rs +++ b/src/test/compile-fail/issue-3099-a.rs @@ -10,6 +10,6 @@ enum a { b, c } -enum a { d, e } //~ ERROR duplicate definition of type `a` +enum a { d, e } //~ ERROR duplicate definition of type or module `a` fn main() {} diff --git a/src/test/compile-fail/issue-3099-b.rs b/src/test/compile-fail/issue-3099-b.rs index 5502b18f094..b3f1b2a32ea 100644 --- a/src/test/compile-fail/issue-3099-b.rs +++ b/src/test/compile-fail/issue-3099-b.rs @@ -10,6 +10,6 @@ pub mod a {} -pub mod a {} //~ ERROR duplicate definition of module `a` +pub mod a {} //~ ERROR duplicate definition of type or module `a` fn main() {}