Skip to content

Importing an enum variant can create a conflict with a new prelude type #127738

Closed as not planned

Description

The experiment in #125107 uncovered an interesting source of version breakage, which occurs if the standard library prelude attempts to introduce an additional type.

Suppose std adds the type Cell to the prelude. This will break code that looks like this:

use Cell::A;

// The derive here is important but it doesn't particularly matter which trait is being derived.
#[derive(PartialEq)]
pub enum Cell {
    A
}

Per the comment at #125107 (comment) , this generates an error of the form:

error[E0659]: `Cell` is ambiguous
  --> src/puzzle.rs:5:5
   |
5  | use Cell::{Empty, Unknown, ValA, ValB, ValC, ValD};
   |     ^^^^ ambiguous name
   |
   = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
note: `Cell` could refer to the enum defined here
  --> src/puzzle.rs:8:1
   |
8  | / pub enum Cell {
9  | |     ValA,
10 | |     ValB,
11 | |     ValC,
...  |
14 | |     Unknown,
15 | | }
   | |_^
   = help: use `self::Cell` to refer to this enum unambiguously
note: `Cell` could also refer to a struct from prelude
  --> /rustc/9130c02509ce15f69dc5da6359bb9d140d41d4ac/library/std/src/prelude/mod.rs:148:13

This makes it a potentially breaking change to add new types to the prelude. We could still potentially add types that create no actual breakage (e.g. because no extant Rust code declares its own conflicting type), but this nonetheless introduces a potential source of breakage that could block introducing new types until an edition boundary (and creates one more thing people have to deal with when migrating to the new edition).

It seems worth exploring whether we can, or should, attempt to fix this, such as by allowing the type to shadow in this case. Note that it does properly shadow if there's no derive on the enum.

Nominating for lang discussion on the "should we" question: should we consider doing something to eliminate or mitigate this source of conflict? This kind of conflict applies both to the current problem with the standard library prelude, as well as any potential future features for letting other libraries have preludes.

Nominating for compiler discussion on the "can we" question: to find out how feasible it would be to deprioritize standard library prelude types and make them lower priority than local enums in this case, or to otherwise mitigate the issue that seems to specifically arise when using a derive macro on such types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language 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