Type mismatch between associated type and concrete type which are the same type.

3612558
Opened by Andrew Cann at 2024-12-21 05:10:32

Trying to build the following code:

trait WithLifetime<'a> {
    type Type;
}

struct Foo;

enum FooRef {}

impl<'a> WithLifetime<'a> for FooRef {
    type Type = &'a Foo;
}

fn wub<T, F>(f: F)
    where T: for<'a> WithLifetime<'a>,
          F: for<'a> FnOnce(&'a Foo) -> <T as WithLifetime<'a>>::Type
{
}

fn main() {
    wub::<FooRef, _>(|foo| foo)
}

Gives the error:

foo.rs:20:28: 20:31 error: mismatched types:
 expected `<FooRef as WithLifetime<'a>>::Type`,
    found `&'a Foo`
(expected associated type,
    found &-ptr) [E0308]
foo.rs:20     wub::<FooRef, _>(|foo| foo)
                                     ^~~

However <FooRef as WithLifetime<'a>>::Type and &'a Foo are the same type. And the compiler should be able to see that.

  1. cc @arielb1 @nikomatsakis Which issue is this a dupe of? I never can find which one is canonical.

    @canndrew I believe is this is the usual "associated type projection under HRTB just doesn't get normalized" which is a limitation of the current implementation. @soltanmm, IIRC, tried to approach a solution, but I haven't heard from them in a while.

    Eduard-Mihai Burtescu at 2016-06-23 16:28:02

  2. Is there any workaround that you know of to trick it into normalising?

    Edit: Welp, explicitly specifying the return type of the closure makes it ICE.

    Andrew Cann at 2016-06-23 16:48:19

  3. @eddyb I'm still here! I've just also been... everywhere else. There's a lot of 'everywhere else'...

    Lazy normalization AFAIK should cover this, and is WIP.

    soltanmm at 2016-06-24 17:04:09

  4. @eddyb Is this https://github.com/rust-lang/rust/issues/30867? It looks similar...

    Mark Rousskov at 2017-05-06 03:00:58

  5. Related, certainly. In general we don't really normalize under binders (Yet! Coming Soon, I hope!) which leads to a lot of problems.

    Niko Matsakis at 2017-05-08 21:26:07

  6. What's the status of this issue at the moment? I seem to run into it a couple of times a year.

    Dylan Ede at 2018-04-14 08:40:50

  7. Triage: error message is different now:

       Compiling playground v0.0.1 (/playground)
    error[E0271]: type mismatch resolving `for<'a> <[closure@src/main.rs:20:22: 20:31] as std::ops::FnOnce<(&'a Foo,)>>::Output == <FooRef as WithLifetime<'a>>::Type`
      --> src/main.rs:20:5
       |
    20 |     wub::<FooRef, _>(|foo| foo)
       |     ^^^^^^^^^^^^^^^^ expected &Foo, found associated type
       |
       = note: expected type `&Foo`
                  found type `<FooRef as WithLifetime<'_>>::Type`
    note: required by `wub`
      --> src/main.rs:13:1
       |
    13 | / fn wub<T, F>(f: F)
    14 | |     where T: for<'a> WithLifetime<'a>,
    15 | |           F: for<'a> FnOnce(&'a Foo) -> <T as WithLifetime<'a>>::Type
    16 | | {
    17 | | }
       | |_^
    
    error: aborting due to previous error
    

    Steve Klabnik at 2019-09-24 01:54:27

  8. Are there any plans to fix this?

    Kazantcev Andrey at 2020-08-16 10:11:49

  9. Compiles since 1.56.0.

    Kalle Wachsmuth at 2023-08-22 20:37:11