Handling non-`Send` data in a `Send` closure

⚓ Rust    📅 2026-05-05    👤 surdeus    👁️ 1      

surdeus

I have a place in my program that can only accept Send functions. However, I'd like to be able to submit non-Send functions as well using a wrapper that makes them Send like so:

fn IOnlyAcceptSend(f: T + Send) {
     ...
}

IOnlyAcceptSend( MakeThisFnSend( nonSendFn ) )

In MakeThisFnSend I convert functions that return Result<(), Box<dyn Error>> to Fn's that return Result<(), Box<dyn Error + Send>>

let func2: Box<dyn Fn() -> Pin<Box<dyn std::future::Future<
        Output = Result<(), Box<dyn Error + Send>>> + Send + 'static>
        > + Send + Sync> =

        Box::new(move || {
            let func_clone = Arc::clone(&arc_func);
            Box::pin(async move {
                let before: Result<(), Box<dyn Error>> = func_clone().await;
                let after: Result<(), Box<dyn Error + Send>> = match before {
                    Ok(()) => { Ok(()) }
                    Err(err) => {
                        Err(Box::new(std::io::Error::new(
                            std::io::ErrorKind::Other, err.to_string())))
                    }
                };
                after
            })
        });

However, the compiler complains: ^ future created by async block is not Send!

As far as I can research, the compiler sees any non-Send values within the block as making the entire block non-Send, even though the whole purpose of the block is to strip away all non-Send material.

As far as I can tell, this code is perfectly safe and it is just that the compiler cannot see that or is overly strict. Is this the case? If it is, can I force this to work somehow? Is this a use case for unsafe?

4 posts - 4 participants

Read full topic

🏷️ Rust_feed