Why don't references in structs have a default lifetime?


#1

Why don’t references in structs have a default lifetime? Is there a reason to allow a reference that doesn’t live at least as long as the struct itself?


#2

structs are unbound by default i.e. 'static. You have to be explicit to contain references. The lifetimes are external of any such structure. (i.e. their creation is before that of the structure and is then supplied to create the structure.)

Maybe info more in recent posting


#3

I don’t see how the default 'static lifetime prevents implementing default lifetimes for references inside the struct. If a struct is 'static the default lifetimes for references inside it could also be 'static since that’s the maximum they can live. Right?


#4

A reference always lives at least as long as the struct holding it, which is precisely why it needs to show up in the signature. I explained this in the thread linked above; please read my replies there.

A default lifetime of 'static wouldn’t be very useful because you would only be able to use borrows of static objects. Just try using &'static in your own structs and you’ll see what I mean.


#5

The explicitness of writing &'static makes the intent clearer. (It is similar to dyn adding some explicitness.)

There is also a overlap of concepts. When you construct you create something owned. The lifetime relates to the borrow of the item T. So when the structure contains a reference itself is still owned. You just become limited in how much you can move the structure as it is bound. (As @ExpHP gets post in before me finishing, This paragraph is essentially the same, just worded slightly differently.)

The content of Box is a case where there is a default implied 'static; there are quite a few topics of newcomers not knowing you have to add a lifetime specifier when storing referential structures.


#6

No, there’s no reason. There exist obvious cases where the compiler could easily allow lifetime elision and deduce lifetimes itself.

struct Foo {
   bar: &u32,
}

Lifetime annotations may be necessary in more complex structs that contain multiple references and/or structs that themselves contain references. But like with lifetimes in functions, there are cases where there is only one obvious solution and compiler doesn’t really need it spelled out for it.


#7

I think that particular example isn’t accepted for the same reason that this function isn’t: It’s pretty often that 'static isn’t what you wanted, so it’s better to ask “hey, what did you want here?” by erroring.

fn foo() -> &u32 { unimplemented!() }

That said, the function does give a

help: consider giving it a 'static lifetime

which the struct doesn’t, and perhaps should.

All that said, something like the following seems interesting:

struct Foo<'_> {
   bar: &u32,
}

Following the same “if there’s only one input lifetime, that’s almost certainly the output lifetime you wanted” that functions use.


#8

I don’t think the function error is a good analogy. These are opposite cases:

  • Foo<'a> allows any lifetime, including 'static.
  • foo() -> &u32 can only allow 'static and nothing else.

So with function you have no choice but to add the limitation. The struct doesn’t need the limitation (you can optionally add one if you really care).