One/two lifetimes for struct with one reference to a reference containing struct?

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

struct BarV1<'a, 'b> {
    foo: &'a Foo<'b>
}

struct BarV2<'a> {
    foo: &'a Foo<'a>
}

Is there any situation where BarV1 will work but BarV2 will not?

Well, basically, to construct a value like this, you need the inner lifetime to be shortenable so you can convert from &'short Foo<'long> to &'short Foo<'short> and store the latter in the field. That is the case for your particular snippet, but as you can read more about here, there are various changes you might make to the struct that would break it.

Another situation where the second version wont work is if you need bar.foo.data to give you a &'long i32 rather than a &'short i32. The second version only allows &'short i32 since the field is of type &'short Foo<'short>.

Like which? BarV1?

Which lifetime is the "inner" one?

BarV2

The one I called 'long.

I just read that doc again but it's a little brain twisty. I'm not sure what it means to break it without any context of how the struct is used. Or are you saying I could add fields that would make rustc reject the declaration of my struct without even looking at places where it's used?

This I think I understand. It's easiest for me to see if I consider a Foo<'static> made on the stack. Ideally foo.bar.data would give &'static i32, but if Bar is generic on only one lifetime it will get the stack one instead of static.

No, the declaration will be valid, but creating a value of such a type (e.g. if the reference in bar is mutable) can be quite difficult.

Indeed. With two lifetimes you could get an &'static i32 back out, but you can't with one lifetime.

Got it, thanks! :pray:

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.