4242// This implies that even an empty internal node has at least one edge.
4343
4444use core:: marker:: PhantomData ;
45- use core:: mem;
45+ use core:: mem:: { self , MaybeUninit } ;
4646use core:: ptr:: { self , Unique , NonNull } ;
4747use core:: slice;
4848
@@ -58,9 +58,6 @@ pub const CAPACITY: usize = 2 * B - 1;
5858/// these should always be put behind pointers, and specifically behind `BoxedNode` in the owned
5959/// case.
6060///
61- /// See also rust-lang/rfcs#197, which would make this structure significantly more safe by
62- /// avoiding accidentally dropping unused and uninitialized keys and values.
63- ///
6461/// We put the metadata first so that its position is the same for every `K` and `V`, in order
6562/// to statically allocate a single dummy node to avoid allocations. This struct is `repr(C)` to
6663/// prevent them from being reordered.
@@ -73,7 +70,7 @@ struct LeafNode<K, V> {
7370 /// This node's index into the parent node's `edges` array.
7471 /// `*node.parent.edges[node.parent_idx]` should be the same thing as `node`.
7572 /// This is only guaranteed to be initialized when `parent` is nonnull.
76- parent_idx : u16 ,
73+ parent_idx : MaybeUninit < u16 > ,
7774
7875 /// The number of keys and values this node stores.
7976 ///
@@ -83,8 +80,8 @@ struct LeafNode<K, V> {
8380
8481 /// The arrays storing the actual data of the node. Only the first `len` elements of each
8582 /// array are initialized and valid.
86- keys : [ K ; CAPACITY ] ,
87- vals : [ V ; CAPACITY ] ,
83+ keys : MaybeUninit < [ K ; CAPACITY ] > ,
84+ vals : MaybeUninit < [ V ; CAPACITY ] > ,
8885}
8986
9087impl < K , V > LeafNode < K , V > {
@@ -94,10 +91,10 @@ impl<K, V> LeafNode<K, V> {
9491 LeafNode {
9592 // As a general policy, we leave fields uninitialized if they can be, as this should
9693 // be both slightly faster and easier to track in Valgrind.
97- keys : mem :: uninitialized ( ) ,
98- vals : mem :: uninitialized ( ) ,
94+ keys : MaybeUninit :: uninitialized ( ) ,
95+ vals : MaybeUninit :: uninitialized ( ) ,
9996 parent : ptr:: null ( ) ,
100- parent_idx : mem :: uninitialized ( ) ,
97+ parent_idx : MaybeUninit :: uninitialized ( ) ,
10198 len : 0
10299 }
103100 }
@@ -115,10 +112,10 @@ unsafe impl Sync for LeafNode<(), ()> {}
115112// ever take a pointer past the first key.
116113static EMPTY_ROOT_NODE : LeafNode < ( ) , ( ) > = LeafNode {
117114 parent : ptr:: null ( ) ,
118- parent_idx : 0 ,
115+ parent_idx : MaybeUninit :: uninitialized ( ) ,
119116 len : 0 ,
120- keys : [ ( ) ; CAPACITY ] ,
121- vals : [ ( ) ; CAPACITY ] ,
117+ keys : MaybeUninit :: uninitialized ( ) ,
118+ vals : MaybeUninit :: uninitialized ( ) ,
122119} ;
123120
124121/// The underlying representation of internal nodes. As with `LeafNode`s, these should be hidden
@@ -430,7 +427,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
430427 root : self . root ,
431428 _marker : PhantomData
432429 } ,
433- idx : self . as_leaf ( ) . parent_idx as usize ,
430+ idx : unsafe { usize :: from ( * self . as_leaf ( ) . parent_idx . get_ref ( ) ) } ,
434431 _marker : PhantomData
435432 } )
436433 } else {
@@ -567,7 +564,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
567564 // the node, which is allowed by LLVM.
568565 unsafe {
569566 slice:: from_raw_parts (
570- self . as_leaf ( ) . keys . as_ptr ( ) ,
567+ self . as_leaf ( ) . keys . as_ptr ( ) as * const K ,
571568 self . len ( )
572569 )
573570 }
@@ -578,7 +575,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
578575 debug_assert ! ( !self . is_shared_root( ) ) ;
579576 unsafe {
580577 slice:: from_raw_parts (
581- self . as_leaf ( ) . vals . as_ptr ( ) ,
578+ self . as_leaf ( ) . vals . as_ptr ( ) as * const V ,
582579 self . len ( )
583580 )
584581 }
@@ -605,7 +602,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
605602 } else {
606603 unsafe {
607604 slice:: from_raw_parts_mut (
608- & mut self . as_leaf_mut ( ) . keys as * mut [ K ] as * mut K ,
605+ self . as_leaf_mut ( ) . keys . get_mut ( ) as * mut [ K ] as * mut K ,
609606 self . len ( )
610607 )
611608 }
@@ -616,7 +613,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
616613 debug_assert ! ( !self . is_shared_root( ) ) ;
617614 unsafe {
618615 slice:: from_raw_parts_mut (
619- & mut self . as_leaf_mut ( ) . vals as * mut [ V ] as * mut V ,
616+ self . as_leaf_mut ( ) . vals . get_mut ( ) as * mut [ V ] as * mut V ,
620617 self . len ( )
621618 )
622619 }
@@ -1013,7 +1010,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
10131010 let ptr = self . node . as_internal_mut ( ) as * mut _ ;
10141011 let mut child = self . descend ( ) ;
10151012 child. as_leaf_mut ( ) . parent = ptr;
1016- child. as_leaf_mut ( ) . parent_idx = idx;
1013+ child. as_leaf_mut ( ) . parent_idx . set ( idx) ;
10171014 }
10181015
10191016 /// Unsafely asserts to the compiler some static information about whether the underlying
@@ -1152,12 +1149,12 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV>
11521149
11531150 ptr:: copy_nonoverlapping (
11541151 self . node . keys ( ) . as_ptr ( ) . add ( self . idx + 1 ) ,
1155- new_node. keys . as_mut_ptr ( ) ,
1152+ new_node. keys . as_mut_ptr ( ) as * mut K ,
11561153 new_len
11571154 ) ;
11581155 ptr:: copy_nonoverlapping (
11591156 self . node . vals ( ) . as_ptr ( ) . add ( self . idx + 1 ) ,
1160- new_node. vals . as_mut_ptr ( ) ,
1157+ new_node. vals . as_mut_ptr ( ) as * mut V ,
11611158 new_len
11621159 ) ;
11631160
@@ -1210,12 +1207,12 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
12101207
12111208 ptr:: copy_nonoverlapping (
12121209 self . node . keys ( ) . as_ptr ( ) . add ( self . idx + 1 ) ,
1213- new_node. data . keys . as_mut_ptr ( ) ,
1210+ new_node. data . keys . as_mut_ptr ( ) as * mut K ,
12141211 new_len
12151212 ) ;
12161213 ptr:: copy_nonoverlapping (
12171214 self . node . vals ( ) . as_ptr ( ) . add ( self . idx + 1 ) ,
1218- new_node. data . vals . as_mut_ptr ( ) ,
1215+ new_node. data . vals . as_mut_ptr ( ) as * mut V ,
12191216 new_len
12201217 ) ;
12211218 ptr:: copy_nonoverlapping (
0 commit comments