rust-lang / rust-lang/rust

Overflow evaluating the requirement when adding const generic bound

Open
#119,690 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-const-generics C-bug T-compiler
Dominant language
Rust
Stars
119k
Forks
16.2k
PR merge metrics
PR metrics pending

Description

I tried this code:

use std::{ops::Mul};

struct Quantity<S, const D: usize>(S);

impl<const D: usize, S> Mul<Quantity<S, D>> for f32
where
    f32: Mul<S>,
    Quantity<<f32 as Mul<S>>::Output, D>:
{
    type Output = Quantity<<f32 as Mul<S>>::Output, { D }>;
    fn mul(self, rhs: Quantity<S, D>) -> Self::Output {
        Quantity(self * rhs.0)
    }
}

I realize that the second trait bound for the const generic is unnecessary here. I needed it in the code I originally wanted to write (where I had a const expr in its place), but writing it this way got me to reproduce this bug on stable and without needing generic_const_exprs.

I expected it to compile. Instead, I get

error[E0275]: overflow evaluating the requirement `f32: Mul<Quantity<_, _>>`

It compiles fine without the additional bound:

use std::{ops::Mul};

struct Quantity<S, const D: usize>(S);

impl<const D: usize, S> Mul<Quantity<S, D>> for f32
where
    f32: Mul<S>,
{
    type Output = Quantity<<f32 as Mul<S>>::Output, { D }>;
    fn mul(self, rhs: Quantity<S, D>) -> Self::Output {
        Quantity(self * rhs.0)
    }
}

This seemed similar to https://github.com/rust-lang/rust/issues/79807 but I do not run into the same error if I replace the bound by <f32 as Mul<S>>::Output: Copy , for example.

As a side comment, a way to get the code to compile with the const generic trait bound is to write something like Quantity<(), D>: or even Quantity<Vec<Vec<String>>, D>:. It doesn't seem to matter at all what the first generic of Quantity is, which was very confusing to me - if the compiler only cares about the const expr evaluating, then why does that need to be expressed in a bound on Quantity and not in a more direct way?

Meta

rustc --version --verbose:

rustc 1.75.0 (82e1608df 2023-12-21)
binary: rustc
commit-hash: 82e1608dfa6e0b5569232559e3d385fea5a93112
commit-date: 2023-12-21
host: x86_64-unknown-linux-gnu
release: 1.75.0
LLVM version: 17.0.6

and on nightly:


rustc 1.77.0-nightly (d6d7a9386 2023-12-22)
binary: rustc
commit-hash: d6d7a93866f2ffcfb51828b8859bdad760b54ce0
commit-date: 2023-12-22
host: x86_64-unknown-linux-gnu
release: 1.77.0-nightly
LLVM version: 17.0.6

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 minimal Quantity/Mul reproducer with the stable 1.75.0 and nightly versions listed in the report, then investigate the trait obligation evaluation that produces the overflow for the additional const-generic bound. Done means the valid example compiles without the overflow, with a regression test covering the reproducer.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.