Is it possible for a struct to outlive its lifetime parameter?

For context, I am the maintainer of a crate that allows creating self-referencing structs (ouroboros). I have had a couple of users run into trouble with structs that use lifetime parameters. Their errors could be resolved if it can be assumed that all lifetime parameters outlive the struct, but I want to make sure that it is always the case before I add that assumption to the crate. Here is an example of one of the patterns this assumption would enable, not particularly useful but illustrates the concept:

#[ouroboros::self_referencing]
struct RefHolder<'a> {
    external_reference: &'a str,
    #[borrows(external_reference)]
    internal_reference: &'this str,
}

impl<'a> RefHolder<'a> {
    fn make_new(external: &'a str) -> RefHolder<'a> {
        RefHolderBuilder {
            external_reference: external,
            internal_reference_builder: |ext| &*ext,
        }
    }
}

In this case, no matter what I've tried, Rust will always throw an error if I try to drop whatever external refers to as long as there is an instance of RefHolder that is borrowing it, so the code is safe. Can this guarantee be extended to all lifetime parameters in general?

This holds if and only if the struct is not contravariant in the lifetime.

struct RefHolder<'a> {
    func: fn(&'a u32) -> u32,
}

fn foo<'a>(r: RefHolder<'a>) -> RefHolder<'static> {
    r
}
4 Likes

It looks like using contravariance, the lifetime parameter can only be made larger than the original lifetime, so the struct would still not outlive the parameter. From reading the page you linked, it looks like there are no ways to make the struct outlive its lifetime parameter, so I will go ahead and proceed with the changes. Thanks for your help!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.