@@ -316,7 +316,9 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
316
316
/// Note that, despite being safe, calling this function can have the side effect
317
317
/// of invalidating mutable references that unsafe code has created.
318
318
pub fn len ( & self ) -> usize {
319
- self . as_leaf ( ) . len as usize
319
+ // Crucially, we only access the `len` field here. There might be outstanding mutable references
320
+ // to keys/values that we must not invalidate.
321
+ unsafe { ( * self . as_leaf ( ) ) . len as usize }
320
322
}
321
323
322
324
/// Returns the height of this node in the whole tree. Zero height denotes the
@@ -334,11 +336,14 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
334
336
/// If the node is a leaf, this function simply opens up its data.
335
337
/// If the node is an internal node, so not a leaf, it does have all the data a leaf has
336
338
/// (header, keys and values), and this function exposes that.
337
- fn as_leaf ( & self ) -> & LeafNode < K , V > {
339
+ ///
340
+ /// Returns a raw ptr to avoid invalidating other references to this node
341
+ /// (such as during iteration).
342
+ fn as_leaf ( & self ) -> * const LeafNode < K , V > {
338
343
// The node must be valid for at least the LeafNode portion.
339
344
// This is not a reference in the NodeRef type because we don't know if
340
345
// it should be unique or shared.
341
- unsafe { self . node . as_ref ( ) }
346
+ self . node . as_ptr ( )
342
347
}
343
348
344
349
/// Borrows a view into the keys stored in the node.
@@ -361,7 +366,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
361
366
pub fn ascend (
362
367
self ,
363
368
) -> Result < Handle < NodeRef < BorrowType , K , V , marker:: Internal > , marker:: Edge > , Self > {
364
- let parent_as_leaf = self . as_leaf ( ) . parent as * const LeafNode < K , V > ;
369
+ let parent_as_leaf = unsafe { ( * self . as_leaf ( ) ) . parent as * const LeafNode < K , V > } ;
365
370
if let Some ( non_zero) = NonNull :: new ( parent_as_leaf as * mut _ ) {
366
371
Ok ( Handle {
367
372
node : NodeRef {
@@ -370,7 +375,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
370
375
root : self . root ,
371
376
_marker : PhantomData ,
372
377
} ,
373
- idx : unsafe { usize:: from ( * self . as_leaf ( ) . parent_idx . as_ptr ( ) ) } ,
378
+ idx : unsafe { usize:: from ( * ( * self . as_leaf ( ) ) . parent_idx . as_ptr ( ) ) } ,
374
379
_marker : PhantomData ,
375
380
} )
376
381
} else {
@@ -475,13 +480,13 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
475
480
impl < ' a , K : ' a , V : ' a , Type > NodeRef < marker:: Immut < ' a > , K , V , Type > {
476
481
fn into_key_slice ( self ) -> & ' a [ K ] {
477
482
unsafe {
478
- slice:: from_raw_parts ( MaybeUninit :: slice_as_ptr ( & self . as_leaf ( ) . keys ) , self . len ( ) )
483
+ slice:: from_raw_parts ( MaybeUninit :: slice_as_ptr ( & ( * self . as_leaf ( ) ) . keys ) , self . len ( ) )
479
484
}
480
485
}
481
486
482
487
fn into_val_slice ( self ) -> & ' a [ V ] {
483
488
unsafe {
484
- slice:: from_raw_parts ( MaybeUninit :: slice_as_ptr ( & self . as_leaf ( ) . vals ) , self . len ( ) )
489
+ slice:: from_raw_parts ( MaybeUninit :: slice_as_ptr ( & ( * self . as_leaf ( ) ) . vals ) , self . len ( ) )
485
490
}
486
491
}
487
492
}
0 commit comments