Skip to content

the name std is defined multiple times #59243

Closed

Description

@Riateche

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.

Activity

  1. petrochenkov commented on Mar 16, 2019

    @petrochenkov
    Contributor

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

  2. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    A-resolveArea: Name/path resolution done by `rustc_resolve` specifically
    on Mar 16, 2019
  3. Riateche commented on Mar 16, 2019

    @Riateche
    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?

  4. self-assigned this
    on Mar 17, 2019
  5. petrochenkov commented on Mar 18, 2019

    @petrochenkov
    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.

  6. petrochenkov commented on Mar 18, 2019

    @petrochenkov
    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).

  7. added
    A-metadataArea: Crate metadata
    and removed
    A-diagnosticsArea: Messages for errors, warnings, and lints
    on Mar 18, 2019
  8. petrochenkov commented on Mar 19, 2019

    @petrochenkov
    Contributor

    Fixed in #59296

  9. added a commit that references this issue on Mar 19, 2019
  10. removed their assignment
    on Mar 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-metadataArea: Crate metadataA-resolveArea: Name/path resolution done by `rustc_resolve` specifically

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions