I'm trying to return an async future from a method on a struct that implements a trait. Here's a simplified version of my Rust code:
use std::future::Future;
fn main() {}
fn sleep() -> impl Future + 'static {
let scheduler = Tokio;
scheduler.sleep()
}
trait Scheduler {
fn sleep<'a>(&'a self) -> impl Future + 'static;
}
struct Tokio;
impl Scheduler for Tokio {
fn sleep<'a>(&'a self) -> impl Future + 'static {
async {}
}
}
This fails to compile with the following error:
error[E0597]: `scheduler` does not live long enough
--> src/main.rs:5:5
|
4 | let scheduler = Tokio;
| --------- binding `scheduler` declared here
5 | scheduler.sleep()
| ^^^^^^^^^--------
| |
| borrowed value does not live long enough
| argument requires that `scheduler` is borrowed for `'static`
6 | }
| - `scheduler` dropped here while still borrowed
I don't understand why this happens. The future returned from sleep()
is 'static, and scheduler is just a local variable. But Rust says it's borrowed for 'static
.
How can I fix this?
My goal is for sleep()
to return a future that's 'static
so it can be spawned or used elsewhere.
impl Trait
always captures all lifetime (and type) parameters in scope. Saying + 'static
doesn't help, unfortunately.
The real fix will be to use the use<>
syntax, which was created precisely for this:
trait Scheduler {
fn sleep<'a>(&'a self) -> impl Future + use<Self>;
}
struct Tokio;
impl Scheduler for Tokio {
fn sleep<'a>(&'a self) -> impl Future + use<> {
async {}
}
}