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

the name std is defined multiple times #59243

Closed
Riateche opened this issue Mar 16, 2019 · 5 comments · Fixed by #59296
Closed

the name std is defined multiple times #59243

Riateche opened this issue Mar 16, 2019 · 5 comments · Fixed by #59296
Labels
A-metadata Area: Crate metadata A-resolve Area: Name resolution

Comments

@Riateche
Copy link

The error happens on latest stable and nightly.
Steps to reproduce: cargo new --lib lib1;
src/lib.rs:

pub mod std {
}

tests/test1.rs:

use lib1;
fn main() {
}

cargo test returns error:

error[E0260]: the name `std` is defined multiple times
  |
  = note: `std` must be defined only once in the type namespace of this module

The error only happens if the module is named std (for instance, core and alloc work without error). The error is not produced if test1.rs doesn't use lib1 in any way. If test1.rs doesn't contain imports but uses the library directly (e.g. ::lib1::x()), the error is produced. cargo build always succeeds.

I don't know if this is supposed to be forbidden but the error message seems to be misleading.

@petrochenkov
Copy link
Contributor

The second instance is extern crate std; injected implicitly.
The error could be better, yes.

@petrochenkov petrochenkov added A-diagnostics Area: Messages for errors, warnings, and lints A-resolve Area: Name resolution labels Mar 16, 2019
@Riateche
Copy link
Author

Where exactly is extern crate std; injected - in the library or in the test? Why does the library work on its own? Why does extern crate std conflict with lib1::std in the test?

@petrochenkov petrochenkov self-assigned this Mar 17, 2019
@petrochenkov
Copy link
Contributor

Ok, it turns out this is a legitimate bug, I misinterpreted it as a more commonly reported diagnostic issue.

extern crate std; is injected into both the library and the test, but only the first one causes the error.

If you set edition = "2015" in Cargo.toml, then you'll see the error immediately while compiling lib.rs - mod std conflicts with extern crate std.

On 2018 edition, however, extern crate std; is injected in more subtle way, as extern crate gensym(std); where gensym(std) is some unique symbol that still has the string representation "std", but doesn't clash with anything in the same crate.
Unfortunately, gensym(std) turns into "just std" after encoding into metadata in the compiled library liblib1.rlib (this is the bug).
So, when we load that library from the test it looks like the library defines two conflicting items.

@petrochenkov
Copy link
Contributor

The solution is to either encode gensyms/hygiene into metadata properly (this is a large task and a long standing issue), or come up with some hack preventing the injected extern crate std specifically from being encoded (it doesn't really need to be encoded).

@petrochenkov petrochenkov added A-metadata Area: Crate metadata and removed A-diagnostics Area: Messages for errors, warnings, and lints labels Mar 18, 2019
@petrochenkov
Copy link
Contributor

Fixed in #59296

Centril added a commit to Centril/rust that referenced this issue Mar 19, 2019
Do not encode gensymed imports in metadata

(Unless they are underscore `_` imports which are re-gensymed on crate loading, see rust-lang#56392.)

We cannot encode gensymed imports properly in metadata and if we encode them improperly, we can get erroneous name conflicts downstream.
Gensymed imports are produced by the compiler, so we control their set, and can be sure that none of them needs being encoded for use from other crates.

A workaround that fixes rust-lang#59243.
@petrochenkov petrochenkov removed their assignment Mar 20, 2019
kennytm added a commit to kennytm/rust that referenced this issue Mar 24, 2019
Do not encode gensymed imports in metadata

(Unless they are underscore `_` imports which are re-gensymed on crate loading, see rust-lang#56392.)

We cannot encode gensymed imports properly in metadata and if we encode them improperly, we can get erroneous name conflicts downstream.
Gensymed imports are produced by the compiler, so we control their set, and can be sure that none of them needs being encoded for use from other crates.

A workaround that fixes rust-lang#59243.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-metadata Area: Crate metadata A-resolve Area: Name resolution
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants