Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I enforce parent-child struct lifetime?

Tags:

rust

I'm writing wrapper code for an external C library, and I'm trying to convince the Rust compiler to enforce external lifetime restrictions that are not reflected in the Rust code itself. For example, one type of "opaque handle" can return a child handle that is only valid for the lifetime of the parent handle.

I experimented with std::marker::PhantomData, but I couldn't convince the compiler to return the expected error.

In other words, I'd like the following block of code fail to compile:

struct Parent;

struct Child; // Note that there is no reference to the parent struct

impl Parent {
    fn get_child( &self ) -> Child {
        Child
    }
}

// I'd like this to complain with "p does not live long enough"
fn test() -> Child {
    let p = Parent;
    p.get_child()
}

fn main() {
    let c = test();
}
like image 589
Peter Bertok Avatar asked Dec 02 '15 08:12

Peter Bertok


1 Answers

You had the right idea with PhantomData. You add a lifetime parameter and a PhantomData field to Child. The PhantomData generic parameter is what you want to emulate in the struct. In this case you want Child to act as if it contains a &Parent.

struct Child<'a> {
    parent: PhantomData<&'a Parent>,
}

impl Parent {
    fn get_child<'a>(&'a self) -> Child<'a> {
        Child {
            parent: PhantomData,
        }
    }
}

You also need to modify the test function to have a generic argument, otherwise you don't see your requested doesn't live long enough error, because the Child needs a lifetime error occurs first.

fn test<'a>() -> Child<'a> {
    let p = Parent;
    p.get_child()
}

Try it out in the Playground

like image 86
oli_obk Avatar answered Nov 05 '22 21:11

oli_obk