Open
Description
I tried this code:
#![feature(generic_associated_types)]
pub trait Func<'a, T> {
type Output;
fn invoke(&mut self, x: T) -> Self::Output;
}
impl<'a, T, U, F> Func<'a, T> for &'a mut F
where
F: FnMut(T) -> U,
{
type Output = U;
fn invoke(&mut self, x: T) -> Self::Output {
self(x)
}
}
trait Foo {
type Bar<'a>
where
Self: 'a;
fn test<F>(f: F)
where
for<'a> &'a mut F: Func<'a, Self::Bar<'a>>;
}
impl Foo for () {
type Bar<'a> = &'a ();
fn test<F>(mut f: F)
where
for<'a> &'a mut F: Func<'a, Self::Bar<'a>>,
{
(&mut f).invoke(&());
}
}
fn main() {
let f: fn(&()) -> &() = |t| t;
<()>::test(f); //works
<()>::test(|t| t); //error
}
I expected to see this happen: Code compiles without errors.
Instead, this happened:
Compiling playground v0.0.1 (/playground)
error: implementation of `FnOnce` is not general enough
--> src/main.rs:33:5
|
33 | <()>::test(|t|t); //error
| ^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 ()) -> &()` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
error: could not compile `playground` due to previous error
The compiler needs closures to be explicitly coerced into a general enough type for the provided trait bounds to work. It's not the end of the world, because I can always use trait objects, but it's definitely an ergonomic issue. Also, it works just fine if you use a non-generic associated type.
Meta
Playground version:
1.64.0-nightly
(2022-07-30 0f4bcadb46006bc484da)