Skip to content

Lifetime error when Send is enforced on async function return type #64176

Closed
@tomaka

Description

@tomaka

Just like a lot of lifetime issues, I'm not actually sure whether this is a bug in the compiler or a bug in my code.

The following code:

use std::pin::Pin;
use std::future::Future;

trait FooRef<'a> {
    type Elem;
    fn next_elem(self) -> Pin<Box<dyn Future<Output = Self::Elem> + Send + Sync + 'a>>;
}

struct FooImpl;
impl<'a> FooRef<'a> for &'a mut FooImpl {
    type Elem = &'a mut FooImpl;
    fn next_elem(self) -> Pin<Box<dyn Future<Output = Self::Elem> + Send + Sync + 'a>> {
        Box::pin(async move { self })
    }
}


async fn run<F>(mut foo: F)
    where for<'r> &'r mut F: FooRef<'r>
{
    loop {
        foo.next_elem().await;
    }
}


fn test() {
    fn req<T: Send>(_: T) {}
    req(run(FooImpl))
}

Triggers the following compilation error:

error: implementation of `FooRef` is not general enough
  --> src/lib.rs:29:5
   |
29 |     req(run(FooImpl))
   |     ^^^
   |
   = note: `FooRef<'1>` would have to be implemented for the type `&'0 mut FooImpl`, for any two lifetimes `'0` and `'1`
   = note: but `FooRef<'2>` is actually implemented for the type `&'2 mut FooImpl`, for some specific lifetime `'2`

Replacing T: Send with just T makes it compile fine.

Replacing async fn run<F>(mut foo: F) with async fn run(mut foo: FooImpl) (ie. removing the generic parameter) also works fine.

Code explanation: calling foo.next_elem() return a Future that should keep foo borrowed, and produces an element (type Elem;) that still keeps foo borrowed.

I don't really see the relationship between this behaviour and Send. All the types used in this code do implement Send.

My compiler version is rustc 1.39.0-nightly (c6e9c76c5 2019-09-04).

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.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions