Lifetime may not live long enough

I'm having an issue with lifetimes that I can't figure out.

This is a more or less minimal example of what I'm trying to achieve:

struct S1(u32);
struct S2(u32);

trait T1 {}

impl T1 for S1 {

}

impl Into<S2> for &S1 {
    fn into(self) -> S2 {
        S2(self.0 % 2)
    }
}

pub fn consume_closure<C, S>(closure: &C, val: &S) -> u32 where C: Fn(&S) -> u32 {
    closure(val)
}


pub fn test<'a, 'b: 'a, S: T1 + 'a>(val: &S) -> u32 where S2: From<&'a S> {
    consume_closure(&|s: &'b S|{
        let s2: S2 = S2::from(s);
        s2.0
    }, &val)
}

which fails with the error

 | pub fn test<'a, 'b: 'a, S: T1 + 'a>(val: &S) -> u32 where S2: From<&'a S> {
 |                 -- lifetime `'b` defined here
 |     consume_closure(&|s: &'b S|{
 |                       ^  - let's call the lifetime of this reference `'1`
 |                       |
 |                       requires that `'1` must outlive `'b`

Before I added the lifetime 'b it failed with borrowed data escapes outside of closure error. Also, changing the code to use concrete types instead of the S: T1 + 'a and where S2: From<&'a S> parts also works, but I'd like to avoid having to resort to that solution.

Any help figuring out this problem would be appreciated :slight_smile:

I'm not sure what we are and aren't allowed to change in the signature, but you probably meant this.


By the way, don't force people to pass closures by reference. That's generally a pain for the caller.

1 Like

Thanks a lot, this fixed my issue. I wasn't aware of for at all.
In the real code I am using the closure in chain of iterator calls, so I think I have to pass it by reference. I'll see if I can simplify it though.

You don't have to. If a closure type F: Fn, then &F: Fn as well (mutatis mutandis for FnMut and &mut F).

3 Likes