Skip to content

async block with futures::stream::Buffered is not Send #104382

Open
@mikeyhew

Description

@mikeyhew

This issue was originally reported in rust-lang/futures-rs#2636, but it looks like a bug in the compiler.

Here is the example from that issue (posted by @Tuetuopay):

use futures::stream::{empty, StreamExt};
use std::future::ready;

fn send<T: Send>(_: T) {}

fn main() {
    send(async {
        empty().map(ready::<&()>).buffered(0).next().await
    });
}

This should compile without issues, however rustc outputs this error message:

error: higher-ranked lifetime error
 --> src/main.rs:7:5
  |
7 | /     send(async {
8 | |         empty().map(ready::<&()>).buffered(0).next().await
9 | |     });
  | |______^
  |
  = note: could not prove `impl futures::Future<Output = Option<&'a ()>>: std::marker::Send`

This occurs on current nightly (2022-11-11) and stable. Playground link: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=43484ffb5887c99e0845737c0241c853

There appears to be some issue in how the compiler checks the async block. If you call .boxed() on the stream before calling .buffered() on it, the error goes away:

use futures::stream::{empty, StreamExt};
use std::future::ready;

fn send<T: Send>(_: T) {}

fn main() {
    send(async {
        empty().map(ready::<&()>).boxed().buffered(0).next().await
    });
}

This compiles without errors on current nightly and stable. Playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=9c086487d1ff76b309796efa45846f67

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.WG-asyncWorking group: Async & await

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions