Skip to content

Support importing enum variants through type aliases #83248

Open

Description

@bstrie

RFC 2338 made it possible to access enum variants through type aliases, like so:

enum Foo { F1, F2 }
type Bar = Foo;
let x = Bar::F1;

However, the following code still fails to compile:

enum Foo { F1, F2 }
type Bar = Foo;
use Bar::F1;

with:

error[E0432]: unresolved import `Bar`
 --> src/main.rs:6:5
  |
6 | use Bar::F1;
  |     ^^^ `Bar` is a type alias, not a module

Type aliases being limited in this way is a problem for libstd because it means that deprecating/renaming any enum must inevitably involve a breaking change, since re-exporting cannot be used (#30827). This was encountered in #82122 (review) .

Activity

  1. added
    A-resolveArea: Name/path resolution done by `rustc_resolve` specifically
    C-bugCategory: This is a bug.
    T-langRelevant to the language team
    on Mar 18, 2021
  2. eddyb commented on Mar 18, 2021

    @eddyb
    Contributor

    cc @petrochenkov

    The reason EnumAlias::Variant even works, AIUI, is that it desugars to <EnumAlias<..>>::Variant, which is type-based name resolution, and therefore cannot be supported in imports (as it would require understanding the type without a typesystem to speak of).

    You're probably better off trying to distinguish between imports of the original vs a reexport, for determining the deprecated status.

  3. bstrie commented on Mar 18, 2021

    @bstrie
    ContributorAuthor

    @eddyb Is this the same reason that importing associated items doesn't work? I recall a tentative proposal for that from a few years ago: https://internals.rust-lang.org/t/importing-associated-constants/6610/4 , but I'm not sure what the current thinking is. Is it just something that's probably never going to be supported?

  4. eddyb commented on Mar 24, 2021

    @eddyb
    Contributor

    Is this the same reason that importing associated items doesn't work?

    @bstrie Yeah. In theory, you can use Foo::Variant (and any limitations are likely accidental) today with:

    type Foo = <X as Trait<Y>>::AssocType;

    You could imagine getting CTFE involved as well, so that the type can only be known after const-evaluating an arbitrarily complex expression with miri.

    This is the sort of thing that separates the type-relative name resolution, from the regular name resolution: the typesystem itself has to be present for the former, but cannot soundly exist until the latter is complete.

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-resolveArea: Name/path resolution done by `rustc_resolve` specificallyC-bugCategory: This is a bug.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions