Before I stumbled upon the code below, I was convinced that a lifetime in a type\'s lifetime parameter would always outlive its own instances. In other words, given a
Another way of explaining this is to notice that Foo doesn't actually hold a reference to anything with a lifetime of 'a. Rather, it holds a function that accepts a reference with lifetime 'a.
You can construct this same behaviour with an actual function instead of PhantomData. And you can even call that function:
struct Foo<'a>(fn(&'a ()));
fn hint<'a, Arg>(_: &'a Arg) -> Foo<'a> {
fn bar<'a, T: Debug>(value: &'a T) {
println!("The value is {:?}", value);
}
Foo(bar)
}
fn main() {
let outlived = ();
let foo;
{
let shortlived = ();
// &shortlived is borrowed by hint() but NOT stored in foo
foo = hint(&shortlived);
}
foo.0(&outlived);
}
As Francis explained in his excellent answer, the type of outlived is a subtype of the type of shortlived because its lifetime is longer. Therefore, the function inside foo can accept it because it can be coerced to shortlived's (shorter) lifetime.