Skip to content

Const generic type inference works when it should not #142378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
nazar-pc opened this issue Jun 11, 2025 · 3 comments
Open

Const generic type inference works when it should not #142378

nazar-pc opened this issue Jun 11, 2025 · 3 comments
Labels
A-inference Area: Type inference C-bug Category: This is a bug. F-generic_const_exprs `#![feature(generic_const_exprs)]` P-low Low priority requires-incomplete-features This issue requires the use of incomplete features. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@nazar-pc
Copy link

I tried this code:

#![expect(incomplete_features, reason = "generic_const_exprs")]
#![feature(generic_const_exprs)]

pub fn compute_root_only<const N: u64>() -> u64
where
    [(); N.ilog2() as usize]:,
{
    N
}

#[test]
fn test() {
    test_impl::<99>();
}

#[cfg(test)]
fn test_impl<const N: u64>()
where
    [(); N.ilog2() as usize]:,
{
    // Const generic is inferred, but it shouldn't be!
    assert_eq!(compute_root_only(), N);
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=1b2f4edef4886032e1f9391f671112f4

I expected to see this happen:

error[E0284]: type annotations needed
  --> src/lib.rs:22:16
   |
22 |     assert_eq!(compute_root_only(), N);
   |                ^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `compute_root_only`
   |
note: required by a const generic parameter in `compute_root_only`
  --> src/lib.rs:4:26
   |
4  | pub fn compute_root_only<const N: u64>() -> u64
   |                          ^^^^^^^^^^^^ required by this const generic parameter in `compute_root_only`
help: consider specifying the generic argument
   |
22 |     assert_eq!(compute_root_only::<N>(), N);
   |                                 +++++

Instead, this happened: It compiles successfully 🤯

The key thing is where bound. If it is simplified to something simpler like this:

where
    [(); N]:,

Then I do get expected compiler error.

This is basically a miscompilation, compiler should not pick arbitrary matching where bound from the context of the caller to infer types of the called function unless corresponding constant is used explicitly.

Meta

rustc --version --verbose:

rustc 1.89.0-nightly (cdd545be1 2025-06-07)
binary: rustc
commit-hash: cdd545be1b4f024d38360aa9f000dcb782fbc81b
commit-date: 2025-06-07
host: x86_64-unknown-linux-gnu
release: 1.89.0-nightly
LLVM version: 20.1.5
@nazar-pc nazar-pc added the C-bug Category: This is a bug. label Jun 11, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jun 11, 2025
@workingjubilee
Copy link
Member

workingjubilee commented Jun 11, 2025

... sorry, trying to understand this report. Isn't the inference correct?

@nazar-pc
Copy link
Author

nazar-pc commented Jun 11, 2025

It is correct here, but I didn't specify the value of const N for compute_root_only() and this is a completely arbitrary guess, there is no direct connection between two functions.

This is the first ever instance where I see a behavior like this. If this was intentional, I would have expected for [(); N]:, to have the same effect and from there probably non-const generics to be inferred the same way too, but none of that is actually the case except for this interesting special case.

@fmease fmease added P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. F-generic_const_exprs `#![feature(generic_const_exprs)]` requires-incomplete-features This issue requires the use of incomplete features. A-inference Area: Type inference and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Jun 11, 2025
@fmease
Copy link
Member

fmease commented Jun 11, 2025

Smaller:

#![feature(generic_const_exprs)]

fn f<const N: usize>() where [(); N as _]: {}
fn g<const N: usize>() where [(); N as _]: { f() }

Reproduces when the where-clauses match 100% and if the const parameter is involved "non-trivially" (N would be "trivial"; N as _ / std::convert::identity(N) would be "non-trivial" ((N) crashes but that's been reported already)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inference Area: Type inference C-bug Category: This is a bug. F-generic_const_exprs `#![feature(generic_const_exprs)]` P-low Low priority requires-incomplete-features This issue requires the use of incomplete features. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants