Your argument makes sense on the one hand: The presence of a generic parameter declaration isn't what restricts validity of the struct, but the actual reference contained inside does. Ok, I can see that perspective, and I see how that conclusion came about.
But on the other hand, the generic parameter is the contract by which the compiler makes its validity proofs. There are cases where the lifetime parameter is not used in any real reference at all (PhantomData
being quite common to "represent" a borrow without actually holding one).
I posted in another thread a while back where a very similar discussion was taking place: Borrow checker and structs containing references - #8 by parasyte And I want to bring up the sources that I linked in that thread again, because they are very relevant here:
Lifetime notation · baby steps describes the initial motivation for introducing this syntax. I think it does an excellent job providing the stark contrast between how things were before the generic parameters were introduced, and where we are today.
Reading the historical context is one thing but knowing that the generic parameter is fundamentally how the borrow checker operates with structs is really quite important. The reasoning for the proofs has pretty much always existed, but the syntax makes it explicit for readers. And provides the ability for structs to contain multiple disjoint references.
And Lifetime notation redux · baby steps brings it up to nearly the modern syntax.
My thoughts here are that the declaration of the lifetime parameter has everything to do with instance validity requirements. And that's because we don't have any other tools to do the same job.