Skip to content

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

Merged
traviscross merged 3 commits intorust-lang:masterfrom
ehuss:enum-discriminant-generic
Mar 17, 2026
Merged

Add a rule that enum discriminants may not use generic parameters#2206
traviscross merged 3 commits 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?

The rule we've been following is that we don't use example admonitions
for examples that directly demonstrate the operation of a normative
rule; we use them for examples that are more general or conceptual,
e.g., "here are some ways that this construct might appear",
generally as part of the introduction.  So let's move the example that
demonstrates this new rule out of an admonition.

Let's also adjust the `ERROR` comments.  We don't generally need
to match what the compiler emits for these.  When we have something
interesting to point out, we can use the space for that.  Here,
there's probably not much to say that isn't already said in the rule,
so let's just say `ERROR`.
The interesting thing about the example in the `items.enum...generics`
rule is that it shows that the generic parameters from the enclosing
enum can't appear anywhere within the initializer of the enum
discriminant.  We don't use "initializer" anywhere on this page yet,
but it is the correct word to use here, so let's use it.
@traviscross traviscross enabled auto-merge March 17, 2026 23:06
@traviscross
Copy link
Contributor

Looks good to me. Thanks.

@traviscross traviscross added this pull request to the merge queue Mar 17, 2026
Merged via the queue into rust-lang:master with commit 65bf656 Mar 17, 2026
6 checks passed
@rustbot rustbot removed the S-waiting-on-review Status: The marked PR is awaiting review from a maintainer label Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants