about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNick Hamann <nick@wabbo.org>2015-10-22 14:53:01 -0500
committerNick Hamann <nick@wabbo.org>2015-10-22 17:12:16 -0500
commitf0af1eb110b3dd12754b02bc3dcb7127ea2dce7f (patch)
tree55c04afff812ba379cdc9fbc69236cd6a9ef1691 /src
parent5692e16270ad844e89aa56859d5f8311159e2eea (diff)
downloadrust-f0af1eb110b3dd12754b02bc3dcb7127ea2dce7f.tar.gz
rust-f0af1eb110b3dd12754b02bc3dcb7127ea2dce7f.zip
Warn when creating a module and a struct that both have the same name.
Currently it is possible to do the following:

 - define a module named `Foo` and then a unit or tuple struct also named `Foo`
 - define any struct named `Foo` and then a module named `Foo`

This commit introduces a warning for both of these cases.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs45
-rw-r--r--src/test/compile-fail/issue-21546.rs65
-rw-r--r--src/test/run-pass/issue-14564.rs15
3 files changed, 110 insertions, 15 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index c051f8c2637..52ec3a0dbf9 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -404,6 +404,29 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             }
 
             ItemMod(..) => {
+                let child = parent.children.borrow().get(&name).cloned();
+                if let Some(child) = child {
+                    // check if there's struct of the same name already defined
+                    if child.defined_in_namespace(TypeNS)
+                        && child.get_module_if_available().is_none() {
+                        self.session.span_warn(sp, &format!(
+                                                    "duplicate definition of {} `{}`. \
+                                                     Defining a module and a struct with \
+                                                     the same name will be disallowed \
+                                                     soon.",
+                                               namespace_error_to_string(TypeError),
+                                               name));
+                        {
+                            let r = child.span_for_namespace(TypeNS);
+                            if let Some(sp) = r {
+                                self.session.span_note(sp,
+                                     &format!("first definition of {} `{}` here",
+                                          namespace_error_to_string(TypeError),
+                                          name));
+                            }
+                        }
+                    }
+                }
                 let name_bindings = self.add_child(name, parent, ForbidDuplicateModules, sp);
 
                 let parent_link = self.get_parent_link(parent, name);
@@ -495,6 +518,28 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 let (forbid, ctor_id) = if struct_def.is_struct() {
                     (ForbidDuplicateTypesAndModules, None)
                 } else {
+                    let child = parent.children.borrow().get(&name).cloned();
+                    if let Some(child) = child {
+                        // check if theres a DefMod
+                        if let Some(DefMod(_)) = child.def_for_namespace(TypeNS) {
+                            self.session.span_warn(sp, &format!(
+                                                        "duplicate definition of {} `{}`. \
+                                                         Defining a module and a struct with \
+                                                         the same name will be disallowed \
+                                                         soon.",
+                                                   namespace_error_to_string(TypeError),
+                                                   name));
+                            {
+                                let r = child.span_for_namespace(TypeNS);
+                                if let Some(sp) = r {
+                                    self.session.span_note(sp,
+                                         &format!("first definition of {} `{}` here",
+                                              namespace_error_to_string(TypeError),
+                                              name));
+                                }
+                            }
+                        }
+                    }
                     (ForbidDuplicateTypesAndValues, Some(struct_def.id()))
                 };
 
diff --git a/src/test/compile-fail/issue-21546.rs b/src/test/compile-fail/issue-21546.rs
new file mode 100644
index 00000000000..bb1bcd4e871
--- /dev/null
+++ b/src/test/compile-fail/issue-21546.rs
@@ -0,0 +1,65 @@
+// 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 <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.
+
+// Also works as a test for #14564
+
+#[allow(non_snake_case)]
+mod Foo { }
+//~^ NOTE first definition of type or module `Foo`
+
+#[allow(dead_code)]
+struct Foo;
+//~^ WARNING duplicate definition of type or module `Foo`
+
+
+#[allow(non_snake_case)]
+mod Bar { }
+//~^ NOTE first definition of type or module `Bar`
+
+#[allow(dead_code)]
+struct Bar(i32);
+//~^ WARNING duplicate definition of type or module `Bar`
+
+
+#[allow(dead_code)]
+struct Baz(i32);
+//~^ NOTE first definition of type or module
+
+#[allow(non_snake_case)]
+mod Baz { }
+//~^ WARNING duplicate definition of type or module `Baz`
+
+
+#[allow(dead_code)]
+struct Qux { x: bool }
+//~^ NOTE first definition of type or module
+
+#[allow(non_snake_case)]
+mod Qux { }
+//~^ WARNING duplicate definition of type or module `Qux`
+
+
+#[allow(dead_code)]
+struct Quux;
+//~^ NOTE first definition of type or module
+
+#[allow(non_snake_case)]
+mod Quux { }
+//~^ WARNING duplicate definition of type or module `Quux`
+
+
+#[allow(dead_code)]
+enum Corge { A, B }
+
+#[allow(non_snake_case)]
+mod Corge { }
+//~^ ERROR duplicate definition of type or module `Corge`
+
+fn main() { }
diff --git a/src/test/run-pass/issue-14564.rs b/src/test/run-pass/issue-14564.rs
deleted file mode 100644
index a661437a44c..00000000000
--- a/src/test/run-pass/issue-14564.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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 <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.
-
-mod Foo { }
-struct Foo;
-impl Foo { }
-
-fn main() { }