Solution to Rust errors of kinds: - implementation of `Fn` is not general enough (works with FnMut and FnOnce as well) - lifetime may not live long enough ```rs use std::future::Future; trait Callback { type Output: Future; fn call(&self, arg: Arg) -> Self::Output; } impl Callback for F where F: Fn(Arg) -> Fut, Fut: Future, { type Output = Fut; fn call(&self, arg: Arg) -> Fut { self(arg) } } async fn run_callback(callback: F) where for<'a> F: Callback<&'a mut i32, i32>, { for mut i in 0..10 { let res = callback.call(&mut i).await; println!("{}", res); } } async fn test() { async fn callback(x: &mut i32) -> i32 { *x += 10; println!("{}", x); *x + 100 } run_callback(callback).await; // Does not work: // run_callback(|x: &mut i32| async move { // *x += 10; // println!("{}", x); // *x + 100 // }).await; } trait CallbackWithState { type Output: Future; fn call(&self, state: State, arg: Arg) -> Self::Output; } impl CallbackWithState for F where F: Fn(State, Arg) -> Fut, Fut: Future, { type Output = Fut; fn call(&self, state: State, arg: Arg) -> Fut { self(state, arg) } } async fn run_callback_with_state(state: &mut State, callback: F) where for<'state, 'arg> F: CallbackWithState<&'state mut State, &'arg mut i32, i32>, { for mut i in 0..10 { let res = callback.call(state, &mut i).await; println!("{}", res); } } async fn test_with_state() { async fn callback(state: &mut String, x: &mut i32) -> i32 { *x += 10; state.push_str(&x.to_string()); println!("{}", x); *x + 100 } run_callback_with_state(&mut String::new(), callback).await; // Does not work: // run_callback_with_state(&mut String::new(), |state: &mut String, x: &mut i32| async move { // *x += 10; // state.push_str(&x.to_string()); // println!("{}", x); // let res = *x + 100; // }); } ``` If you want to restrict the Callback trait to take references only you have to use explicit lifetimes like so: ```rs use std::future::Future; trait Callback<'arg, Arg: 'arg, Res> { type Output: Future; fn call(&self, arg: &'arg mut Arg) -> Self::Output; } impl<'arg, Arg: 'arg, Res, F, Fut> Callback<'arg, Arg, Res> for F where F: Fn(&'arg mut Arg) -> Fut, Fut: Future, { type Output = Fut; fn call(&self, arg: &'arg mut Arg) -> Fut { self(arg) } } async fn run_callback(callback: F) where for<'a> F: Callback<'a, i32, i32>, { for mut i in 0..10 { let res = callback.call(&mut i).await; println!("{}", res); } } async fn test() { async fn callback(x: &mut i32) -> i32 { *x += 10; println!("{}", x); *x + 100 } run_callback(callback).await; // Does not work: // run_callback(|x: &mut i32| async move { // *x += 10; // println!("{}", x); // *x + 100 // }).await; } trait CallbackWithState<'state, 'arg, State: 'state, Arg: 'arg, Res> { type Output: Future; fn call(&self, state: &'state mut State, arg: &'arg mut Arg) -> Self::Output; } impl<'state, 'arg, State: 'state, Arg: 'arg, Res, F, Fut> CallbackWithState<'state, 'arg, State, Arg, Res> for F where F: Fn(&'state mut State, &'arg mut Arg) -> Fut, Fut: Future, { type Output = Fut; fn call(&self, state: &'state mut State, arg: &'arg mut Arg) -> Fut { self(state, arg) } } async fn run_callback_with_state(state: &mut State, callback: F) where for<'state, 'arg> F: CallbackWithState<'state, 'arg, State, i32, i32>, { for mut i in 0..10 { let res = callback.call(state, &mut i).await; println!("{}", res); } } async fn test_with_state() { async fn callback(state: &mut String, x: &mut i32) -> i32 { *x += 10; state.push_str(&x.to_string()); println!("{}", x); *x + 100 } run_callback_with_state(&mut String::new(), callback).await; // Does not work: // run_callback_with_state(&mut String::new(), |state: &mut String, x: &mut i32| async move { // *x += 10; // state.push_str(&x.to_string()); // println!("{}", x); // let res = *x + 100; // }); } ```