This code works:
use std::future::Future;
pub trait Callback<State> {
type Output: Future<Output = ()>;
fn call(&self, state: State) -> Self::Output;
}
impl<State, F, Fut> Callback<State> for F
where
F: Fn(State) -> Fut,
Fut: Future<Output = ()>,
{
type Output = Fut;
fn call(&self, state: State) -> Self::Output {
self(state)
}
}
pub async fn aaa<State, Cb>(state: &mut State, callback: &Cb)
where
for<'state> Cb: Callback<&'state mut State>,
{
}
pub async fn bbb<State, Cb>(state: &mut State) {
struct InnerState<'state, State> {
state: &'state mut State,
x: i32,
}
async fn callback<'a, State>(state: &mut InnerState<'a, State>) {}
aaa(&mut InnerState { state, x: 42 }, &callback).await;
}
This does not:
use std::future::Future;
pub trait Callback<'state, State> {
type Output: Future<Output = ()>;
fn call(&self, state: &'state mut State) -> Self::Output;
}
impl<'state, State: 'state, F, Fut> Callback<'state, State> for F
where
F: Fn(&'state mut State) -> Fut,
Fut: Future<Output = ()>,
{
type Output = Fut;
fn call(&self, state: &'state mut State) -> Self::Output {
self(state)
}
}
pub async fn aaa<State, Cb>(state: &mut State, callback: &Cb)
where
for<'state> Cb: Callback<'state, State>,
{
}
pub async fn bbb<State: 'static, Cb>(state: &mut State) {
struct InnerState<'state, State> {
state: &'state mut State,
x: i32,
}
async fn callback<'a, State>(state: &mut InnerState<'a, State>) {}
aaa(&mut InnerState { state, x: 42 }, &callback).await;
}
with error:
error[E0521]: borrowed data escapes outside of function
--> src/lib.rs:34:5
|
26 | pub async fn bbb<State: 'static, Cb>(state: &mut State) {
| ----- - let's call the lifetime of this reference `'1`
| |
| `state` is a reference that is only valid in the function body
...
34 | aaa(&mut InnerState { state, x: 42 }, &callback).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| `state` escapes the function body here
| argument requires that `'1` must outlive `'static`
Am I adding the explicit lifetimes wrongly or some magic happens in the compiler making code without lifetimes somewhat "superior" (compiling)?