Lifetime issue with &str

I struggle with the code below. Basically, I have a lifetime issue with the &str passed into f1 and f2, but I don't understand how to solve it. vi and vx are attempts to make the String more long-lived, but this does not seem to work. My code gets more complicated and more weird with each step I add attempting to fix this :frowning: seems time for a question here...

(The fragment in reality is more complicated, but this shows the essence of the problem).

use std::process::ExitCode;

fn foo(fun: Option<Box<&dyn Fn(&str)->bool>>) {
    let mut test = vec!["abc", "def", "ghi"];
    let mut _result : Vec<_>;
    if let Some(f) = fun {
        _result = test.iter_mut().filter(|x| f(x)).collect();

static O1 : Option<String> = Some(String::new());
static O2 : Option<String> = Some(String::new());

fn main() -> ExitCode {
    let mut f1 : Box<&dyn Fn(&str)->bool> = Box::new(&|_x: &str| -> bool { true });
    let mut f2 : Box<&dyn Fn(&str)->bool> = Box::new(&|_x: &str| -> bool { true });
    let vi: String;
    let vx: String;
    if let Some(ref v) = O1 {
        vi = v.clone();
        f1 = Box::new(&|x: &str| -> bool { x.contains(&vi) });    // <-- here
    if let Some(ref v) = O2 {
        vx = v.clone();
        f2 = Box::new(&|x: &str| -> bool { !x.contains(vx.as_str()) }); // <-- or here

    foo(Some(Box::new(&|x| { f1(x) & f2(x) })));

Here's a modified working version of your code. You can ask more question about the specific parts. But the key is just using move everywhere.


The main problem is the Box<&dyn Fn> type. While a dyn trait object is unsized and required to be behind a kind of indirection like references or boxes, it's usually one or the other.