Why does this code not work?
trait Wrappers {
type Wrapper<'a>
where
Self: 'a;
}
fn foo<W1, W2, F>(f: F)
where
W1: Wrappers,
W2: Wrappers,
F: for<'a> Fn(W1::Wrapper<'a>) -> W2::Wrapper<'a>,
{
}
playground
The error message is:
error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
--> src/lib.rs:11:39
|
11 | F: for<'a> Fn(W1::Wrapper<'a>) -> W2::Wrapper<'a>,
| ^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0582`.
this is a tricky one, I sort of understand the reason, but I don't know how to fix. the problem comes from the Fn()
sugar syntax. if you know the desugared syntax, you'll probably get an rough idea.
the sugar syntax Fn(A1, A2) -> Ret
can be desugared to Fn<(A1, A2), Output = Ret>
, note the return type is an associated type instead of generic parameter. that's the what the compile error message means. but I don't know how to express your idea in rust.
1 Like
Crazy. this works: F: for<'a> Fn(&'a (), W1::Wrapper<'a>) -> W2::Wrapper<'a>
.
1 Like
is this acceptable? I use a custom trait instead of the Fn
trait:
trait Map<From, To> {
fn map(&self, from: From) -> To;
}
impl<From, To, F> Map<From, To> for F where F: Fn(From) -> To {
fn map(&self, from: From) -> To {
self(from)
}
}
fn foo<W1, W2, F>(f: F)
where
W1: Wrappers,
W2: Wrappers,
F: for<'a> Map<W1::Wrapper<'a>, W2::Wrapper<'a>>,
{
}
Is this a bug of the compiler?