Skip to content
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 some_crate as some_name breaks glob imports #52141

Closed
CryZe opened this issue Jul 7, 2018 · 4 comments · Fixed by #52923
Closed

[Rust 2018] pub use some_crate as some_name breaks glob imports #52141

CryZe opened this issue Jul 7, 2018 · 4 comments · Fixed by #52923
Assignees
Labels
A-rust-2018-preview Area: The 2018 edition preview C-bug Category: This is a bug. P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Milestone

Comments

@CryZe
Copy link
Contributor

CryZe commented Jul 7, 2018

Let's say lib.rs contains:

pub use some_crate as some_name;

in order to make a crate available as a different name, using a glob import in the same crate (but other file) as such:

use crate::some_name::*;

doesn't actually import anything into scope, while using explicit imports or pub extern crate some_crate as some_name; instead works. This is possibly related to #52140

@stokhos stokhos added the A-edition-2018-lints Area: Lints supporting the 2018 edition label Jul 8, 2018
@alexcrichton alexcrichton removed the A-edition-2018-lints Area: Lints supporting the 2018 edition label Jul 11, 2018
@Mark-Simulacrum Mark-Simulacrum added C-bug Category: This is a bug. A-rust-2018-preview Area: The 2018 edition preview labels Jul 11, 2018
@aturon aturon added this to the Rust 2018 Release Candidate milestone Jul 24, 2018
@aturon aturon added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 24, 2018
@aturon
Copy link
Member

aturon commented Jul 24, 2018

cc @petrochenkov

@pnkfelix
Copy link
Member

pnkfelix commented Aug 2, 2018

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?

@petrochenkov
Copy link
Contributor

The reason is probably that resolution for single-segment imports is implemented as a special case in fn finalize_import, it probably should happen in some other function that's called earlier than "finalize".

If someone can investigate this now, please do.
I'll be able to do it in 3-4 weeks.

@nikomatsakis
Copy link
Contributor

Visiting during compiler meeting. It appears that @eddyb and @petrochenkov have been discussing this bug over in #52923, going to assign to @eddyb

bors added a commit that referenced this issue Aug 14, 2018
#[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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rust-2018-preview Area: The 2018 edition preview C-bug Category: This is a bug. P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants