Skip to content

Ambiguous item error fails to trigger when use is declared before the source #112713

Closed
@P1n3appl3

Description

@P1n3appl3

With the following code:

pub fn foo() -> u32 {
    use sub::*;
    C
}

mod sub {
    mod mod1 { pub const C: u32 = 1; }
    mod mod2 { pub const C: u32 = 2; }

    pub use mod1::*;
    pub use mod2::*;
}

We expected to see this compiler error.

Instead, the compiler accepts it and foo() returns 1. We found that if you move foo below sub, you do get the expected error. @ComputerDruid and I took a while to repro this, because we assumed that the order in which you define functions/modules shouldn't change the semantics. It appears that glob re-exports are also necessary for this behavior to occur. If you change it to:

    pub use mod1::*;
    pub use mod2::C;

The explicit one will shadow the glob regardless of where foo is defined, and if you make both explicit, it'll trigger this error.

You can see the difference if you uncomment the bottom function in this playground link. Even changing the import within foo to use sub::C will make it trigger the expected ambiguous item error, so both of the re-exports and the import have to be globs to see the weird behavior.

This may be a separate issue, but in the accepted code if you swap the order of the glob re-exports in sub, foo() will return 2, suggesting that whichever one is re-exported first "wins".

rustc --version --verbose:

rustc 1.70.0 (90c541806 2023-05-31)

(same behavior on nightly)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-local-reexportsArea: Documentation that has been locally re-exported (i.e., non-cross-crate)A-resolveArea: Name/path resolution done by `rustc_resolve` specificallyC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions