Here's a crazy idea! Could we support 'a: T with the semantics that 'a must live at least as long as all the lifetime parameters in T? Currently, this can be simulated with traits:
The rules for implementing MaxLifetime<'a> for a given type T:
All the fields of T should implement MaxLifetime<'a>. All types with no type or lifetime parameters implement for<'a> MaxLifetime<'a>, and references MaxLifetime<'a> like so
impl<'a: 'b, 'b, T: ?Sized> MaxLifetime<'a> for &'b T {}
These rules could be encoded via a derive macro, however, this feels like something that the language should handle.
The syntax 'a: T seems much too clever and would add to lifetime confusion by Rust learners. I don't mean to doubt that this would be a useful feature, but an uncommonly-used feature like this should have a verbose name that gives people who haven't seen it before a clearer hint about the meaning.
I agree that any new extension to lifetimes should be met with scrutiny, in large part because beginners get tripped up with lifetimes. However since the syntax and semantics are so similar to existing constructs, I don't think this is too much of an additional burden. Said another way, if you understand T: 'a, then 'a: T is not that big of a step because they are analogous in syntax and semantics.
I agree that this is a niche use-case, but it has come up more than a few times in my code and in others' as well.
This means struct A(&'static str); couldn't be used where struct A(String); could, which doesn't seem right...
This is because you could have code:
fn f<'a, T>(v: T, r: &'a u8) where 'a: T {
}
struct A<T>(T);
fn g() {
let v: u8 = 0;
f::<A<&'static str>>(A(""), &v); // fails because v doesn't live as long as 'static
f::<A<String>>(A(String::new()), &v); // succeeds because String has no lifetimes
}
I dispute this, because it took me tens of minutes to understand what this feature means, and now that I do understand what it means, it seems like it is not what I would expect from the syntax 'a: T. In particular, T: 'a means that T's lifetime includes all of 'a, so I would expect that 'a: T would mean that 'a includes all of T's lifetime (so, for example, 'a: i32 would imply that 'a is 'static).
I also haven't been able to grok what the URLO thread is trying to do that requires this, so it's hard for me to come up with an alternative syntax that I would prefer (since that would require me to understand the purpose of the feature).
After thinking about this some more, I have to agree with @elidupree here. @atagunov's confusion on this proposal and @programmerjake's example which highlights my own misunderstanding of how this ought to be are telling that this proposal isn't as simple as I had thought. Thanks for all the feedback!
That does sound most consistent, unfortunately that's not too useful so I'm unsure how to fix the proposal.
Since String is a type with no lifetimes, it falls under the rule: "All types with no type or lifetime parameters implement for<'a> MaxLifetime<'a>", which means 'a: String for all lifetimes 'a, in particular including the lifetime of v.