rune
rune copied to clipboard
Root projection
This really needs to be proc macro to auto derive since implementing is unsafe, but that is not yet implemented.
We get a RootRef
by using RootOwner
on Root
. Root projection let's take a RootRef
of a struct and get RootRef
of the fields. This is similar to pin-project with a few big differences. First is that a Pin<P>
hold a pointer to some data, but our type RootRef<T>
hold the data itself. This means we can never return an owned RootRef
(like you can we Pin
) but instead return only references from our projections.
For example here is what is implemented for hashmap
https://github.com/CeleritasCelery/rune/blob/7136b74386a4586537ffa59c3be4849cb76354fe/src/arena/root.rs#L357-L384
We get the interior value which does not have RootRef
on it (similar to how we would get a &mut T
from a Pin<P>
with get_mut_unchecked
. Then we call the function we need (like get
) and cast the return value &V
directly to &RootRef<V>
. This let's us use Root-only methods on V
because we have transitively rooted it.
Why this is sound
RootRef
is repr(transparent)
so it is safe to cast it a wrapper, since we know the parent is rooted. The "child" reference borrows from the "parent", so it will follow rusts normal borrowing rules. This is the same logic that std::cell::Cell
's as_slice_of_cells uses.