Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/items/enumerations.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,25 @@ enum OverflowingDiscriminantError2 {
}
```

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?


> [!EXAMPLE]
> ```rust,compile_fail
> #[repr(u32)]
> enum E<'a, T, const N: u32> {
> Lifetime(&'a T) = {
> let a: &'a (); // ERROR: generic parameters may not be used in enum discriminant
> 1
> },
> Type(T) = {
> let x: T; // ERROR: generic parameters may not be used in enum discriminant
> 2
> },
> Const = N, // ERROR: generic parameters may not be used in enum discriminant
> }
> ```

### Accessing discriminant

#### Via `mem::discriminant`
Expand Down
Loading