Skip to content

Add a rule that enum discriminants may not use generic parameters#2206

Open
ehuss wants to merge 1 commit intorust-lang:masterfrom
ehuss:enum-discriminant-generic
Open

Add a rule that enum discriminants may not use generic parameters#2206
ehuss wants to merge 1 commit intorust-lang:masterfrom
ehuss:enum-discriminant-generic

Conversation

@ehuss
Copy link
Contributor

@ehuss ehuss commented Mar 11, 2026

This is implemented in the compiler with the diagnostic ParamInEnumDiscriminant and NoConstantGenericsReason::IsEnumDiscriminant.

@rustbot rustbot added the S-waiting-on-review Status: The marked PR is awaiting review from a maintainer label Mar 11, 2026
```

r[items.enum.discriminant.restrictions.generics]
Explicit enum discriminants may not use generic parameters from the enclosing enum.
Copy link
Contributor

@DanielEScherzer DanielEScherzer Mar 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from the enclosing enum.

What about from anywhere else? Playground says that you also can't use from an enclosing item either

fn demo<const N: u32>() {
    enum Foo {
        Bar = N,
    }
}

though it does also have an unhelpful suggestion to

help: try introducing a local generic parameter here
  |
2 |     enum Foo<N> {
  |             +++

which then leads to

  • same "can't use generic parameters from outer item" error
  • with a new suggestion
help: try introducing a local generic parameter here
  |
2 |     enum Foo<N, N> {
  |              ++
  • and also an error type parameter `N` is never used

I suggest

Suggested change
Explicit enum discriminants may not use generic parameters from the enclosing enum.
Explicit enum discriminants may not use generic parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The restriction that generic parameters are not in scope within items in a function body is covered by items.generics.syntax.scope.

The reason it uses the "enclosing enum" terminology is because generic parameters defined within the enum discriminant initializer may be used, as in:

enum E {
    V1 = {
        const fn f<T>(x: T) -> T { x }
        f::<isize>(123)
    }
}

I didn't want to risk potential confusion around that.

Copy link
Contributor

@DanielEScherzer DanielEScherzer Mar 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the actual discriminant of f::<isize>(123) is not based on any generic parameter, just the invocation of a constant function that happens to be generic, same as

const fn f<T>(x: T) -> T { x }
enum E {
    V1 = {
        f::<isize>(123)
    }
}

what about

Explicit enum discriminants may not use generic parameters. Note that they may still invoke generic functions.

or something like that?

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

Labels

S-waiting-on-review Status: The marked PR is awaiting review from a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants