This doesn't compile:
async fn foo<F: Future<Output = i32>>(x: &i32, future: F) -> i32 {
let y = await!(future);
*x + y
}
error[E0311]: the parameter type `F` may not live long enough
--> src/lib.rs:5:62
|
5 | async fn foo<F: Future<Output = i32>>(x: &i32, future: F) -> i32 {
| ^^^
|
= help: consider adding an explicit lifetime bound for `F`
note: the parameter type `F` must be valid for the anonymous lifetime #1 defined on the function body at 5:1...
--> src/lib.rs:5:1
|
5 | / async fn foo<F: Future<Output = i32>>(x: &i32, future: F) -> i32 {
6 | | let y = await!(future);
7 | | *x + y
8 | | }
| |_^
note: ...so that the type `impl std::future::Future` will meet its required lifetime bounds
--> src/lib.rs:5:62
|
5 | async fn foo<F: Future<Output = i32>>(x: &i32, future: F) -> i32 {
| ^^^
But it does compile if you replace the &i32 with an i32. This is because async fn foo<T>() -> R desugars to -> impl Future<Output = R>, but async fn foo<T>(x: &i32) -> R desugars to -> impl Future<Output = R> + '_. Since T doesn't outlive the elided lifetime, it fails to compile. We need instead to capture the minimum lifetime of T and '_. Note that this is similar to the issue where async fn cannot have multiple different named lifetimes because there's not a way to express the desugared "minimum of all lifetimes" in the -> impl Trait return type.
cc @withoutboats who originally reported this on discord.
This doesn't compile:
But it does compile if you replace the
&i32with ani32. This is becauseasync fn foo<T>() -> Rdesugars to-> impl Future<Output = R>, butasync fn foo<T>(x: &i32) -> Rdesugars to-> impl Future<Output = R> + '_. SinceTdoesn't outlive the elided lifetime, it fails to compile. We need instead to capture the minimum lifetime ofTand'_. Note that this is similar to the issue whereasync fncannot have multiple different named lifetimes because there's not a way to express the desugared "minimum of all lifetimes" in the-> impl Traitreturn type.cc @withoutboats who originally reported this on discord.