rust-lang / rust-lang/rust

[generic_const_exprs] [nightly] Unable to unify a const generic expression with its value

Open
#153,393 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug F-generic_const_exprs T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code

Hi all,

I was doing some Rust using the incomplete generic_const_exprs feature in an old compiler nightly compiler and, when I tried to update to the latest nightly version, it looks like some behavior have changed, that I consider a regression.

This code used to compile in rustc 1.89.0-nightly (2eef47813 2025-05-22):

I tried this code:

#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

pub trait MyTrait {
    const N: usize;

    fn do_something(&mut self) -> [u32; Self::N];
}

pub struct MyStruct<A> {
    _phantom: core::marker::PhantomData<A>,
}

impl<A> MyTrait for MyStruct<A> {
    const N: usize = 1;

    fn do_something(&mut self) -> [u32; Self::N] {
        [1]
    }
}

This code stopped compiling on rustc 1.89.0-nightly (3e674b06b 2025-05-23), and the error still happening on the latest nightly compiler (rustc 1.96.0-nightly (d9563937f 2026-03-03), failing to compile with the following error:

error[E0308]: mismatched types
  --> src/lib.rs:18:9
   |
18 |         [1]
   |         ^^^ expected `Self::N`, found `1`
   |
   = note: expected constant `Self::N`
              found constant `1`

It looks like the new compiler is refusing to unify the value 1 with Self::N, even though the current impl does state that N = 1. Additionally, this wouldn't work either in the broken rustc versions:

[...]

impl<A> MyTrait for MyStruct<A> {
    const N: usize = 1;

    fn do_something(&mut self) -> [u32; 1] {
        [1]
    }
}

(Note the change in the do_something function signature)

This will fail with the following error, and presumably for the same reasons:

error[E0308]: method not compatible with trait
  --> src/lib.rs:17:5
   |
17 |     fn do_something(&mut self) -> [u32; 1] {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::N`, found `1`
   |
   = note: expected constant `Self::N`
              found constant `1`

However, if we remove the generic type A from the struct definition, it will compile on any of the aforementioned rustc versions:

#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

pub trait MyTrait {
    const N: usize;

    fn do_something(&mut self) -> [u32; Self::N];
}

pub struct MyStruct {
    _unused: u32
}

impl MyTrait for MyStruct {
    const N: usize = 1;

    fn do_something(&mut self) -> [u32; Self::N] {
        [1]
    }
}

I would consider this a regression, and I will appreciate someone taking a look into this. Thanks in advance!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the two provided reproductions with the listed nightly versions and compare the generic-parameter and non-generic cases. Then trace the compiler's handling of generic_const_exprs when checking the associated const against the array length. Done means adding a regression test that captures the intended behavior and restoring or documenting consistent compilation.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.