Hello all,
I've got a struct that I need to keep a reference to it's parent. In effect it forms a stack. Here is a simplified version of the struct and methods
use std::ptr::NonNull;
MyStruct<'a> {
some_data: &'a DataStuff,
parent: Option<NonNull<MyStruct<'a>>
}
impl<'a> MyStruct<'a> {
pub fn new(some_data: &'a DataStuff) -> Self {
Self {
some_data,
parent: None,
}
}
pub fn child(parent: &mut MyStruct<'a>) -> Self {
Self {
some_data: parent.someData,
parent: Some(NonNull::from(parent))
}
}
// we need to do something with my struct but we also need to process the children
pub fn process_1(&mut self) {
self.do_stuff();
self.process_2();
}
// we create a child with what is now a NonNull to what will be it's parent and process
pub fn process_2(&mut self) {
let child = MyStruct(&mut *self)
child.process_1();
}
fn do_stuff(&mut self) {
match self.parent {
Some(parent) => { /* do a thing with parent */ }
None => { /* do something else if we're the base struct */}
}
}
}
So right now I'm using a NonNull pointer because it just ignores lifetimes, but after looking at this for a while it seem to me in this example that child
in process_2
has exclusive mutable access to &mut self
for the length of the method before it gets cleaned up. It feel I should be able to go with the safer &mut MyStruct<'a>
instead of a NonNull
. I tried changing my struct to something like
MyStruct<'a, 'p> {
someData: &'a DataStuff,
parent: Option<&'p mut MyStruct<'a, 'p>>
}
But I then get lifetime conflicts. I think the problem is it tries to take 'p
from the parent is too long since that the lifetime outlives the child. If it's not possible, I'm fine with the NonNull since I already have plenty of tests that show it works and it fairly easy to reason that it isn't mutating anything that disagrees with rust ownership semantics. Anyways appreciate any help on this!