Given this code:
struct RefWrapper<'a, T> {
r: &'a T,
}
... the compiler complains:
error: the parameter type
T
may not live long enoughconsider adding an explicit lifetime bound
T: 'a
so that the reference type&'a T
does not outlive the data it points at.
I've seen this error multiple times already and so far I just listened to the compiler and everything worked out fine. However, thinking more about it, I don't understand why I have to write T: 'a
.
As far as I understand, it is already impossible to get such a reference. Having &'a T
implies that there is an object of type T
that lives for at least 'a
. But we can't store any references in said object which point to data having a shorter lifetime than 'a
. This would already result in a compiler error.
In that sense it is already impossible to get a &'a T
where T
does not outlive 'a
. Thus the additional annotation (T: 'a
) shouldn't be necessary.
Am I right? Am I wrong and if yes: how could I break code, if T: 'a
would not be required?
Links:
This is part of the well-formedness rules. The type
&'a T
is only well-formed ifT: 'a
(“T outlives 'a”; it is required because we have a reference which we can access during the scope'a
; the pointed-to value inT
needs to be valid for at least that scope, too).struct RefWrapper<'a, T>
is a generic type and it says you can input a lifetime'x
and a typeU
and get aRefWrapper<'x, U>
type back. However, this type is not necessarily well-formed or even implemented unless the requirementT: 'a
is respected.This requirement comes from an implementation detail; it's not necessarily so that
T
and'a
are used together like&'a T
in the struct's internals. The well formedness requirement needs to be promoted to the public interface of theRefWrapper
struct, so that the requirements of forming aRefWrapper<'_, _>
type are public, even if the internal implementation is not.(There are other places where the same requirement
T: 'a
comes back but is implict:we spot a difference: here the type
&'a T
is part of the public api, too.)Congratulations, you were right! As of Rust 1.31, thanks to RFC 2093, Infer
T: 'x
outlives requirements on structs, the requirement on the user to type out this restriction has been removed:Basically, there wasn't a case where this wasn't required, so there wasn't much value in forcing the programmer to write it out.