-
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
[Rust 2018] pub use can't export crates #52140
Comments
Got bit by this today. It's extra bad because it should work... took me a while to convince myself this was a bug, and it wasn't until I asked on Discord that it was confirmed. |
as with #52141: visited for triage. P-high. Not sure who is going to work on it; @petrochenkov do you think you have space on your plate to look at this? |
The reason is probably that resolution for single-segment imports is implemented as a special case in If someone can investigate this now, please do. |
Visiting during compiler meeting. It appears that @eddyb and @petrochenkov have been discussing this bug over in #52923, going to assign to @eddyb |
#[feature(uniform_paths)]: allow `use x::y;` to resolve through `self::x`, not just `::x`. _Branch originally by @cramertj, based on @petrochenkov's [description on the internals forum](https://internals.rust-lang.org/t/relative-paths-in-rust-2018/7883/30?u=petrochenkov)._ _(note, however, that the approach has significantly changed since)_ Implements `#[feature(uniform_paths)]` from #53130, by treating unqualified `use` paths as maybe-relative. That is, `use x::y;`, where `x` is a plain identifier (not a keyword), is no longer the same as `use ::x::y;`, and before picking an external crate named `x`, it first looks for an item named `x` in the same module (i.e. `self::x`) and prefers that local item instead. Such a "maybe-relative" `x` can only resolve to an external crate if it's listed in "`extern_prelude`" (i.e. `core` / `std` and all the crates passed to `--extern`; the latter includes Cargo dependencies) - this is the same condition as being able to refer to the external crate from an unqualified, non-`use` path. All other crates must be explicitly imported with an absolute path, e.g. `use ::x::y;` To detect an ambiguity between the external crate and the local item with the same name, a "canary" import (e.g. `use self::x as _;`), tagged with the `is_uniform_paths_canary` flag, is injected. As the initial implementation is not sophisticated enough to handle all possible ways in which `self::x` could appear (e.g. from macro expansion), this also guards against accidentally picking the external crate, when it might actually get "shadowed" later. Also, more canaries are injected for each block scope around the `use`, as `self::x` cannot resolve to any items named `x` in those scopes, but non-`use` paths can, and that could be confusing or even backwards-incompatible. Errors are emitted only if the main "canary" import succeeds while an external crate exists (or if any of the block-scoped ones succeed at all), and ambiguities have custom error reporting, e.g.: ```rust #![feature(uniform_paths)] pub mod foo { use std::io; pub mod std { pub mod io {} } } ``` ```rust error: import from `std` is ambiguous --> test.rs:3:9 | 3 | use std::io; | ^^^ could refer to external crate `::std` 4 | pub mod std { pub mod io {} } | ----------------------------- could also refer to `self::std` | = help: write `::std` or `self::std` explicitly instead = note: relative `use` paths enabled by `#![feature(uniform_paths)]` ``` Another example, this time with a block-scoped item shadowing a module-scoped one: ```rust #![feature(uniform_paths)] enum Foo { A, B } fn main() { enum Foo {} use Foo::*; } ``` ```rust error: import from `Foo` is ambiguous --> test.rs:5:9 | 4 | enum Foo {} | ----------- shadowed by block-scoped `Foo` 5 | use Foo::*; | ^^^ | = help: write `::Foo` or `self::Foo` explicitly instead = note: relative `use` paths enabled by `#![feature(uniform_paths)]` ``` Additionally, this PR, because replacing "the `finalize_import` hack" was a blocker: * fixes #52140 * fixes #52141 * fixes #52705 cc @aturon @joshtriplett
If instead of
pub extern crate some_crate;
you usepub use some_crate;
in Rust 2018, the crate isn't actually reexported.The text was updated successfully, but these errors were encountered: