Problem with value escaping from closure (lifetime issue?)

Hi,

(see playground).

I am trying to modify the elements of an iterator using a capturing closure.
The closure captures the variable myvec, which is derived from the function argument input.
However, there is a compile error ("returns a reference to a captured variable which escapes the closure body").

I suppose that the compile error is related to the lifetime of myvec as using input in the closure instead of myvec works (even though this is oversimplifies my actual problem).

I guess that I want to tie myvec to the lifetime of input (since myvec should survive until the iterator is completely used up (although I believed that move would make sure of this already)) but my attempts did not work.

Interestingly, unfolding the call to bar (commented last line of foo) also works, which is pretty unclear to me. Also here, I would expect the same error message. Maybe it is because the lifetime annotations foo and bar are not tied together...?

fn bar<'a, A>(vec: &'a Vec<&'a A>, index: usize) -> Vec<&'a A> {
    vec![vec[index]]
}

fn foo<'a>(domain: &'a Vec<&'a u32>) -> impl Iterator<Item=Vec<&'a u32>> {
    // compiles and works: but myvec 'computation' is too much simplified
    //let myvec = domain;

    // compile error: returns a reference to a captured variable which escapes the closure body
    let myvec = domain.clone();
    
    return vec![&0_usize, &1, &2].into_iter().map(move |&x| bar(&myvec, x));
    //return vec![&0_usize, &1, &2].into_iter().map(move |&x| vec![myvec[x]]);
}

#[test]
fn test() {
    assert_eq!(
        foo(&vec![&1_u32, &2, &3]).collect::<Vec<_>>(),
        vec![vec![&1_u32], vec![&2], vec![&3]]);
}

Unfolding the call to bar works because the lifetime signature of bar is more restrictive (to the caller) than necessary (given the way it's implemented). If you change the signature to:

fn bar<'a, A>(vec: &Vec<&'a A>, index: usize) -> Vec<&'a A> {
    vec![vec[index]]
}

then calling bar instead of unfolding/inlining the call works, too.

For more explanations about this kind of lifetime signature, I can recommend watching this video:

1 Like

Thanks! The video really helped me. I went back to my case, removed all lifetimes and adding them a second time around worked. :slight_smile:

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.