@@ -645,6 +645,8 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
645645 }
646646
647647 fn into_key_slice_mut ( mut self ) -> & ' a mut [ K ] {
648+ // Same as for `into_key_slice` above, we try to avoid a run-time check
649+ // (the alignment comparison will usually be performed at compile-time).
648650 if mem:: align_of :: < K > ( ) > mem:: align_of :: < LeafNode < ( ) , ( ) > > ( ) && self . is_shared_root ( ) {
649651 & mut [ ]
650652 } else {
@@ -667,9 +669,26 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
667669 }
668670 }
669671
670- fn into_slices_mut ( self ) -> ( & ' a mut [ K ] , & ' a mut [ V ] ) {
671- let k = unsafe { ptr:: read ( & self ) } ;
672- ( k. into_key_slice_mut ( ) , self . into_val_slice_mut ( ) )
672+ fn into_slices_mut ( mut self ) -> ( & ' a mut [ K ] , & ' a mut [ V ] ) {
673+ debug_assert ! ( !self . is_shared_root( ) ) ;
674+ // We cannot use the getters here, because calling the second one
675+ // invalidates the reference returned by the first.
676+ // More precisely, it is the call to `len` that is the culprit,
677+ // because that creates a shared reference to the header, which *can*
678+ // overlap with the keys.
679+ unsafe {
680+ let len = self . len ( ) ;
681+ let leaf = self . as_leaf_mut ( ) ;
682+ let keys = slice:: from_raw_parts_mut (
683+ MaybeUninit :: first_ptr_mut ( & mut ( * leaf) . keys ) ,
684+ len
685+ ) ;
686+ let vals = slice:: from_raw_parts_mut (
687+ MaybeUninit :: first_ptr_mut ( & mut ( * leaf) . vals ) ,
688+ len
689+ ) ;
690+ ( keys, vals)
691+ }
673692 }
674693}
675694
0 commit comments