Is there a way to create a closure with non-static lifetime?

I have a system built with "services" (traits) that are implemented with structs that use generic types like so:

    pub struct Service<
        'a,
        O: OtherService + Send + Sync,
    > {
        pub other_service: Arc<O>,
    }

In the impl, a method spawns a thread:

                    self.thread_handle = Some(std::thread::spawn(move || loop {
                        action::<'a, O>();
                    }));

It won't compile:

error[E0310]: the parameter type `O` may not live long enough

The system requires O to have static lifetime, because the closure must.

Note that you also can't specify a lifetime for the closure function:

error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
  --> services/src/trading.rs:71:40
   |
71 |                         action::<'a, O>();

What I want to do here - I think! - is restrict the new thread's lifetime to 'a. Is this possible?

Is there any reason you can't require O have a static lifetime? i.e. O: 'static + OtherService + Send + Sync.

If not, then the only way to spawn a thread with a limited lifetime is using std::thread::scope (or similar constructs from crates like crossbeam)... but given that you seem to be storing the join handle somewhere, I don't know if that would even work in your case.

3 Likes

To add to the previous reply, thread::scope doesn't require 'static because all the threads spawned from within are joined (destroyed) by the time it returns. If you want them to run detached (indefinitely long), you need the 'static bound.

5 Likes

This is a red herring. Even if you could do this, it wouldn't solve your problem, it would just move the type error elsewhere.

Lifetime annotations describe, they don't affect how long values live. You can't make a local variable live for the static lifetime by forcibly annotating borrows of it as &'static.

The only way to make a value live longer is to move its owner to a broader scope.

2 Likes

There really isn't such a reason. I just thought using 'a was cleaner.

But I realized that 'a really means 'static in the app anyway.

Since I am spawning threads that cannot be scoped, it seems the thing to do is change my lifetime to 'static.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.