Closed
Description
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.