Skip to content

Commit 2549cbe

Browse files
committed
rustc_resolve: Do not allow mods to shadow types
This commit modifies resolve to prevent conflicts with typedef names in the same method that conflits are prevented with enum names. This is a breaking change due to the differing semantics in resolve, and any errors generated on behalf of this change require that a conflicting typedef, module, or structure to be renamed so they do not conflict. [breaking-change] Closes #6936
1 parent 46366fa commit 2549cbe

File tree

3 files changed

+73
-16
lines changed

3 files changed

+73
-16
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -321,9 +321,19 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
321321
// These items live in the type namespace.
322322
ItemTy(..) => {
323323
let name_bindings =
324-
self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp);
324+
self.add_child(name, parent, ForbidDuplicateTypesAndModules,
325+
sp);
325326

326-
name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
327+
name_bindings.define_type(DefTy(local_def(item.id), false), sp,
328+
modifiers);
329+
330+
let parent_link = self.get_parent_link(parent, name);
331+
name_bindings.set_module_kind(parent_link,
332+
Some(local_def(item.id)),
333+
TypeModuleKind,
334+
false,
335+
is_public,
336+
sp);
327337
parent.clone()
328338
}
329339

@@ -423,21 +433,19 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
423433
return parent.clone();
424434
}
425435
};
426-
427436
// Create the module and add all methods.
428-
let parent_opt = parent.children.borrow().get(&mod_name).cloned();
429-
let new_parent = match parent_opt {
437+
let child_opt = parent.children.borrow().get(&mod_name)
438+
.and_then(|m| m.get_module_if_available());
439+
let new_parent = match child_opt {
430440
// It already exists
431-
Some(ref child) if child.get_module_if_available()
432-
.is_some() &&
433-
(child.get_module().kind.get() == ImplModuleKind ||
434-
child.get_module().kind.get() == TraitModuleKind) => {
435-
child.get_module()
436-
}
437-
Some(ref child) if child.get_module_if_available()
438-
.is_some() &&
439-
child.get_module().kind.get() ==
440-
EnumModuleKind => child.get_module(),
441+
Some(ref child) if (child.kind.get() == ImplModuleKind ||
442+
child.kind.get() == TraitModuleKind) => {
443+
child.clone()
444+
}
445+
Some(ref child) if child.kind.get() == EnumModuleKind ||
446+
child.kind.get() == TypeModuleKind => {
447+
child.clone()
448+
}
441449
// Create the module
442450
_ => {
443451
let name_bindings =
@@ -859,7 +867,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
859867

860868
let kind = match def {
861869
DefTy(_, true) => EnumModuleKind,
862-
DefStruct(..) | DefTy(..) => ImplModuleKind,
870+
DefTy(_, false) => TypeModuleKind,
871+
DefStruct(..) => ImplModuleKind,
863872
_ => NormalModuleKind
864873
};
865874

src/librustc_resolve/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ enum ModuleKind {
459459
TraitModuleKind,
460460
ImplModuleKind,
461461
EnumModuleKind,
462+
TypeModuleKind,
462463
AnonymousModuleKind,
463464
}
464465

@@ -2240,6 +2241,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
22402241
TraitModuleKind |
22412242
ImplModuleKind |
22422243
EnumModuleKind |
2244+
TypeModuleKind |
22432245
AnonymousModuleKind => {
22442246
search_module = parent_module_node.upgrade().unwrap();
22452247
}
@@ -2337,6 +2339,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
23372339
TraitModuleKind |
23382340
ImplModuleKind |
23392341
EnumModuleKind |
2342+
TypeModuleKind |
23402343
AnonymousModuleKind => module_ = new_module,
23412344
}
23422345
}
@@ -2353,6 +2356,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
23532356
TraitModuleKind |
23542357
ImplModuleKind |
23552358
EnumModuleKind |
2359+
TypeModuleKind |
23562360
AnonymousModuleKind => {
23572361
match self.get_nearest_normal_module_parent(module_.clone()) {
23582362
None => module_,

src/test/compile-fail/issue-6936.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct T;
12+
13+
mod t1 {
14+
type Foo = ::T;
15+
mod Foo {} //~ ERROR: duplicate definition of type or module `Foo`
16+
}
17+
18+
mod t2 {
19+
type Foo = ::T;
20+
struct Foo; //~ ERROR: duplicate definition of type or module `Foo`
21+
}
22+
23+
mod t3 {
24+
type Foo = ::T;
25+
enum Foo {} //~ ERROR: duplicate definition of type or module `Foo`
26+
}
27+
28+
mod t4 {
29+
type Foo = ::T;
30+
fn Foo() {} // ok
31+
}
32+
33+
mod t5 {
34+
type Bar<T> = T;
35+
mod Bar {} //~ ERROR: duplicate definition of type or module `Bar`
36+
}
37+
38+
mod t6 {
39+
type Foo = ::T;
40+
impl Foo {} // ok
41+
}
42+
43+
44+
fn main() {}

0 commit comments

Comments
 (0)