Repository navigation
Glob Time Travel #74556
Description
Activity
- addedA-resolveArea: Name/path resolution done by `rustc_resolve` specificallyArea: Name/path resolution done by `rustc_resolve` specificallyT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language team
on Jul 20, 2020 This use bar::bar; shadows one (glob-imported) bar with another bar. As far as I know, this should be forbidden.
Shadowing a glob import with a specific item is allowed and will unambiguously resolve to the specific one. This is also how the prelude works. The following compiles fine as well:
// implicit: use std::prelude::v1::*; containing Vec struct Vec; fn a() -> Vec { unimplemented!() }
To clarify, the problem is not shadowing, but time travel. We shadow identifier which have been already used to resolve another import, so we end up with
barmeaning two things at the same time in the same scope.This is a change from Rust 1.44, in Rust 1.43 this is an ICE "inconsistent resolution for an import".
Possibly a consequence of #70236.I'm not sure this is a bug.
When resolving
use bar::bar;we are looking at all names in scope except for the names introduced byuse bar::bar;itself. Otherwise we'd have cycles even in trivial cases likeuse my_crate;wheremy_crateis a name from extern prelude.If you take this detail into consideration, then all paths seem to be resolved correctly.
cc #62769 (somewhat related)
I think, the difference with
use my_crate;is thatuse my_crate;doesn't replace one resolution with another. We already have a namemy_cratein the scope that is resolved to a particular extern crate.In my example,
use bar::bar;usesbarname from the scope, and then rebinds thisbarname to another item.I can complicate my example a bit.
mod foo { pub mod bar { pub mod bar { pub fn foobar() { println!("111") } } pub fn foobar() { println!("222") } } } use foo::*; use bar::bar; use bar::foobar; fn main() { foobar(); }
What this program prints, "111" or "222"? It'd say, it depends on imports resolution order, but looks like it always prints "111".
It'd say, it depends on imports resolution order
The intent for the resolution results is to never depend on internal resolution order.
(cc #53778 (comment), order-dependence can probably happen in practice due to the current not very principled implementation, but hopefully still can be eliminated in backward-compatible-in-practice way by rewriting the main resolution/expansion loop more carefully.)but looks like it always prints "111"
That's what I'd expect.
foobarresolves touse bar::foobarbarinbar::foobarresolves touse bar::bar(because non-globs shadow globs)- first
barinbar::barresolves touse foo::*(which the onlybarin scope after excludinguse bar::baritself)
I'd still be ok with replacing the former ICE with an error though, since that's a more conservative choice.
Actually enabling the property "name resolve to the same thing whether some items were excluded during its resolution to avoid cycles or not" may be useful for using something like "inference variables" for unresolved imports and making import resolution more like unification in type inference.
That's an idea I had for quite some, but I hadn't realized that merging #70236 went against it.
Reacted by Esteban KuberSigh, the issue already affects three stable releases - from 1.44 to 1.46.
I'll try to prioritize it.Reacted by Iago-lito and Dmitry MurzinReacted by Jonas Schievink and Vlad Beskrovny- addedregression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
on Oct 1, 2020 - addedI-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
on Oct 1, 2020 Addressed in #77421.
- removedI-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
on Oct 1, 2020 Assigning
P-highso this isn't lost. See the relevant discussion.The fix caused some regressions - #77586.
@petrochenkov The code in the issue produce no errors using Rust 1.67.1. Should we re-open the issue or is it not considered a bug now?
@vlad20012
The fix was reverted due to breakage (#78784) and the current behavior is considered by design since then.Reacted by Vlad Beskrovny(Also it's not exactly a time travel - #77586 (comment).)
I tried this code:
I expected to see this happen: Compilation error. This
use bar::bar;shadows one (glob-imported)barwith anotherbar. As far as I know, this should be forbidden.Instead, this happened: this code successfully compiled.
Meta
rustc --version --verbose:c.c. @matklad
c.c. @petrochenkov