I have two structs. The first, "parent" struct holds a resource that needs explicit cleanup, which I am handling by deriving the Drop trait. The second, "child" struct is retrieved from the parent struct and needs that said resource hasn't been deallocated to be valid.
In other words, any parent instance must outlive its children.
My solution uses references to make the borrow checker enforce this rule.
struct Parent {
// Private resource data.
}
impl Parent {
fn new() -> Self {
Parent {}
}
fn new_child(&self) -> Child {
return Child { _parent: self };
}
}
impl Drop for Parent {
fn drop(&mut self) {
// Do some cleanup after which no instance of Child will be valid.
}
}
struct Child<'a> {
_parent: &'a Parent,
// Private data.
}
impl<'a> Child<'a> {
fn hello(&self) {
println!("Hello Child!");
}
}
fn main() {
let parent = Parent::new();
let child = parent.new_child();
child.hello();
// Fails to compile with the following line uncommented (as intented).
// drop(parent);
// child.hello();
}
This works, but the Child doesn't actually need to know its parent. I thought to replace the reference field with a PhantomData:
struct Child<'a> {
_parent: PhantomData<&'a Parent>,
// Private data.
}
But in this case, how can I "bind" _parent to the parent instance, in Parent::new_child?