Solved: How do I satisfy a `'static + FnOnce()` requirement?


I’m trying to call this method:

pub fn call_with_gvl<F, R>(func: F) -> R
    F: 'static + FnOnce() -> R,

And when I pass it a closure it complains about the lifetime. If I try to box the closure it says that it does not have a constant size known at compile time.

The closure needs to take in three things within the method I’m writing.


The closure cannot borrow anything from its environment - it must consist of only owned data or references to 'static data (that’s the 'static requirement in the call_with_gvl signature). From the little you’ve said, I suspect your closure is borrowing from the environment. Can you show it?


Here’s the first attempt:

let closure = || {
    call_public_method(self.value(), "==", Some(vec![other.value()]))

let result = Thread::call_with_gvl(closure);

And the next

let closure = Box::new(move ||
    call_public_method(self.value(), "==", Some(vec![other.value()]))

let result = Thread::call_with_gvl(*closure);

And the error

error[E0477]: the type `[closure@src/class/traits/ 625:10 self:&&Self, other:&T]` does not fulfill the required lifetime
   --> src/class/traits/
627 |         let result = Thread::call_with_gvl(closure);
    |                      ^^^^^^^^^^^^^^^^^^^^^
    = note: type must satisfy the static lifetime

Both the call_public_method and call_with_gvl are FFI calls across to Ruby through its C API.


Your closure is borrowing self and other. Can you do the following instead:

let v = self.value();
let other = other.value();
let closure = move || call_public_method(v, "==", Some(vec![other]));


Thanks! That got past the Rust compiler. Now I’m on to a separate issue not Rust related. Thanks for the tip!