How to use a closure instead of a trait?
I want to register Gen::my_g
as a callback. The easy way is to implement trait Foo
for Gen
, but I don't want to implement trait Foo
for Gen
.
In other words, I want to comment out the code marked as B!!!
and uncomment the code marked as A!!!
.
This is not my code; I cannot change this:
struct S1;
struct TT;
trait MyRes {}
trait Foo {
fn g<'a>(&self, ecx: &'a mut S1, tt: &[TT]) -> Box<MyRes + 'a>;
}
impl<F> Foo for F
where
F: for<'a> Fn(&'a mut S1, &[TT]) -> Box<MyRes + 'a>,
{
fn g<'a>(&self, ecx: &'a mut S1, tt: &[TT]) -> Box<MyRes + 'a> {
(*self)(ecx, tt)
}
}
fn f1<F>(name: &str, extension: F)
where
F: Foo + 'static,
{
}
This is my code:
struct Gen {}
impl Gen {
fn register(self) {
// f1("aaa", move |ecx, tt| self.my_g(ecx, tt));//A!!!
f1("aaa", self); //B!!!
}
fn my_g<'a>(&self, ecx: &'a mut S1, tt: &[TT]) -> Box<MyRes + 'a> {
unimplemented!();
}
}
impl Foo for Gen {
fn g<'a>(&self, ecx: &'a mut S1, tt: &[TT]) -> Box<MyRes + 'a> {
self.my_g(ecx, tt)
}
}
If I uncomment //A!!!
, the compiler tells me what I don't understand:
error[E0271]: type mismatch resolving `for<'a, 'r> <[closure@src/main.rs:29:19: 29:52 self:_] as std::ops::FnOnce<(&'a mut S1, &'r [TT])>>::Output == std::boxed::Box<MyRes + 'a>` --> src/main.rs:29:9 | 29 | f1("aaa", move |ecx, tt| self.my_g(ecx, tt)); //A!!! | ^^ expected bound lifetime parameter, found concrete lifetime | = note: concrete lifetime that was found is lifetime '_#12r = note: required because of the requirements on the impl of `Foo` for `[closure@src/main.rs:29:19: 29:52 self:_]` = note: required by `f1` error[E0281]: type mismatch: `[closure@src/main.rs:29:19: 29:52 self:_]` implements the trait `std::ops::Fn<(&mut S1, &[TT])>`, but the trait `for<'a, 'r> std::ops::Fn<(&'a mut S1, &'r [TT])>` is required --> src/main.rs:29:9 | 29 | f1("aaa", move |ecx, tt| self.my_g(ecx, tt)); //A!!! | ^^ --------------------------------- implements `std::ops::Fn<(&mut S1, &[TT])>` | | | requires `for<'a, 'r> std::ops::Fn<(&'a mut S1, &'r [TT])>` | expected concrete lifetime, found bound lifetime parameter | = note: required because of the requirements on the impl of `Foo` for `[closure@src/main.rs:29:19: 29:52 self:_]` = note: required by `f1`
+3
source to share