Lifetime bound of the form T: 'a
Asked Answered
E

1

8

I am trying to understand what T: 'a means, where, I guess, T is a type and 'a is a lifetime.

I understand what 'a: 'b means: x('a) outlives y('b) and so we cannot assign y to x in the following code

fn foo<'a, 'b, T>(mut x: &'a T, mut y: &'b T) 
   where 'a: 'b {
  x = y; //compile time error
}

This reference book writes

T: 'a means that all lifetime parameters of T outlive 'a.

But I am confused by the "all lifetime parameters of T". What is a "lifetime parameter of (type?) T" ? I know that 'a is a lifetime of x in this signature fn foo<'a, T>(x: &'a T). Does it mean the same thing?

Could someone explain what T:'a means by giving an example? I can't even imagine where we could use it and why.

Esparza answered 31/12, 2020 at 11:5 Comment(1)
Imagine a type struct Foo<'b, 'c> {bar: &'b str, boo: &'c [u8] }. T:'a would mean that than calling foo::<Foo>() would guarantee that 'b and 'c are at least 'aChere
I
5

While references can have lifetimes, types can have lifetimes too. The simplest example would probably be:

struct Foo<'a> {
    x: &'a i32
}

If you construct a struct of type Foo (let's call this instance foo) with a reference to an i32 (let's call this num) on the local stack, then foo cannot live longer than the scope of num, regardless of the scope of foo itself. It's a lifetime without a reference (to the type, at least).

Let's take a look at a real world example of this: Box::leak:

pub fn leak<'a>(b: Box<T>) -> &'a mut T
where
    T: 'a,

The type signature basically says that, given a box, you can create a reference to its value for any lifetime as long as the value itself is capable of lasting for that lifetime. So, we could create a &'static i32 with Box::leak, since i32 has nothing restricting its lifetime, but we can't create a &'static Foo that references a stack integer, as it has a reference restricting its lifetime.

Note that if you're testing this locally, things like &5 will actually create a &'static i32 due to rvalue static promotion, so you might want to change the i32 to an unpromotable type like String.

Isley answered 31/12, 2020 at 11:51 Comment(7)
Thank you for reply. I don't understand how a Type can "live". I understand that a variable can live (on a stack or heap), reference can live (ref is simply a pointer, 4 byte value), instance of a struct can live... but type (u32, Foo, str...) are not something that live, they are used to declare a var (kinda inform compiler that a variable will be of some size). Am I wrong?Esparza
@Esparza What if your struct contains a reference though?Isley
Right. Then it must have a lifetime somehow related to that ref.Esparza
@Applet123, one more thing. We have &'a mut T and where T: 'a. Do &'a mut T say "the REF to the var has lifetime 'a" and T: 'a say "type T outlives 'a"? I mean &'a mut T is not enough, right?Esparza
&'a mut T means that the reference has lifetime 'a, and the T: 'a is implied (but means that T should be able to outlive or match 'a).Isley
If T: 'a is implied by &'a mut T then why do we need to write where T: 'a? That's what really confused me.Esparza
From the comment next to the function declaration: "Technically not needed, but kept to be explicit."Isley

© 2022 - 2024 — McMap. All rights reserved.