Hi,
I'm trying to combine Rust with Python, in order to speed up a tree search algorithm I'm playing around with.
The outer program is a python script, which calls into a PyO3 wrapper around a Rust tree search.
This works well so far, but now I'm trying to occasionally evaluate a Python function within the Rust tree search and hitting the limits of my Rust knowledge.
I'm getting this lifetime error and am failing to understand why it thinks the lifetime should be 'static and how to fix it:
error[E0621]: explicit lifetime required in the type of `pyfun`
--> src/lib.rs:90:19
|
88 | fn test4(&mut self, pyfun: &PyObjectRef) -> PyResult<(u8)> {
| ------------ help: add explicit lifetime `'static` to the type of `pyfun`: `&'static pyo3::PyObjectRef`
89 | let closure = || -> u8 { pyfun.call0().unwrap().extract().unwrap() };
90 | Ok(search(&closure))
| ^^^^^^^^ lifetime `'static` required
Here's a minimal example of what I'm trying to run and what still works:
In my python script I'm importing my rust module as m, and then calling different test methods with just a lambda as my "evaluation function":
print(m.test1(lambda: 1))
print(m.test2(lambda: 2))
print(m.test3(lambda: 3))
print(m.test4(lambda: 4))
The test functions are implemented in Rust, getting more complex and 1-3 work perfectly, with 4 I'm getting the error above:
// Just call the passed python function directly -> works
fn test1(&mut self, pyfun: &PyObjectRef) -> PyResult<(u8)> {
pyfun.call0()?.extract()
}
// Put the evaluation into a closure, directly call the closure -> works
fn test2(&mut self, pyfun: &PyObjectRef) -> PyResult<(u8)> {
let closure = || -> u8 { pyfun.call0().unwrap().extract().unwrap() };
Ok(closure())
}
// placeholder for my tree search that should later call into the python function
type EvalFn = Fn() -> (u8);
fn search(f: &EvalFn) -> u8 {
1 // later I'd call f in here, but not necessary to trigger my issue
}
// Try calling search with a Rust closure -> works
fn test3(&mut self, pyfun: &PyObjectRef) -> PyResult<(u8)> {
let closure = || -> u8 { 33 };
Ok(search(&closure))
}
// Now what I'm actually trying to do: search with a Python evaluation function
// -> errors with lifetime `'static` required
fn test4(&mut self, pyfun: &PyObjectRef) -> PyResult<(u8)> {
let closure = || -> u8 { pyfun.call0().unwrap().extract().unwrap() };
Ok(search(&closure))
}
I don't understand why it thinks the lifetime needs to be 'static when I put the pyfun evaluation into a closure, I don't think it should be necessary.
But I'm not sure how to debug this or tell it otherwise?
Any help would be greatly appreciated!