Type mismatch between associated type and concrete type which are the same type.
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.
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
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
@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
@eddyb Is this https://github.com/rust-lang/rust/issues/30867? It looks similar...
Mark Rousskov at 2017-05-06 03:00:58
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
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
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 errorSteve Klabnik at 2019-09-24 01:54:27
Are there any plans to fix this?
Kazantcev Andrey at 2020-08-16 10:11:49
Compiles since 1.56.0.
Kalle Wachsmuth at 2023-08-22 20:37:11