Skip to content

Non-send future produced by chaining Stream combinators #2845

Closed
@George-Miao

Description

@George-Miao

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`.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions