The future produced by chaining filter_map and chunks with a self reference inside filter_map closure is not Send for some reason, and this can be fixed by adding a .boxed() after the chunks call.
fn assert_send<T: Send>(t: T) -> T { t }
async fn test() {
struct A;
impl A {
async fn a(&self) {
futures::stream::iter([0u8])
.filter_map(|_| async {
self.c();
// self.b().await; // Same as calling `c`
Some(0)
})
.chunks(1)
// .boxed() // This will fix the problem
.for_each(|_| async {}) // This can be anything consumes the stream without pinning it, include for_each_concurrent and collect
.await;
}
async fn b(&self) {}
fn c(&self) {}
}
assert_send(A.a()).await; // This will fail to compile
}
Error:
error[E0308]: mismatched types
--> [:REDACTED:]/test.rs:252:9
|
231 | .filter_map(|_| async {
| _____________________________________-
232 | | self.c();
233 | | // self.b().await; // Same as calling `c`
234 | | Some(0)
235 | | })
| | -
| | |
| |_____________________the expected `async` block
| the found `async` block
...
252 | assert_send(A.a_consume()).await; // This will fail to compile
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected `async` block `{async block@[:REDACTED:]/test.rs:231:37: 235:22}`
found `async` block `{async block@[:REDACTED:]/test.rs:231:37: 235:22}`
note: the lifetime requirement is introduced here
--> [:REDACTED:]/test.rs:223:23
|
223 | fn assert_send<T: Send>(t: T) -> T {
| ^^^^
For more information about this error, try `rustc --explain E0308`.
The future produced by chaining
filter_map
andchunks
with aself
reference insidefilter_map
closure is notSend
for some reason, and this can be fixed by adding a.boxed()
after the chunks call.Error: