@@ -152,30 +152,34 @@ impl<K, V> InternalNode<K, V> {
152
152
}
153
153
}
154
154
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.
159
165
struct BoxedNode < K , V > {
160
- ptr : Unique < LeafNode < K , V > > ,
166
+ ptr : Unique < NodeHeader < K , V > > ,
161
167
}
162
168
163
169
impl < K , V > BoxedNode < K , V > {
164
170
fn from_leaf ( node : Box < LeafNode < K , V > > ) -> Self {
165
- BoxedNode { ptr : Box :: into_unique ( node) }
171
+ BoxedNode { ptr : Box :: into_unique ( node) . cast ( ) }
166
172
}
167
173
168
174
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 ( ) }
172
176
}
173
177
174
- unsafe fn from_ptr ( ptr : NonNull < LeafNode < K , V > > ) -> Self {
178
+ unsafe fn from_ptr ( ptr : NonNull < NodeHeader < K , V > > ) -> Self {
175
179
BoxedNode { ptr : Unique :: from ( ptr) }
176
180
}
177
181
178
- fn as_ptr ( & self ) -> NonNull < LeafNode < K , V > > {
182
+ fn as_ptr ( & self ) -> NonNull < NodeHeader < K , V > > {
179
183
NonNull :: from ( self . ptr )
180
184
}
181
185
}
@@ -197,11 +201,7 @@ impl<K, V> Root<K, V> {
197
201
198
202
pub fn shared_empty_root ( ) -> Self {
199
203
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 ( ) ) } ,
205
205
height : 0 ,
206
206
}
207
207
}
@@ -310,7 +310,7 @@ impl<K, V> Root<K, V> {
310
310
/// Turning this into a `NodeHeader` reference is always safe.
311
311
pub struct NodeRef < BorrowType , K , V , Type > {
312
312
height : usize ,
313
- node : NonNull < LeafNode < K , V > > ,
313
+ node : NonNull < NodeHeader < K , V > > ,
314
314
// `root` is null unless the borrow type is `Mut`
315
315
root : * const Root < K , V > ,
316
316
_marker : PhantomData < ( BorrowType , Type ) > ,
@@ -372,11 +372,11 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
372
372
/// See `NodeRef` on why the node may not be a shared root.
373
373
unsafe fn as_leaf ( & self ) -> & LeafNode < K , V > {
374
374
debug_assert ! ( !self . is_shared_root( ) ) ;
375
- self . node . as_ref ( )
375
+ & * ( self . node . as_ptr ( ) as * const LeafNode < K , V > )
376
376
}
377
377
378
378
fn as_header ( & self ) -> & NodeHeader < K , V > {
379
- unsafe { & * ( self . node . as_ptr ( ) as * const NodeHeader < K , V > ) }
379
+ unsafe { self . node . as_ref ( ) }
380
380
}
381
381
382
382
/// 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> {
505
505
/// This also implies you can invoke this member on the shared root, but the resulting pointer
506
506
/// might not be properly aligned and definitely would not allow accessing keys and values.
507
507
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 >
509
509
}
510
510
511
511
/// The caller must ensure that the node is not the shared root.
0 commit comments