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: hidden type for impl Trait captures lifetime that does not appear in bounds #59001

Closed
jethrogb opened this issue Mar 7, 2019 · 7 comments · Fixed by #59286
Closed
Assignees
Labels
A-async-await Area: Async & Await AsyncAwait-Polish Async-await issues that are part of the "polish" area C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jethrogb
Copy link
Contributor

jethrogb commented Mar 7, 2019

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

use std::future::Future;

async fn enter<'a, F, R>(mut callback: F)
where
    F: FnMut(&'a mut i32) -> R,
    R: Future<Output = ()> + 'a
{
    unimplemented!()
}
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
 --> src/lib.rs:6:1
  |
6 | where
  | ^
  |
note: hidden type `impl std::future::Future` captures the lifetime 'a as defined on the function body at 5:16
 --> src/lib.rs:5:16
  |
5 | async fn enter<'a, F, R>(mut callback: F)
  |                ^^

I think this is a bug? The RFC says

All of the input lifetimes to this function are captured in the future returned by the async function

so I'd expect the function to return impl Future<...> + 'a.

@jonas-schievink jonas-schievink added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. A-async-await Area: Async & Await labels Mar 7, 2019
@csmoe
Copy link
Member

csmoe commented Mar 8, 2019

@jethrogb
Copy link
Contributor Author

jethrogb commented Mar 8, 2019

@csmoe what do you mean "not needed"? You changed the signature of the function.

@Matthias247
Copy link
Contributor

@jethrogb This compiles for me on on playground.

@jethrogb
Copy link
Contributor Author

@Matthias247 that's strange. The playground appears broken currently, but when I compile that locally with the latest nightly I still get the original error.

@csmoe
Copy link
Member

csmoe commented Mar 11, 2019

cc @cramertj

@cramertj
Copy link
Member

Yes, this is a bug I'm currently working on fixing.

@cramertj cramertj self-assigned this Mar 11, 2019
@nikomatsakis nikomatsakis added the AsyncAwait-Polish Async-await issues that are part of the "polish" area label Mar 12, 2019
@nikomatsakis
Copy link
Contributor

Marking this as blocking as it is part of the lifetime refactoring work that @cramertj has already started doing and should be addressed by that (as discussed here).

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-async-await Area: Async & Await AsyncAwait-Polish Async-await issues that are part of the "polish" area C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants