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