With following code, I get error that "implementation of std::ops::FnOnce is not general enough" and "no two async blocks, even if identical, have the same type. consider pinning your async block and casting it to a trait object". The error is on spawn line, and detail line number points to the whole closure of inner_stream call in then. I tried to pin the closure or the block, nothing seems to work. Maybe I did not do it right. How can I fix this?
PS: This code works in Playground, but not locally with Rust Stable. I have no idea why.
use futures::StreamExt;
use futures::TryStreamExt;
use futures::stream;
use futures::stream::BoxStream;
use tokio::task::JoinSet;
#[derive(Debug)]
struct Error;
async fn inner_stream(_i: usize) -> Result<BoxStream<'static, Result<usize, Error>>, Error> {
Err(Error)
}
async fn outer_stream(_x: String) -> Result<(), Error> {
let iter = [].into_iter().filter(|x: &Vec<usize>| !x.is_empty());
stream::iter(iter)
.then(async |x| {
// some processing
Ok(x)
})
.map_ok(async |x| {
stream::iter(x.into_iter())
// .then(|y| Box::pin(async move { inner_stream(y).await }))
.then(async |y| inner_stream(y).await ))
.try_flatten()
.try_collect::<Vec<_>>()
.await
})
.try_for_each_concurrent(8, async |x| {
let _ = x.await;
Ok(())
})
.await?;
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), Error> {
let xs: Vec<String> = vec![];
let mut js = JoinSet::new();
for x in xs {
js.spawn(async move { outer_stream(x).await });
}
js.join_all().await;
Ok(())
}