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();
}
You had the right idea with
PhantomData
. You add a lifetime parameter and aPhantomData
field toChild
. ThePhantomData
generic parameter is what you want to emulate in the struct. In this case you wantChild
to act as if it contains a&Parent
.You also need to modify the
test
function to have a generic argument, otherwise you don't see your requesteddoesn't live long enough
error, because theChild needs a lifetime
error occurs first.Try it out in the Playground