New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

async fn should support multiple lifetimes #56238

Open
withoutboats opened this Issue Nov 26, 2018 · 5 comments

Comments

Projects
None yet
5 participants
@withoutboats
Copy link
Contributor

withoutboats commented Nov 26, 2018

According to the RFC, the async fn syntax is supposed to capture all input lifetimes in the implicit outer return type. Currently it only captures one elided lifetime, and returns errors regarding other lifetimes.

This needs to be changed so that all lifetimes are captured in async fn.

Example:

async fn foo(x: &mut i32, y: &mut i32) -> i32 {
    *x += *y;
    *y += *x;
    *x + *y
}

Playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2015&gist=1953befb5a939c1379468aae9788dac8

cc @cramertj @Nemo157

@Nemo157

This comment has been minimized.

Copy link
Contributor

Nemo157 commented Nov 26, 2018

In case this helps either ideas on how to fix this, or others that get stuck with needing this, here's a way to write this that compiles currently, using the normal multi-lifetime Captures workaround for impl Trait:

fn foo<'a: 'c, 'b: 'c, 'c>(
    x: &'a mut i32,
    y: &'b mut i32,
) -> impl Future<Output = i32> + Captures<'a> + Captures<'b> + 'c {
    async move {
        *x += *y;
        *y += *x;
        *x + *y
    }
}

Playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=d8199b6efc90fe1c3e5df485a5006d15

@cramertj

This comment has been minimized.

Copy link
Member

cramertj commented Nov 26, 2018

(note that in order for that to work you have to still introduce a third lifetime, 'c, which outlives all of the lifetimes used elsewhere)

@Nemo157

This comment has been minimized.

Copy link
Contributor

Nemo157 commented Nov 26, 2018

(note that in order for that to work you have to still introduce a third lifetime, 'c, which outlives all of the lifetimes used elsewhere)

Isn't it a new lifetime that is outlived by all the lifetimes used elsewhere (i.e. the returned future can only live for the intersection of all incoming data's lifetimes).

@cramertj

This comment has been minimized.

Copy link
Member

cramertj commented Nov 26, 2018

Yes, you're correct.

@bbangert

This comment has been minimized.

Copy link

bbangert commented Jan 3, 2019

I ran into this on my first attempt to make some small async programs with nightly, the Capture workaround gets unwieldy fast as a fn has more elided lifetimes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment