Reputation: 2174
I'm trying to understand how lifetimes work and I've come up with this example:
use std::future::Future;
use std::pin::Pin;
use futures::future::{BoxFuture, FutureExt};
struct Message{}
struct Client{}
impl Client {
fn send_and_expect(
& mut self,
message: & Message
) -> Pin<Box<(dyn futures::Future<Output = std::result::Result<(), ()>> + std::marker::Send )>> {
async move {
let m = message;
Ok(())
}.boxed()
}
}
I get this error about anonymous lifetime. Why &request
needs to satisfy a 'static
lifetime requirement?
Error:
error[E0759]: `message` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> src/lib.rs:14:20
|
12 | message: & Message
| --------- this data with an anonymous lifetime `'_`...
13 | ) -> Pin<Box<(dyn futures::Future<Output = std::result::Result<(), ()>> + std::marker::Send )>> {
14 | async move {
| ____________________^
15 | | let m = message;
16 | | Ok(())
17 | | }.boxed()
| |_________^ ...is captured here, requiring it to live as long as `'static`
|
help: to declare that the trait object captures data from argument `message`, you can add an explicit `'_` lifetime bound
|
13 | ) -> Pin<Box<(dyn futures::Future<Output = std::result::Result<(), ()>> + std::marker::Send + '_ )>> {
| ^^^^
I always thought it had to live as long as the pinned returned value. Not necessairly 'static
I know that giving a specific lifetime for
Upvotes: 0
Views: 959
Reputation: 4775
This is because the returned future is keeping the capture of the argument so the argument has to outlive the future, and Box<T>
implicitly has a 'static
lifetime unless T
is constrained by a lifetime identifier.
If you constrain the return type's lifetime to match the argument's lifetime, it could compile
impl Client {
fn send_and_expect<'a>(
&'a mut self,
message: & Message
) -> Pin<Box<(dyn futures::Future<Output = std::result::Result<(), ()>> + std::marker::Send + 'a)>> {
async move {
let m = message;
Ok(())
}.boxed()
}
}
Upvotes: 2