@@ -645,6 +645,8 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
645
645
}
646
646
647
647
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).
648
650
if mem:: align_of :: < K > ( ) > mem:: align_of :: < LeafNode < ( ) , ( ) > > ( ) && self . is_shared_root ( ) {
649
651
& mut [ ]
650
652
} else {
@@ -667,9 +669,26 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
667
669
}
668
670
}
669
671
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
+ }
673
692
}
674
693
}
675
694
0 commit comments