Skip to content

Should enum discriminants have generics in scope? #70453

Closed
@eddyb

Description

@eddyb

What are our options?

  1. we teach name resolution (rustc_resolve) to hide enum generic parameters from the discriminant expression
    • this effectively enshrines that we don't want the parameterization to happen
    • I'm not sure this can be backwards-compatible with 2.
  2. we keep the current name resolution support but error if we can't evaluate to concrete values

Examples of current behavior:

Note: #![feature(const_generics)] is used below so that this special-case kicks in:

// FIXME(#43408) enable this always when we get lazy normalization.
Node::AnonConst(_) => {
// HACK(eddyb) this provides the correct generics when

Also, note that the reason for the uniform current treatment (which doesn't consider enum parameters as not in scope of discriminants), is because rustc_resolve treats surrounding generics as being in scope of AnonConsts, always - all the bugs later in compilation are due to the lack of lazy normalization (see #43408).


This ICEs currently (playground):

#![feature(const_generics)]

#[repr(usize)]
enum Foo<T> {
    Zero = 0,
    SizeOf = std::mem::size_of::<T>(),
}

with

error: internal compiler error: src/librustc/ty/mod.rs:2538: enum discriminant depends on generic arguments
 --> src/lib.rs:6:14
  |
6 |     SizeOf = std::mem::size_of::<T>(),
  |              ^^^^^^^^^^^^^^^^^^^^^^^^

Same thing happens if a const parameter is used instead of size_of::<T>().

If we choose option 2, this ICE will turn into a regular error.


EDIT: and this currently compiles on nightly (playground):

#![feature(const_generics, arbitrary_enum_discriminant)]

#[repr(usize)]
enum MyWeirdOption<T> {
    None = 0,
    Some(T) = std::mem::size_of::<*mut T>(),
}

And using *mut *mut T instead of *mut T would make it work even when T: Sized isn't known.
(If not for the substitution failure, you could remove #![feature(const_generics)])


cc @rust-lang/compiler @rust-lang/lang

Metadata

Metadata

Assignees

No one assigned

    Labels

    P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team, which will review and decide on the PR/issue.disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions