Simple error: returning this value requires that `'1` must outlive `'2`

I'm trying to understand this simple lifetime problem:

struct Borrow<'a> {
    data: &'a[u64]
}

fn main() {
    let data = vec![0u64; 1];
    let borrow = |data: &[u64]| {
        let b = Borrow {
            data
        };
        b
    };
    
    borrow(data.as_slice());
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c524e580c9d07b367363917903ed5273

Error:

   Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
  --> src/main.rs:11:9
   |
7  |     let borrow = |data: &[u64]| {
   |                         -     - return type of closure is Borrow<'2>
   |                         |
   |                         let's call the lifetime of this reference `'1`
...
11 |         b
   |         ^ returning this value requires that `'1` must outlive `'2`

The Vec data clearly lives more than the Borrow inside of the closure. So why the error?

The code compiles if you remove the type annotation on the data arg in the closure. The issue is something to do with lifetime elision on closures. I think it is summed up by this comment. The open ticket tracking this is Make lifetime elision rules for closures consistent with lifetime elision rules for functions · Issue #86921 · rust-lang/rust (github.com)

2 Likes

When a type hint is necessary, you can usually use an identity function with an explicitly higher-ranked bound:

    fn hint<F: FnOnce(&[u64]) -> Borrow<'_>>(f: F) -> F {f}
    let borrow = hint(|data| { /* ... */ });
1 Like

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.