Skip to content

Generic patterns and generic array lengths can call const fn with impossible generics #147721

@theemathas

Description

@theemathas
// No type implements this trait
unsafe trait NotImplemented {}

const fn lol<T: NotImplemented>() -> usize {
    panic!("This should not be callable");
}

struct Dummy<T>(T);
impl<T: NotImplemented> Dummy<T> {
    const C: usize = lol::<T>();
}

fn foo<T: NotImplemented>() {
    if let Dummy::<T>::C = 1 {}
}

I expected the above code to not execute the panic, either at compile time or run time, since there is no T that implements NotImplemented. Instead, I got the following compiler error:

error[E0080]: evaluation panicked: This should not be callable
  --> src/lib.rs:10:22
   |
10 |     const C: usize = lol::<T>();
   |                      ^^^^^^^^^^ evaluation of `Dummy::<T>::C` failed inside this call
   |
note: inside `lol::<T>`
  --> src/lib.rs:5:5
   |
 5 |     panic!("This should not be callable");
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here

For more information about this error, try `rustc --explain E0080`.

Note that the code compiles fine if I make fn lol return a value normally instead of panicking.

Also note that the code gives a reasonable compile error if I make fn lol return size_of::<T>()

Error with `size_of::()`
error[E0158]: constant pattern cannot depend on generic parameters
  --> src/lib.rs:14:12
   |
 9 | impl<T: NotImplemented> Dummy<T> {
   | --------------------------------
10 |     const C: usize = lol::<T>();
   |     -------------- constant defined here
...
13 | fn foo<T: NotImplemented>() {
   |        - constant depends on this generic parameter
14 |     if let Dummy::<T>::C = 1 {}
   |            ^^^^^^^^^^^^^ `const` depends on a generic parameter

For more information about this error, try `rustc --explain E0158`.

Using an array length instead of a pattern also runs into a similar issue:

Code and error using array length
// No type implements this trait
unsafe trait NotImplemented {}

const fn lol<T: NotImplemented>() -> usize {
    panic!("This should not be callable");
}

struct Dummy<T>(T);
impl<T: NotImplemented> Dummy<T> {
    const C: usize = lol::<T>();
}

fn foo<T: NotImplemented>() {
    let _x = [0u8; Dummy::<T>::C];
}
error[E0080]: evaluation panicked: This should not be callable
  --> src/lib.rs:10:22
   |
10 |     const C: usize = lol::<T>();
   |                      ^^^^^^^^^^ evaluation of `Dummy::<T>::C` failed inside this call
   |
note: inside `lol::<T>`
  --> src/lib.rs:5:5
   |
 5 |     panic!("This should not be callable");
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here

note: erroneous constant encountered
  --> src/lib.rs:14:20
   |
14 |     let _x = [0u8; Dummy::<T>::C];
   |                    ^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0080`.

Meta

Reproducible on the playground with version 1.92.0-nightly (2025-10-13 4b94758d2ba7d0ef71cc)

Metadata

Metadata

Assignees

Labels

A-arrayArea: `[T; N]`A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-patternsRelating to patterns and pattern matchingC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamneeds-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions