Skip to content

Confusing mismatched type error message with generic_const_exprs #82619

Open
@roboFiddle

Description

I'd be happy to try to fix this, but some pointers on where to start would be greatly appreciated.

Given the following code - playground:

#![allow(incomplete_features)]
#![feature(const_generics)]
#![feature(const_evaluatable_checked)]

use std::ops::Add;

struct ConstWrapper<const N: usize>;
impl<const N1: usize, const N2: usize> Add<ConstWrapper<N2>> for ConstWrapper<N1>
where ConstWrapper<{N1 + N2}>: Sized
{
   type Output = ConstWrapper<{N1 + N2}>;
   fn add(self, _other: ConstWrapper<N2>) -> Self::Output {
       ConstWrapper
   }
}

struct WrapConstWrapper<T>(T);
impl<T1: Add<T2>, T2> Add<WrapConstWrapper<T2>> for WrapConstWrapper<T1> {
    type Output = WrapConstWrapper<<T1 as Add<T2>>::Output>;
    fn add(self, other: WrapConstWrapper<T2>) -> Self::Output {
        WrapConstWrapper ( self.0 + other.0 )
    }
}

fn get_0() -> WrapConstWrapper<ConstWrapper<0>> {
    WrapConstWrapper(ConstWrapper)
}

fn main() {
    let x: WrapConstWrapper<ConstWrapper<1>> = get_0() + get_0();
    let y = get_0() + get_0();
    let z: WrapConstWrapper<ConstWrapper<1>>;
    z = y;
}

The current output is:

error[E0308]: mismatched types
  --> src/main.rs:30:48
   |
30 |     let x: WrapConstWrapper<ConstWrapper<1>> = get_0() + get_0();
   |                                                ^^^^^^^^^^^^^^^^^ expected `1_usize`, found `0_usize`
   |
   = note: expected type `1_usize`
              found type `0_usize`

error[E0308]: mismatched types
  --> src/main.rs:33:9
   |
33 |     z = y;
   |         ^ expected `1_usize`, found `0_usize`
   |
   = note: expected struct `WrapConstWrapper<ConstWrapper<1_usize>>`
              found struct `WrapConstWrapper<ConstWrapper<0_usize>>`

Ideally, the error messages would be identical. Removing the {N1 + N2} calculation allows the compiler to provide the same error message for both bindings (as seen here). It appears that the compiler is stopping at the mismatched constant instead of evaluating the entire type of get_0() + get_0().

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsD-papercutDiagnostics: An error or lint that needs small tweaks.F-generic_const_exprs`#![feature(generic_const_exprs)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions