Open varqox opened 1 month ago
here's a working version:
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 = ()> + 'state,
{
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) {
async fn callback<State>(state: &mut State) {}
aaa(state, &callback).await;
}
Okay, I wanted to make the example simple, but lost the issue real issue along the way. Thanks for the solution to the original problem. 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;
}
However, this does not compile:
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`
this type of question would probably be better directed to URLO
Compiler version 1.81.0.
I am writing an asynchronous function that takes asynchronous callback, I managed to write it so that it compiles:
However, if I try to add explicit lifetimes to the Callback trait, I get compilation error:
for the following code:
But if I fix it according to the suggestion, I get the following error:
for the code
I thing something is not correct about treating explicit lifetimes by the compiler, or I added the lifetimes incorrectly. Please help.