At this point I've got a use to assuming in safe Rust that I generally need to keep my data structures acyclic. I'm trying to better understand what I can get away with in unsafe code.
I understand that it's definitely undefined behavior if I ever have two &mut
referring to the same object. I also understand that if I have a &mut
referring to some object it is possible for me to turn that into a &mut
to anything contained directly or indirectly by that object so long as fields are all public.
My question is is it okay (defined behavior) If I write unsafe code that makes it so that the user might have access to &mut
for an object a
at the same time as &mut
for an object b
, where b
is somehow reachable from a
, but not via any public safe interface, so that in practice two &mut
to b
never coexist.
In other words if I use other features of the language to make sure that in practice users writing safe code can't turn the &mut
to a
into a &mut
to b
, is it ok that b
is technically reachable from a
?
The first way I can imagine doing this is simply that a
contains a private pointer to b
. Pointers can't be dereferenced in safe code anyway, and I assume then it's up to me and my implementation to make sure that I never mutable dereference the private pointer while another dereference of it is still alive, and make sure I haven't exposed any safe functions that would trigger this.
The second way I could imagine it is direct ownership, where a
privately contains a b
, but where the interface for a
doesn't expose b
directly. If the public methods of a
only let you get &mut
to components of a
other than b
, I assume it is safe for &mut
to a
to exist in the program at the same time as a &mut
to b
?