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!