&'a &'b
and not with where 'a: 'b
I suppose I don't understand enough of how the first is different from the second one, and how it impacts this issue. &'a &'b
and not with where 'a: 'b
I suppose I don't understand enough of how the first is different from the second one, and how it impacts this issue.In contrast, if a lifetime is subject to an explicit where bound, it must be "early-bound": each function pointer can must choose one particular value for that lifetime, that must be upheld for every call. For a practical example, you might have tried to declare a closure with a &T parameter, only to get lifetime errors when you call it twice. This is because the lifetime in the closure type is early-bound and must be the same for every call. (Sometimes the compiler figures out that a late-bound lifetime is desired, but the rules are very subtle. This is also why it's difficult to write a function that accepts a generic async closure.)
Late binding is necessary for certain kinds of variance, which is a big part of this issue. Function pointers are contravariant in their parameters, which means if you have a type like "fn(&'short str)", you can cast it to "fn(&'static str)", since a 'static reference will always be valid for 'short. They're also covariant in their return type, so that "fn() -> &'static str" can be cast into "fn() -> &'short str". But when performing these variance transformations with late-bound lifetimes, the compiler doesn't always take into account the implied bounds in the source type properly, which allows you to perform casts that aren't actually sound.
Also, it's a lot less weird if you don't stop in the middle of the type. The entire type is for example
&'a &'b u8
or &'a &'b ()
So the outer reference has lifetime 'a and the inner reference has lifetime 'b.Yes it does; there's an implied `'b: 'a` outlives relationship that's required for the type to be well-formed.
where 'b: 'a
meaning 'b is at least as useful as 'a. So 'b can live the same time, or longer, but not less.