Skip to content

Compiler not realizing an impl is more specific than another when using const generic bounds #138308

Closed
@Absobel

Description

@Absobel

I tried this code which creates a register and an operation to decrease it's value by one or change it's value to another register. All of that at compile time.

#![feature(generic_const_exprs)]

trait _DecOr<E> {
    type O;
}

struct R1<const N: usize>;

impl<E> _DecOr<E> for R1<0> {
    type O = E;
}

impl<const N:usize, E> _DecOr<E> for R1<N> where [(); N - 1]: {
    type O = R1<{N - 1}>;
}

I expected it to work with no errors.

Instead, this happened:

   Compiling mintypesky v0.1.0 (/home/absobel/Mir/GitRepos/MinTypeSky)
error[E0080]: evaluation of `<R1<0> as _DecOr<!0>>::{constant#0}` failed
  --> src/main.rs:25:55
   |
25 | impl<const N:usize, E> _DecOr<E> for R1<N> where [(); N - 1]: {
   |                                                       ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow

error[E0080]: evaluation of `<R1<0> as _DecOr<E>>::{constant#0}` failed
  --> src/main.rs:25:55
   |
25 | impl<const N:usize, E> _DecOr<E> for R1<N> where [(); N - 1]: {
   |                                                       ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow

For more information about this error, try `rustc --explain E0080`.
error: could not compile `mintypesky` (bin "mintypesky") due to 2 previous errors

It looks like the compiler evaluates the second impl with all values of N instead of realizing there is a more specific one for N=0. Also the error message is duplicated ?

It may be related to #112341. Maybe other issues but I didn't find them.
Obviously related to #76560 too

Meta

rustc --version --verbose:

rustc 1.83.0-nightly (fa724e5d8 2024-09-27)
binary: rustc
commit-hash: fa724e5d8cbbdfbd1e53c4c656121af01b694406
commit-date: 2024-09-27
host: x86_64-unknown-linux-gnu
release: 1.83.0-nightly
LLVM version: 19.1.0

I kind of expect this issue to get no answer so I might try to solve it myself. It will make for a nice project to plunge into.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-discussionCategory: Discussion or questions that doesn't represent real issues.F-generic_const_exprs`#![feature(generic_const_exprs)]`

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions