about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-06-10 20:52:32 -0700
committerbors <bors@rust-lang.org>2013-06-10 20:52:32 -0700
commitdf5b0c040c744879705b4c37be3bb1cbe7282ab2 (patch)
tree1e827daf214b7ec3f99ef21e40bdb7eb69ec3ad9
parent37733c7eafdcf4bd6c4c95d38a05c307abda78d6 (diff)
parent693b9ce4e88f60af6a486f6c55fff0a761b38030 (diff)
downloadrust-df5b0c040c744879705b4c37be3bb1cbe7282ab2.tar.gz
rust-df5b0c040c744879705b4c37be3bb1cbe7282ab2.zip
auto merge of #7046 : luqmana/rust/issue-7044, r=sanxiyn
Fixes #7044.
-rw-r--r--src/librustc/middle/resolve.rs66
-rw-r--r--src/test/compile-fail/issue-7044.rs14
2 files changed, 44 insertions, 36 deletions
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 96838c32266..97b0d61499b 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -294,18 +294,6 @@ pub enum DuplicateCheckingMode {
     OverwriteDuplicates
 }
 
-// Returns the namespace associated with the given duplicate checking mode,
-// or fails for OverwriteDuplicates. This is used for error messages.
-pub fn namespace_for_duplicate_checking_mode(mode: DuplicateCheckingMode)
-                                          -> Namespace {
-    match mode {
-        ForbidDuplicateModules | ForbidDuplicateTypes |
-        ForbidDuplicateTypesAndValues => TypeNS,
-        ForbidDuplicateValues => ValueNS,
-        OverwriteDuplicates => fail!("OverwriteDuplicates has no namespace")
-    }
-}
-
 /// One local scope.
 pub struct Rib {
     bindings: @mut HashMap<ident,def_like>,
@@ -1007,37 +995,43 @@ impl Resolver {
                 //   nothing.
 
                 let mut is_duplicate = false;
-                match duplicate_checking_mode {
+                let ns = match duplicate_checking_mode {
                     ForbidDuplicateModules => {
-                        is_duplicate =
-                            child.get_module_if_available().is_some();
+                        is_duplicate = child.get_module_if_available().is_some();
+                        Some(TypeNS)
                     }
                     ForbidDuplicateTypes => {
                         match child.def_for_namespace(TypeNS) {
                             Some(def_mod(_)) | None => {}
                             Some(_) => is_duplicate = true
                         }
+                        Some(TypeNS)
                     }
                     ForbidDuplicateValues => {
                         is_duplicate = child.defined_in_namespace(ValueNS);
+                        Some(ValueNS)
                     }
                     ForbidDuplicateTypesAndValues => {
+                        let mut n = None;
                         match child.def_for_namespace(TypeNS) {
                             Some(def_mod(_)) | None => {}
-                            Some(_) => is_duplicate = true
+                            Some(_) => {
+                                n = Some(TypeNS);
+                                is_duplicate = true;
+                            }
                         };
                         if child.defined_in_namespace(ValueNS) {
                             is_duplicate = true;
+                            n = Some(ValueNS);
                         }
+                        n
                     }
-                    OverwriteDuplicates => {}
-                }
-                if duplicate_checking_mode != OverwriteDuplicates &&
-                        is_duplicate {
+                    OverwriteDuplicates => None
+                };
+                if is_duplicate {
                     // Return an error here by looking up the namespace that
                     // had the duplicate.
-                    let ns = namespace_for_duplicate_checking_mode(
-                        duplicate_checking_mode);
+                    let ns = ns.unwrap();
                     self.session.span_err(sp,
                         fmt!("duplicate definition of %s `%s`",
                              namespace_to_str(ns),
@@ -1195,22 +1189,22 @@ impl Resolver {
 
             // These items live in both the type and value namespaces.
             item_struct(struct_def, _) => {
-                let (name_bindings, new_parent) =
-                    self.add_child(ident, parent, ForbidDuplicateTypes, sp);
+                // 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)
+                };
 
-                name_bindings.define_type(
-                    privacy, def_ty(local_def(item.id)), sp);
+                let (name_bindings, new_parent) = self.add_child(ident, parent, forbid, sp);
 
-                // If this struct is tuple-like or enum-like, define a name
-                // in the value namespace.
-                match struct_def.ctor_id {
-                    None => {}
-                    Some(ctor_id) => {
-                        name_bindings.define_value(
-                            privacy,
-                            def_struct(local_def(ctor_id)),
-                            sp);
-                    }
+                // Define a name in the type namespace.
+                name_bindings.define_type(privacy, def_ty(local_def(item.id)), sp);
+
+                // If this is a newtype or unit-like struct, define a name
+                // in the value namespace as well
+                do ctor_id.while_some |cid| {
+                    name_bindings.define_value(privacy, def_struct(local_def(cid)), sp);
+                    None
                 }
 
                 // Record the def ID of this struct.
diff --git a/src/test/compile-fail/issue-7044.rs b/src/test/compile-fail/issue-7044.rs
new file mode 100644
index 00000000000..ee332789b0e
--- /dev/null
+++ b/src/test/compile-fail/issue-7044.rs
@@ -0,0 +1,14 @@
+// Copyright 2013 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.
+
+static X: int = 0;
+struct X; //~ ERROR error: duplicate definition of value `X`
+
+fn main() {}