I have the following (simplified) code, which came up while generalizing the mechanism from my previous question to a callback argument which has a lifetime.
struct ThingWithLifetime<'a> {
borrowed_thing: &'a i32,
}
fn process<Arg, Func>(f: Func)
where
Func: FnMut(Arg) + 'static, // I think here I'd need something like `for<'a> FnMut(Arg<'a>)
Arg: Argument<Func = Box<dyn FnMut(Arg)>>,
{
<Arg as Argument>::process_boxed(Box::new(f))
}
trait Argument {
type Func;
fn process_boxed(func: Self::Func);
}
impl Argument for ThingWithLifetime<'_> {
type Func = Box<dyn for<'b> FnMut(ThingWithLifetime<'b>)>;
fn process_boxed(func: Self::Func) {}
}
fn main() {
let cb = |_msg: ThingWithLifetime<'_>| {};
process(cb);
}
It gives an error
25 | process(|_msg: ThingWithLifetime<'_>| {});
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
= note: expected struct `Box<(dyn for<'b> FnMut(ThingWithLifetime<'b>) + 'static)>`
found struct `Box<(dyn FnMut(ThingWithLifetime<'_>) + 'static)>
How can I adjust the process()
function to make this work with the given Argument
trait and impl? I think I need to express that Func
should not be tied to any specific lifetime of its argument.
I tried various things, like adding for<'a>
in various places to the trait bounds of process()
, but none of them worked. I also tried changing main()
to process(|_msg: ThingWithLifetime<'_>| {})
because type inference around closures can be tricky, but that did not help either.