-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
closures with async blocks have concrete argument lifetimes #59337
Comments
@rustbot modify labels: A-async-await and T-compiler. |
Interestingly, using trait aliases instead of the extra trait above gives a different error message, not sure exactly what it believes is wrong here (could easily be a trait alias issue rather than an async closure issue) (playground) #![feature(async_await, futures_api, trait_alias, unboxed_closures)]
use std::future::Future;
trait Foo<'a> = FnOnce<(&'a u8,)> where <Self as FnOnce<(&'a u8,)>>::Output: Future<Output = u8> + 'a;
fn foo<F>(f: F) where F: for<'a> Foo<'a> {
let bar = 5;
f(&bar);
}
fn main() {
foo(async move | f: &u8 | { *f });
foo({ async fn baz(f: &u8) -> u8 { *f } baz });
}
|
Marking as deferred since async closures are not considered part of the "core functionality" we are trying to stabilize. |
I think this is actually a problem with regular closures. It's just a lot more noticeable with async closures. In the working example, replace: foo({ async fn baz(f: &u8) -> u8 { *f } baz }); with: foo({ async fn baz(f: &u8) -> u8 { *f } |f| baz(f) }); This isn't an async closure. It should have the same function signature as baz, taking a borrowed u8 and returning a future. However, it doesn't compile:
|
I just ran into this too: in relation to async/await, but in a situation that does not require a nightly compiler: I think the "requires-nightly" label should be removed as this is clearly a broader problem that affects all closures. |
It seems like it might be a problem with the type inference of the closures return type? It ends up inferring the return type to be |
Looking at debug logs, the inferred function signature appears to come from Free functions that look more like fn test<'a, T>(_x: &'a T) -> impl Future<Output = ()> + 'a { // works fine
std::future::ready(())
}
fn test2<'a, T: 'a>(_x: T) -> impl Future<Output = ()> + 'a { // error
std::future::ready(())
}
fn test3<T>(_x: T) -> impl Future<Output = ()> { // error
std::future::ready(())
}
Note that this works exactly the same for I think this is the underlying problem. |
This doesn't require impl Trait. Even the generic identity function fails. EDIT: Even further minimized, but with a different error message: fn test1<T>(_: &T) { }
fn test2<T>(_: T) { }
fn main() {
let _: for<'a> fn(&'a u32) = test1;
let _: for<'a> fn(&'a u32) = test2; // error: one type is more general than the other
} |
This might be related to #84937 |
(playground) currently errors with(updated playground (with 2021 ed)) currently errors with:
You can see that the
async fn
correctly satisfies the HRLB required byfoo
, but the async closure has a concrete lifetime for the argument instead of being for any lifetime.The text was updated successfully, but these errors were encountered: