Skip to content

Commit 986a183

Browse files
committed
BTree: fix untrue safety
1 parent a4e595d commit 986a183

File tree

1 file changed

+15
-16
lines changed
  • library/alloc/src/collections/btree

1 file changed

+15
-16
lines changed

library/alloc/src/collections/btree/node.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,8 @@ impl<K, V> LeafNode<K, V> {
7878
}
7979
}
8080

81-
/// Creates a new boxed `LeafNode`. Unsafe because all nodes should really be hidden behind
82-
/// `BoxedNode`, preventing accidental dropping of uninitialized keys and values.
83-
unsafe fn new() -> Box<Self> {
81+
/// Creates a new boxed `LeafNode`.
82+
fn new() -> Box<Self> {
8483
unsafe {
8584
let mut leaf = Box::new_uninit();
8685
LeafNode::init(leaf.as_mut_ptr());
@@ -108,10 +107,9 @@ struct InternalNode<K, V> {
108107
impl<K, V> InternalNode<K, V> {
109108
/// Creates a new boxed `InternalNode`.
110109
///
111-
/// This is unsafe for two reasons. First, it returns an owned `InternalNode` in a box, risking
112-
/// dropping of uninitialized fields. Second, an invariant of internal nodes is that `len + 1`
113-
/// edges are initialized and valid, meaning that even when the node is empty (having a
114-
/// `len` of 0), there must be one initialized and valid edge. This function does not set up
110+
/// # Safety
111+
/// An invariant of internal nodes is that they have at least one
112+
/// initialized and valid edge. This function does not set up
115113
/// such an edge.
116114
unsafe fn new() -> Box<Self> {
117115
unsafe {
@@ -145,7 +143,7 @@ impl<K, V> Root<K, V> {
145143

146144
impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
147145
fn new_leaf() -> Self {
148-
Self::from_new_leaf(unsafe { LeafNode::new() })
146+
Self::from_new_leaf(LeafNode::new())
149147
}
150148

151149
fn from_new_leaf(leaf: Box<LeafNode<K, V>>) -> Self {
@@ -157,10 +155,13 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
157155
fn new_internal(child: Root<K, V>) -> Self {
158156
let mut new_node = unsafe { InternalNode::new() };
159157
new_node.edges[0].write(child.node);
160-
NodeRef::from_new_internal(new_node, child.height + 1)
158+
unsafe { NodeRef::from_new_internal(new_node, child.height + 1) }
161159
}
162160

163-
fn from_new_internal(internal: Box<InternalNode<K, V>>, height: usize) -> Self {
161+
/// # Safety
162+
/// `height` must not be zero.
163+
unsafe fn from_new_internal(internal: Box<InternalNode<K, V>>, height: usize) -> Self {
164+
debug_assert!(height > 0);
164165
let node = NonNull::from(Box::leak(internal)).cast();
165166
let mut this = NodeRef { height, node, _marker: PhantomData };
166167
this.borrow_mut().correct_all_childrens_parent_links();
@@ -1086,14 +1087,12 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
10861087
/// - All the key-value pairs to the right of this handle are put into a newly
10871088
/// allocated node.
10881089
pub fn split(mut self) -> SplitResult<'a, K, V, marker::Leaf> {
1089-
unsafe {
1090-
let mut new_node = LeafNode::new();
1090+
let mut new_node = LeafNode::new();
10911091

1092-
let kv = self.split_leaf_data(&mut new_node);
1092+
let kv = self.split_leaf_data(&mut new_node);
10931093

1094-
let right = NodeRef::from_new_leaf(new_node);
1095-
SplitResult { left: self.node, kv, right }
1096-
}
1094+
let right = NodeRef::from_new_leaf(new_node);
1095+
SplitResult { left: self.node, kv, right }
10971096
}
10981097

10991098
/// Removes the key-value pair pointed to by this handle and returns it, along with the edge

0 commit comments

Comments
 (0)