-
Notifications
You must be signed in to change notification settings - Fork 13k
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
use dep1::foo as dep1
is considered ambiguous
#77586
Comments
searched nightlies: from nightly-2020-10-03 to nightly-2020-10-04 bisected with cargo-bisect-rustc v0.5.2Host triple: x86_64-unknown-linux-gnu cargo bisect-rustc --start=2020-10-03 --end=2020-10-04 --preserve |
Out of the prs in that roll up, I suspect #77421 could be related. @petrochenkov |
Yes, #77421 should be the reason. Strictly speaking, #77421 is not a bug fix, but rather an implementation of a slightly more conservative language rule giving us some more freedom in the future. |
Interesting. It appears I must have threaded the needle on versions here: 1.43 emits the same error as nightly, as do earlier versions. For reference: the crate was converted to While a bit annoying, it should be straight forward to fix for me. Just need to add some |
Without this, rustc 1.48 (as of now, rustc nightly-2020-10-04) is expected to fail to build rust-systemd. Rustc issue: rust-lang/rust#77586
141: use :: to disambiguate `use` r=jmesmon a=jmesmon Without this, rustc 1.48 (as of now, rustc nightly-2020-10-04) is expected to fail to build rust-systemd. Rustc issue: rust-lang/rust#77586 Co-authored-by: Cody Schafer <[email protected]>
Without this, rustc 1.48 (as of now, rustc nightly-2020-10-04) is expected to fail to build rust-systemd. Rustc issue: rust-lang/rust#77586
141: use :: to disambiguate `use` r=jmesmon a=jmesmon Without this, rustc 1.48 (as of now, rustc nightly-2020-10-04) is expected to fail to build rust-systemd. Rustc issue: rust-lang/rust#77586 Co-authored-by: Cody Schafer <[email protected]>
@rustbot prioritize |
Discussed at T-compiler meeting. nominating for discussion at T-lang meeting. |
self-assigning as reminder to do prep to describe issue at next T-lang meeting. |
Discussed in today's lang-team meeting:
|
Discussed in today's meeting:
|
It seems like this broke several more crates/repositories, in particular:
It feels like this pattern is (somewhat surprisingly) common-ish. I'm going to renominate given crater data, but given that this pattern was permitted on stable for several cycles and my impression from @petrochenkov's comments it that it's not too annoying for us to support, we should keep it around for at least 2018 edition (I wouldn't object to an edition break here though). |
use dep1::foo as dep1
is considered ambiguous on nightly but not betause dep1::foo as dep1
is considered ambiguous
@petrochenkov how difficult would it be to continue supporting this pattern? |
@nikomatsakis I'd say that for the current implementation of resolve it's more natural to support it than to not support. |
We discussed this in the @rust-lang/lang meeting today. Our consensus was that in light of the larger-than-expected impact, as well as @petrochenkov's comment, that we should revert #77421 and restore the older behavior. There is a reasonable case to be made for either behavior: there is a self-cycle here, but there is also only one reasonable way to resolve the cycle at present. (I presume that if However @petrochenkov I'd like to get your take. I was reading a bit into #74556 and especially this comment of yours which seems to be the best summary of what we are "giving up" by accepting this pattern. I'm having a bit of trouble parsing it though, I admit. I did find the example from #74556 interesting and I don't feel like we explored it in the @rust-lang/lang meeting. The example is: mod foo {
pub mod bar {
pub mod bar {
pub fn foobar() {}
}
}
}
use foo::*;
use bar::bar;
use bar::foobar;
fn main() {
bar::foobar();
} What happens here, as best as I can tell, is that It seems important to me to reject this case, but perhaps it is not so easy to reject this case while also permitting cases like the one in the OP? |
I'm going to leave this nominated. |
Namely, causality.
The current causality-based approach is different from my "import resolution as inference" idea (this comment of mine) where the output is planted into the module first as a fresh inference variable, and then participates in the input's resolution creating an inference failure (
A name can have different meaning in different places because due to the causality logic different names are effectively resolved in different environments.
This is a deterministic rule, it doesn't change if we randomize some item resolution order or macro expansion order, so I'm not sure whether it's directly related to time traveling or not.
Perhaps it is not, since it's the same feature in action. |
The causality rule do not apply to glob imports because they don't have an easily obtainable set of output names, and people are actually complaining about this (#62769)! If we excluded |
Yeah, I think there's a secondary constraint that I had in mind, which is basically that, in the end, we can come up with a single "resolution result" for each module which is a mapping of I guess that we can think of |
One option would be to allow overlap between "pub use" and "use", but not allow overlap within the two. This would allow having |
Assigning to self for a revert of #77421. |
We discussed this in the language meeting today. We thought that we may want the more constrained behavior, but we were not at this point inclined to land breakage. It is possible that in a future edition, we may want to move to a different resolution story (perhaps @petrochenkov's inference idea), and in which case we would lint on such patterns (and presumably others?). @pnkfelix brought up that we may want to lint on this pattern regardless (since it is rather confusing in most cases), but that should likely go through the standard dance of a proposal dedicated to such a lint which T-lang can FCP (or start in Clippy, perhaps). |
So here is a brain puzzler. Which version of mod foo {
pub mod bar {
pub fn foobar() -> u32 { 1 }
pub mod bar {
pub fn foobar() -> u32 { 2 }
}
}
}
use foo:*;
use bar::bar;
use bar::foobar; Answer: version 2, and I imagine this is because we refuse to resolve (In any case, @joshtriplett, to answer your question in the meeting, what we are giving up is that we are accepting the current interpretation of cases like this, but these are the sorts of corner cases where different models or evaluation orders or what have you might give slightly different answers.) |
@nikomatsakis Interesting. That does seem like it should be rejected (specifically, at the point of Our current error messages seem painfully confusing; "ambiguity" isn't the issue here, that does indeed feel wrong because of causality. Ideally we'd give a clear error about a name conflict, instead. A lint to gently steer people away from this kind of name conflict (and to take advantage of cap-lints to avoid causing breakage in the process) seems reasonable though. |
Here's how to solve this step-by step.
|
Another case where people explicitly wanted disambiguation based on causality - #56414 (comment) ("An import should never be ambiguous with itself."). |
src/lib.rs
:dep1/src/lib.rs
:I expected to see this happen: build succeeds.
Instead, this happened:
Meta
working beta:
rustc --version --verbose
:non-working nightly:
rustc +nightly --version --verbose
This broke
rust-systemd
's build (https://travis-ci.com/github/jmesmon/rust-systemd/jobs/395293939) (broken versions arev0.6.0
andv0.5.0
which useedition = "2018"
).I'm not sure if there is a simpler single-crate break (there could be).
The text was updated successfully, but these errors were encountered: