Closure that borrow from their captures

⚓ Rust    📅 2026-02-11    👤 surdeus    👁️ 1      

surdeus

I'm experimenting with closures that return a Future, passed as a function parameter. If I create the Future with an async {} (without the move), I get a compile error because closure can't borrow from their capture. It was one of the motivations for the async closure.

But if I reborrow inside the async {}, it compiles. Why this is working ?

use std::pin::Pin;

#[tokio::main]
async fn main() {

    // Doesn't compile.
    // for_each_city_box(|city| Box::pin(async { println!("{city}") })).await;

    // But with reborrowing it does.
    for_each_city(|city| {
        Box::pin(async {
            let city = &*city;
            println!("{city}")
        })
    })
    .await;
}

async fn for_each_city<F>(mut f: F)
where
    F: for<'c> FnMut(&'c str) -> Pin<Box<dyn Future<Output = ()> + Send + 'c>>,
{
    for x in ["New York", "London", "Tokyo"] {
        f(x).await;
    }
}

Playground link

2 posts - 2 participants

Read full topic

🏷️ Rust_feed