Skip to content
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/await: Usage of trait objects reports multiple different lifetimes when only one is used #58885

Closed
Matthias247 opened this issue Mar 3, 2019 · 1 comment

Comments

@Matthias247
Copy link
Contributor

@Matthias247 Matthias247 commented Mar 3, 2019

The following code (playground) fails to compile:

#![feature(futures_api, async_await, await_macro)]

struct Xyz {
    a: u64,
}

trait Foo {}

impl Xyz {
    async fn do_sth<'a>(
        &'a self, foo: &'a dyn Foo
    ) -> bool
    {
        true
    }
}

Error:

error[E0709]: multiple different lifetimes used in arguments of `async fn`
  --> src/lib.rs:11:10
   |
11 |         &'a self, foo: &'a dyn Foo
   |          ^^                ^^^^^^^ different lifetime here
   |          |
   |          first lifetime here
   |
   = help: `async fn` can only accept borrowed values with identical lifetimes

This is very surprising, since only one lifetime is visible.

Workaround (thanks to @Nemo157 ):

Defining the function as

async fn do_sth<'a>(&'a self, foo: &'a (dyn Foo + 'a)) -> bool

will allow compilation.

@nikomatsakis
Copy link
Contributor

@nikomatsakis nikomatsakis commented Mar 5, 2019

Tagging as blocking -- this issue ought to be resolved before async-await can be stabilized, because it is generally surprising and kind of a bug. However, we expect it to get fixed by fixing #56238 (see that issue for notes as to why).

bors added a commit that referenced this issue Apr 2, 2019
Refactor async fn return type lowering

async fn now lowers directly to an existential type declaration
rather than reusing the `impl Trait` return type lowering.

As part of this, it lowers all argument-position elided lifetimes
using the in-band-lifetimes machinery, creating fresh parameter
names for each of them, using each lifetime parameter as a generic
argument to the generated existential type.

This doesn't currently successfully allow multiple
argument-position elided lifetimes since `existential type`
doesn't yet support multiple lifetimes where neither outlive
the other:
```rust
existential type Foo<'a, 'b>:; // error: ambiguous lifetime bound in `impl Trait`
fn foo<'a, 'b>(_: &'a u8, _: &'b u8) -> Foo<'a, 'b> { () }
```

This requires a separate fix.

Fix #59001
Fix #58885
Fix #55324
Fix #54974
Progress on #56238

r? @nikomatsakis
Centril added a commit to Centril/rust that referenced this issue Apr 2, 2019
Refactor async fn return type lowering

async fn now lowers directly to an existential type declaration
rather than reusing the `impl Trait` return type lowering.

As part of this, it lowers all argument-position elided lifetimes
using the in-band-lifetimes machinery, creating fresh parameter
names for each of them, using each lifetime parameter as a generic
argument to the generated existential type.

This doesn't currently successfully allow multiple
argument-position elided lifetimes since `existential type`
doesn't yet support multiple lifetimes where neither outlive
the other:
```rust
existential type Foo<'a, 'b>:; // error: ambiguous lifetime bound in `impl Trait`
fn foo<'a, 'b>(_: &'a u8, _: &'b u8) -> Foo<'a, 'b> { () }
```

This requires a separate fix.

Fix rust-lang#59001
Fix rust-lang#58885
Fix rust-lang#55324
Fix rust-lang#54974
Progress on rust-lang#56238

r? @nikomatsakis
@bors bors closed this in #59286 Apr 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

4 participants