Skip to content

resolve: Fresh bindings in match/let are preferred to "import ambiguity items" #46079

Closed
@petrochenkov

Description

@petrochenkov

In the example below two glob imports bring two conflicting names V into scope.

enum E1 { V }
use E1::*;

enum E2 { V }
use E2::*; // OK, no conflict with `use E1::*;`

fn main() {
    let v = V; // ERROR `V` is ambiguous
    match v {
        V => {} // No error, `V` is a fresh binding
    }
}

According to RFC 1560 an error is not immediately reported when two globs conflict, it is reported "on use" only if the ambiguous name is actually used.
Internally such an ambiguity creates an "erroneous item" (Def::Err) with name V used exclusively for reporting diagnostics. (However, see #36837, which is an issue closely related to this one.)
For other purposes the name V doesn't exist in our module.

In the example above we can see that in let v = V; V is properly reported as ambiguous on use.

In match however the meaning of V is determined in two-step disambiguation process. First we search for an existing item named V, then if no item named V exists we create a new variable.
Diagnostics-only Def::Err items do not exist from this disambiguation process' point of view, so the first step fails for V and we interpret it as a new variable without any "ambiguous name" warning.

In many cases however, a warning about unused imports will be reported for use E1::*; and use E2::*;, but this happens only if the imports aren't actually used anywhere else and the warnings are not always noticed (see #46078).

Two possible solutions are:

  • Issue some "did you mean the ambiguous import, not new variable?" warning for V in match.
  • Make "import ambiguity items" actual items, affecting not only diagnostics, but name resolution behavior in general, including disambiguation for fresh bindings. This alternative may be better for resolving item_like_imports: Can "ambiguity error" items be reexported? #36837.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-resolveArea: Name/path resolution done by `rustc_resolve` specificallyC-enhancementCategory: An issue proposing an enhancement or a PR with one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions