Can't use async closure instead of fn

When I refactored some deeply nested await/async code, I found a problem, which I tried to simplify to

What I want to achieve in my code: call a closure that has access to some local context (channel tx) from some nested loop, so that the result is more flatten.

Basically, I can write

async fn f(x: &str) {
    println!("inside f() without ctx");
    tokio::time::sleep(std::time::Duration::from_millis(1)).await;
    println!("x={}", x);
};
for i in 0..2 {
    let a = ...;
    f(&a).await;
}

but can not

let g = |x: &str| async move {
    println!("inside g() with ctx {}", ctx);
    tokio::time::sleep(std::time::Duration::from_millis(1)).await;
    println!("x={}", x);
};
for i in 0..2 {
    let c = ...;
    g(&c).await;
}

If I try to let Rust deduce type and lifetime for closure parameter, I get:

`c` does not live long enough

in

for i in 0..2 {
    let c = hello("c", i);
    g(&c).await;
}

Which is something I don't understand as "hand-written" version (G in the playground) compiles fine.
Any ideas if I can achieve "capture" of some context into async lambda and call it multiple times?

Thanks for any advice or explanations.

Honestly, this is a limitation of the type system that you can't do much about.

I came up with this solution which involves boxing the return type of the future, if it helps. I don't know if there's a way to remove hack.

Not really the most beautiful solution, but given that the approach with an explicit helper struct worked for you, one possibility is to just try to make that solution be more ergonomic, mainly through some helper macro.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.