Skip to content

Commit 46ea9b4

Browse files
authored
Rollup merge of rust-lang#82439 - ssomers:btree_fix_unsafety, r=Mark-Simulacrum
BTree: fix untrue safety Fix needless and missing `unsafe` tags. r? ``@Mark-Simulacrum``
2 parents 7ca5fa6 + 986a183 commit 46ea9b4

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

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,8 @@ impl<K, V> LeafNode<K, V> {
7777
}
7878
}
7979

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

145143
impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
146144
fn new_leaf() -> Self {
147-
Self::from_new_leaf(unsafe { LeafNode::new() })
145+
Self::from_new_leaf(LeafNode::new())
148146
}
149147

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

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

1086-
let kv = self.split_leaf_data(&mut new_node);
1086+
let kv = self.split_leaf_data(&mut new_node);
10871087

1088-
let right = NodeRef::from_new_leaf(new_node);
1089-
SplitResult { left: self.node, kv, right }
1090-
}
1088+
let right = NodeRef::from_new_leaf(new_node);
1089+
SplitResult { left: self.node, kv, right }
10911090
}
10921091

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

0 commit comments

Comments
 (0)