Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upDo not allow a module and tuple struct of the same name to coexist. #26421
Conversation
rust-highfive
assigned
pcwalton
Jun 19, 2015
This comment has been minimized.
This comment has been minimized.
|
r? @pcwalton (rust_highfive has picked a reviewer for you, use r? to override) |
nham
force-pushed the
nham:fix_21546
branch
from
a8cfb62
to
d6c0753
Jun 19, 2015
This comment has been minimized.
This comment has been minimized.
|
This is unfortunately a breaking change, so we need to be sure to tread carefully here (especially in resolve). cc @rust-lang/lang, @nrc, I forget if cases like this were intentional or not? |
This comment has been minimized.
This comment has been minimized.
|
I've started this on crater. |
pnkfelix
reviewed
Jun 20, 2015
| struct Foo; | ||
| //~^ ERROR duplicate definition of type or module `Foo` |
This comment has been minimized.
This comment has been minimized.
pnkfelix
Jun 20, 2015
Member
given that [RFC 218]("empty struct with braces") was accepted, it would probably be a good idea to have both this test and a separate one of non-empty tuple structs, since I expect the code paths for how the two are handled to diverge somewhat in the future.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton asked:
I'm pretty sure this was an oversight. Every kind of struct definition puts an entry into the type namespace (while only some put an entry into the value namespace, but this is not relevant). The collision at the type namespace level is what is problematic. In other words, this errors today: mod Foo {}
struct Foo { x: i32 }
fn main() {}so there's no reason for these to be succeeding: mod Foo {}
struct Foo(i32);
fn main() {}and mod Foo {}
struct Foo;
fn main() {} |
This comment has been minimized.
This comment has been minimized.
|
Here is a more concrete example of a problematic program this bug is exposing: #[allow(non_snake_case)]
mod Foo { pub fn foo() -> i32 { 4 } }
struct Foo(i32);
impl Foo { fn foo() -> i32 { 3 } }
fn main() { println!("foo: {}", Foo::foo()); } // what does this print? |
This comment has been minimized.
This comment has been minimized.
|
Having said that, its not a soundness issue to my knowledge. Fixing it would not break code that is following "usual" style conventions about struct and module names, but otherwise it is indeed a breaking change. Does it qualify as a course correction, or just a bug fix? We could certainly employ the |
This comment has been minimized.
This comment has been minimized.
|
This was not intentional. I think it is definitely a bug fix, not a course correction or 'proper' breaking change. |
This comment has been minimized.
This comment has been minimized.
alexcrichton
added
I-needs-decision
T-lang
I-nominated
and removed
I-needs-decision
labels
Jun 25, 2015
This comment has been minimized.
This comment has been minimized.
|
Tagging with T-lang and I-nominated, just getting some broader visibility (and will be dealt with during triage) |
This comment has been minimized.
This comment has been minimized.
|
Similarly to #27026 (which was specifically mentioned during the last lang team meeting, where the response was "warning cycle first, then release the breaking change"), I am again wondering whether this needs to go through a warning cycle or not. I interpret @nrc above as saying "no, it does not need a warning cycle." But if that is the case, then why apply a different policy to #27026 ? Are these two cases all that different? |
This comment has been minimized.
This comment has been minimized.
|
I think it could (and probably should) get a warning cycle. I don't think it should get a legacy flag or anything more permanent than a warning cycle. |
This comment has been minimized.
This comment has been minimized.
|
So under this policy, does the change in #25993 need to be reverted and have a warning cycle added? The following program used to compile pre-patch, but does not after: trait Foo {
type Ty;
}
impl Foo for () {
type Ty = ();
type Ty = usize;
}
fn main() {
let _: <() as Foo>::Ty = ();
} |
nikomatsakis
removed
the
I-nominated
label
Jul 23, 2015
This comment has been minimized.
This comment has been minimized.
|
Triage: removing I-nominated as we've taken a look. Seems like a warning cycle makes sense, given how widely used tuple structs and modules are. With respect to #25993, I think we can let that go --- istm that overlap there is less likely, and of course we'll see if crater picks up anything. |
This comment has been minimized.
This comment has been minimized.
|
ping? @nham would you be ok implementing a warning for this change? |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
Re assigning to myself, I will try to revise with warning cycle support if we see no response from @nham |
pnkfelix
assigned
pnkfelix
and unassigned
pcwalton
Oct 18, 2015
This comment has been minimized.
This comment has been minimized.
|
Sorry, I've been busy the past couple of weeks. I have some time to look at it this week, but I still need to figure out how the warning cycles work, so if you want to take it @pnkfelix that's okay with me. |
This comment has been minimized.
This comment has been minimized.
|
@nham oh I have plenty of other stuff on my plate, so you've got time to look at it this week if you like. :) |
alexcrichton
referenced this pull request
Oct 20, 2015
Closed
Unit/tuple structs with the same name as a module are allowed. #29185
nham
force-pushed the
nham:fix_21546
branch
from
da2d1fa
to
f0af1eb
Oct 22, 2015
This comment has been minimized.
This comment has been minimized.
|
I've made an attempt at adding warnings. The warnings address both the original issue and another issue mentioned by @james-darkfox in #29185, which is that programs like this currently compile: struct Foo { x: i32 }
mod Foo { }
fn main() {}This is slightly different from the original issue because it is allowed only when the module comes after the struct, and also because it works for all structs, not just unit/tuple structs. I wasn't sure what to put for the warning message. Looking for feedback here! |
This comment has been minimized.
This comment has been minimized.
pnkfelix
reviewed
Oct 27, 2015
| @@ -404,6 +404,29 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { | |||
| } | |||
|
|
|||
| ItemMod(..) => { | |||
| let child = parent.children.borrow().get(&name).cloned(); | |||
This comment has been minimized.
This comment has been minimized.
pnkfelix
Oct 27, 2015
Member
Seems a shame to clone the child; I would have thought there was a way to structure this to avoid that.
pnkfelix
reviewed
Oct 27, 2015
| 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!( |
This comment has been minimized.
This comment has been minimized.
pnkfelix
Oct 27, 2015
Member
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.
pnkfelix
referenced this pull request
Oct 27, 2015
Closed
A type with static methods with the same name as a module generates incorrect error message #14564
This comment has been minimized.
This comment has been minimized.
|
@nham this looks fine to me, apart from the clone, which I assume you tried to avoid and I must just be missing some reason why you found it necessary |
This comment has been minimized.
This comment has been minimized.
|
@bors r+ |
This comment has been minimized.
This comment has been minimized.
|
|
nham commentedJun 19, 2015
Fixes #21546.