Example where lifetime bound 'a: 'b in a struct matters?

Hi,

While experimenting with lifetimes, I’m trying to find an example where a lifetime bound of a struct matters and that does not use 'static.

Let’s say we have the following struct

#[derive(Debug)]
struct MyRefs<'a, 'b, T>(&'a T, &'b T) where 'a: 'b;

Then the following will fail to compile, unless we remove the lifetime bound:

fn main() {
    static OUTER: i32 = 0;
    let inner = 1;
    let r = MyRefs::<'_, 'static, i32>(&inner, &OUTER);
    dbg!(&r);
}

Even if inner is the local variable of a function, and outer is the reference to an argument, the compiler is able to convince itself that inner lives long enough.

Can there ever be a situation that does not involve 'static where lifetimes appear that fail to meet the requirement in MyRefs?

You mean, it doesn't fail in that case? That is not true.

// Fails to compile with the bound, compiles without it
fn example<'b>(arg: &'b i32) {
    let local = 0;
    MyRefs::<'_, 'b, _>(&local, arg);
}

Maybe you left off the annotation? In that case, covariance kicks in and the 'b gets coerced to something shorter.


Here's a complementary example that compiles with the bound on the struct, but not if you remove the bound.

// Compiles with the bound, fails to compile without it
fn example<'a, 'b, T>(arg: MyRefs<'a, 'b, T>, s: &'a str) -> &'b str {
    s
}

The reason is that lifetime bounds on a struct become implied bounds elsewhere, so the presence of MyRefs<'a, 'b, T> in the input arguments means there's an implicit 'a: 'b bound (and T: 'a and T: 'b, due to the presence of &'a T and &'b T in the fields; that's RFC 2093).

1 Like

Indeed, thanks a lot.

Very interesting, thanks!