I have SummaryExt
that has async fn summary()
, I couldn't make it compile without using #[async_trait]
. I thought my use case for async trait has been stabilized in Rust 1.75?
From the async_trait crate
The stabilization of async functions in traits in Rust 1.75 did not include support for using traits containing async functions as
dyn Trait
.
Does the error caused by the boxed error Box<dyn Error + Send + Sync + 'static>
and I still have to use the async_trait crate?
// use async_trait::async_trait;
use std::error::Error;
use chrono::{DateTime, Local};
use futures::{
future::try_join_all,
stream::{self, StreamExt},
};
#[derive(Clone, Copy, Default)]
struct DateTimeRange {
start: DateTime<Local>,
end: DateTime<Local>,
}
// #[async_trait]
trait SummaryExt {
// type Output: Send + Sync + 'static;
type Output;
async fn summary() -> Result<Vec<Self::Output>, Box<dyn Error + Send + Sync + 'static>>;
// fn summary() -> impl std::future::Future<Output = Result<Vec<Self::Output>, Box<dyn Error + Send + Sync + 'static>>> + std::marker::Send;
}
async fn do_work<T: SummaryExt + 'static>(ranges: Vec<DateTimeRange>) -> Vec<(DateTimeRange, Vec<T::Output>)>
where
T::Output: Send + Sync + 'static,
{
let futures = stream::iter(&ranges)
.map(|_| tokio::spawn(T::summary()))
.collect::<Vec<tokio::task::JoinHandle<_>>>()
.await;
try_join_all(futures).await;
Vec::new()
}
error[E0277]: `impl futures::Future<Output = Result<Vec<<T as SummaryExt>::Output>, Box<(dyn std::error::Error + std::marker::Send + Sync + 'static)>>>` cannot be sent between threads safely
--> src/lib.rs:30:31
|
30 | .map(|_| tokio::spawn(T::summary()))
| ------------ ^^^^^^^^^^^^ `impl futures::Future<Output = Result<Vec<<T as SummaryExt>::Output>, Box<(dyn std::error::Error + std::marker::Send + Sync + 'static)>>>` cannot be sent between threads safely
| |
| required by a bound introduced by this call
|
= help: the trait `std::marker::Send` is not implemented for `impl futures::Future<Output = Result<Vec<<T as SummaryExt>::Output>, Box<(dyn std::error::Error + std::marker::Send + Sync + 'static)>>>`
note: required by a bound in `tokio::spawn`
--> /playground/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/task/spawn.rs:167:21
|
165 | pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
| ----- required by a bound in this function
166 | where
167 | F: Future + Send + 'static,
| ^^^^ required by this bound in `spawn`
help: `std::marker::Send` can be made part of the associated future's guarantees for all implementations of `SummaryExt::summary`
|
21 - async fn summary() -> Result<Vec<Self::Output>, Box<dyn Error + Send + Sync + 'static>>;
21 + fn summary() -> impl std::future::Future<Output = Result<Vec<Self::Output>, Box<dyn Error + Send + Sync + 'static>>> + std::marker::Send;