Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not allow a module and tuple struct of the same name to coexist. #26421

Merged
merged 1 commit into from
Oct 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,29 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
}

ItemMod(..) => {
let child = parent.children.borrow().get(&name).cloned();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems a shame to clone the child; I would have thought there was a way to structure this to avoid that.

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);
Expand Down Expand Up @@ -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!(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we consider allocating a error number now for this?

I guess it can wait until we promote the warning into a proper error, since I don't know if our error number policy would allow us to reuse the same number for the warning and the error it is later promoted into.

"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()))
};

Expand Down
65 changes: 65 additions & 0 deletions src/test/compile-fail/issue-21546.rs
Original file line number Diff line number Diff line change
@@ -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() { }
15 changes: 0 additions & 15 deletions src/test/run-pass/issue-14564.rs

This file was deleted.