@@ -316,7 +316,9 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
316316 /// Note that, despite being safe, calling this function can have the side effect
317317 /// of invalidating mutable references that unsafe code has created.
318318 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 }
320322 }
321323
322324 /// 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> {
334336 /// If the node is a leaf, this function simply opens up its data.
335337 /// If the node is an internal node, so not a leaf, it does have all the data a leaf has
336338 /// (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 > {
338343 // The node must be valid for at least the LeafNode portion.
339344 // This is not a reference in the NodeRef type because we don't know if
340345 // it should be unique or shared.
341- unsafe { self . node . as_ref ( ) }
346+ self . node . as_ptr ( )
342347 }
343348
344349 /// Borrows a view into the keys stored in the node.
@@ -361,7 +366,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
361366 pub fn ascend (
362367 self ,
363368 ) -> 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 > } ;
365370 if let Some ( non_zero) = NonNull :: new ( parent_as_leaf as * mut _ ) {
366371 Ok ( Handle {
367372 node : NodeRef {
@@ -370,7 +375,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
370375 root : self . root ,
371376 _marker : PhantomData ,
372377 } ,
373- idx : unsafe { usize:: from ( * self . as_leaf ( ) . parent_idx . as_ptr ( ) ) } ,
378+ idx : unsafe { usize:: from ( * ( * self . as_leaf ( ) ) . parent_idx . as_ptr ( ) ) } ,
374379 _marker : PhantomData ,
375380 } )
376381 } else {
@@ -475,13 +480,13 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
475480impl < ' a , K : ' a , V : ' a , Type > NodeRef < marker:: Immut < ' a > , K , V , Type > {
476481 fn into_key_slice ( self ) -> & ' a [ K ] {
477482 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 ( ) )
479484 }
480485 }
481486
482487 fn into_val_slice ( self ) -> & ' a [ V ] {
483488 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 ( ) )
485490 }
486491 }
487492}
0 commit comments