@@ -152,30 +152,34 @@ impl<K, V> InternalNode<K, V> {
152152 }
153153}
154154
155- /// An owned pointer to a node. This basically is either `Box<LeafNode<K, V>>` or
156- /// `Box<InternalNode<K, V>>`. However, it contains no information as to which of the two types
157- /// of nodes is actually behind the box, and, partially due to this lack of information, has no
158- /// destructor.
155+ /// A managed, non-null pointer to a node. This is either an owned pointer to
156+ /// `LeafNode<K, V>`, an owned pointer to `InternalNode<K, V>`, or a (not owned)
157+ /// pointer to `NodeHeader<(), ()` (more specifically, the pointer to EMPTY_ROOT_NODE).
158+ /// All of these types have a `NodeHeader<K, V>` prefix, meaning that they have at
159+ /// least the same size as `NodeHeader<K, V>` and store the same kinds of data at the same
160+ /// offsets; and they have a pointer alignment at least as large as `NodeHeader<K, V>`'s.
161+ /// So that's the pointee type we store, and `as_header()` is unconditionally safe.
162+ /// However, `BoxedNode` contains no information as to which of the three types
163+ /// of nodes it actually contains, and, partially due to this lack of information,
164+ /// has no destructor.
159165struct BoxedNode < K , V > {
160- ptr : Unique < LeafNode < K , V > > ,
166+ ptr : Unique < NodeHeader < K , V > > ,
161167}
162168
163169impl < K , V > BoxedNode < K , V > {
164170 fn from_leaf ( node : Box < LeafNode < K , V > > ) -> Self {
165- BoxedNode { ptr : Box :: into_unique ( node) }
171+ BoxedNode { ptr : Box :: into_unique ( node) . cast ( ) }
166172 }
167173
168174 fn from_internal ( node : Box < InternalNode < K , V > > ) -> Self {
169- unsafe {
170- BoxedNode { ptr : Unique :: new_unchecked ( Box :: into_raw ( node) as * mut LeafNode < K , V > ) }
171- }
175+ BoxedNode { ptr : Box :: into_unique ( node) . cast ( ) }
172176 }
173177
174- unsafe fn from_ptr ( ptr : NonNull < LeafNode < K , V > > ) -> Self {
178+ unsafe fn from_ptr ( ptr : NonNull < NodeHeader < K , V > > ) -> Self {
175179 BoxedNode { ptr : Unique :: from ( ptr) }
176180 }
177181
178- fn as_ptr ( & self ) -> NonNull < LeafNode < K , V > > {
182+ fn as_ptr ( & self ) -> NonNull < NodeHeader < K , V > > {
179183 NonNull :: from ( self . ptr )
180184 }
181185}
@@ -197,11 +201,7 @@ impl<K, V> Root<K, V> {
197201
198202 pub fn shared_empty_root ( ) -> Self {
199203 Root {
200- node : unsafe {
201- BoxedNode :: from_ptr ( NonNull :: new_unchecked (
202- & EMPTY_ROOT_NODE as * const _ as * const LeafNode < K , V > as * mut _ ,
203- ) )
204- } ,
204+ node : unsafe { BoxedNode :: from_ptr ( NonNull :: from ( & EMPTY_ROOT_NODE ) . cast ( ) ) } ,
205205 height : 0 ,
206206 }
207207 }
@@ -310,7 +310,7 @@ impl<K, V> Root<K, V> {
310310/// Turning this into a `NodeHeader` reference is always safe.
311311pub struct NodeRef < BorrowType , K , V , Type > {
312312 height : usize ,
313- node : NonNull < LeafNode < K , V > > ,
313+ node : NonNull < NodeHeader < K , V > > ,
314314 // `root` is null unless the borrow type is `Mut`
315315 root : * const Root < K , V > ,
316316 _marker : PhantomData < ( BorrowType , Type ) > ,
@@ -372,11 +372,11 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
372372 /// See `NodeRef` on why the node may not be a shared root.
373373 unsafe fn as_leaf ( & self ) -> & LeafNode < K , V > {
374374 debug_assert ! ( !self . is_shared_root( ) ) ;
375- self . node . as_ref ( )
375+ & * ( self . node . as_ptr ( ) as * const LeafNode < K , V > )
376376 }
377377
378378 fn as_header ( & self ) -> & NodeHeader < K , V > {
379- unsafe { & * ( self . node . as_ptr ( ) as * const NodeHeader < K , V > ) }
379+ unsafe { self . node . as_ref ( ) }
380380 }
381381
382382 /// Returns whether the node is the shared, empty root.
@@ -505,7 +505,7 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
505505 /// This also implies you can invoke this member on the shared root, but the resulting pointer
506506 /// might not be properly aligned and definitely would not allow accessing keys and values.
507507 fn as_leaf_mut ( & mut self ) -> * mut LeafNode < K , V > {
508- self . node . as_ptr ( )
508+ self . node . as_ptr ( ) as * mut LeafNode < K , V >
509509 }
510510
511511 /// The caller must ensure that the node is not the shared root.
0 commit comments