Skip to content

Mutually recursive async fns are hard to make Send #62284

Open
@cramertj

Description

@cramertj

There are several other related issues to this, but I'm opening this to track this one specifically since it's a pain-- there are workarounds, but it'd be lovely (and should be possible) to make this "just work." The following example compiles just fine without + Send, but adding the Send bound causes a cycle error:

#![feature(async_await)]

use {
    std::{
        future::Future,
        pin::Pin,
    },
};

type BoxFuture = Pin<Box<dyn Future<Output = ()> /* + Send */>>; // adding Send causes a cycle error

async fn foo() -> BoxFuture {
    Box::pin(bar()) as _
}

async fn bar() {
    let _ = foo().await;
}

Working around the cycle error is possible, but annoying:

#![feature(async_await)]

use {
    std::{
        future::Future,
        pin::Pin,
    },
};

type BoxFuture = Pin<Box<dyn Future<Output = ()> + Send>>;

async fn foo() -> BoxFuture {
    box_bar()
}

fn box_bar() -> BoxFuture {
    Box::pin(bar())
}

async fn bar() {
    let _ = foo().await;
}

Ideally we wouldn't have a cycle error in either case, since it is possible to see that foo must be Send without ever looking at the body of bar, since bar is immediately boxed into a BoxFuture.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions