Gatonito
Gatonito

Reputation: 2174

(reference) is captured here, requiring it to live as long as `'static`

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

Playground

Upvotes: 0

Views: 959

Answers (1)

Alsein
Alsein

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

Related Questions