42
42
// This implies that even an empty internal node has at least one edge.
43
43
44
44
use core:: marker:: PhantomData ;
45
- use core:: mem;
45
+ use core:: mem:: { self , MaybeUninit } ;
46
46
use core:: ptr:: { self , Unique , NonNull } ;
47
47
use core:: slice;
48
48
@@ -58,9 +58,6 @@ pub const CAPACITY: usize = 2 * B - 1;
58
58
/// these should always be put behind pointers, and specifically behind `BoxedNode` in the owned
59
59
/// case.
60
60
///
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
- ///
64
61
/// We put the metadata first so that its position is the same for every `K` and `V`, in order
65
62
/// to statically allocate a single dummy node to avoid allocations. This struct is `repr(C)` to
66
63
/// prevent them from being reordered.
@@ -73,7 +70,7 @@ struct LeafNode<K, V> {
73
70
/// This node's index into the parent node's `edges` array.
74
71
/// `*node.parent.edges[node.parent_idx]` should be the same thing as `node`.
75
72
/// This is only guaranteed to be initialized when `parent` is nonnull.
76
- parent_idx : u16 ,
73
+ parent_idx : MaybeUninit < u16 > ,
77
74
78
75
/// The number of keys and values this node stores.
79
76
///
@@ -83,8 +80,8 @@ struct LeafNode<K, V> {
83
80
84
81
/// The arrays storing the actual data of the node. Only the first `len` elements of each
85
82
/// array are initialized and valid.
86
- keys : [ K ; CAPACITY ] ,
87
- vals : [ V ; CAPACITY ] ,
83
+ keys : MaybeUninit < [ K ; CAPACITY ] > ,
84
+ vals : MaybeUninit < [ V ; CAPACITY ] > ,
88
85
}
89
86
90
87
impl < K , V > LeafNode < K , V > {
@@ -94,10 +91,10 @@ impl<K, V> LeafNode<K, V> {
94
91
LeafNode {
95
92
// As a general policy, we leave fields uninitialized if they can be, as this should
96
93
// 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 ( ) ,
99
96
parent : ptr:: null ( ) ,
100
- parent_idx : mem :: uninitialized ( ) ,
97
+ parent_idx : MaybeUninit :: uninitialized ( ) ,
101
98
len : 0
102
99
}
103
100
}
@@ -115,10 +112,10 @@ unsafe impl Sync for LeafNode<(), ()> {}
115
112
// ever take a pointer past the first key.
116
113
static EMPTY_ROOT_NODE : LeafNode < ( ) , ( ) > = LeafNode {
117
114
parent : ptr:: null ( ) ,
118
- parent_idx : 0 ,
115
+ parent_idx : MaybeUninit :: uninitialized ( ) ,
119
116
len : 0 ,
120
- keys : [ ( ) ; CAPACITY ] ,
121
- vals : [ ( ) ; CAPACITY ] ,
117
+ keys : MaybeUninit :: uninitialized ( ) ,
118
+ vals : MaybeUninit :: uninitialized ( ) ,
122
119
} ;
123
120
124
121
/// 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> {
430
427
root : self . root ,
431
428
_marker : PhantomData
432
429
} ,
433
- idx : self . as_leaf ( ) . parent_idx as usize ,
430
+ idx : unsafe { usize :: from ( * self . as_leaf ( ) . parent_idx . get_ref ( ) ) } ,
434
431
_marker : PhantomData
435
432
} )
436
433
} else {
@@ -567,7 +564,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
567
564
// the node, which is allowed by LLVM.
568
565
unsafe {
569
566
slice:: from_raw_parts (
570
- self . as_leaf ( ) . keys . as_ptr ( ) ,
567
+ self . as_leaf ( ) . keys . as_ptr ( ) as * const K ,
571
568
self . len ( )
572
569
)
573
570
}
@@ -578,7 +575,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
578
575
debug_assert ! ( !self . is_shared_root( ) ) ;
579
576
unsafe {
580
577
slice:: from_raw_parts (
581
- self . as_leaf ( ) . vals . as_ptr ( ) ,
578
+ self . as_leaf ( ) . vals . as_ptr ( ) as * const V ,
582
579
self . len ( )
583
580
)
584
581
}
@@ -605,7 +602,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
605
602
} else {
606
603
unsafe {
607
604
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 ,
609
606
self . len ( )
610
607
)
611
608
}
@@ -616,7 +613,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
616
613
debug_assert ! ( !self . is_shared_root( ) ) ;
617
614
unsafe {
618
615
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 ,
620
617
self . len ( )
621
618
)
622
619
}
@@ -1013,7 +1010,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
1013
1010
let ptr = self . node . as_internal_mut ( ) as * mut _ ;
1014
1011
let mut child = self . descend ( ) ;
1015
1012
child. as_leaf_mut ( ) . parent = ptr;
1016
- child. as_leaf_mut ( ) . parent_idx = idx;
1013
+ child. as_leaf_mut ( ) . parent_idx . set ( idx) ;
1017
1014
}
1018
1015
1019
1016
/// 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>
1152
1149
1153
1150
ptr:: copy_nonoverlapping (
1154
1151
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 ,
1156
1153
new_len
1157
1154
) ;
1158
1155
ptr:: copy_nonoverlapping (
1159
1156
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 ,
1161
1158
new_len
1162
1159
) ;
1163
1160
@@ -1210,12 +1207,12 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
1210
1207
1211
1208
ptr:: copy_nonoverlapping (
1212
1209
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 ,
1214
1211
new_len
1215
1212
) ;
1216
1213
ptr:: copy_nonoverlapping (
1217
1214
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 ,
1219
1216
new_len
1220
1217
) ;
1221
1218
ptr:: copy_nonoverlapping (
0 commit comments