Handling non-`Send` data in a `Send` closure
⚓ Rust 📅 2026-05-05 👤 surdeus 👁️ 1I 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
🏷️ Rust_feed