diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index aa959c667accf..c0b75fd5eacec 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -413,7 +413,7 @@ impl NodeRef { impl<'a, K, V, Type> NodeRef, K, V, Type> { /// Unsafely asserts to the compiler some static information about whether this /// node is a `Leaf` or an `Internal`. - unsafe fn cast_unchecked(&mut self) -> NodeRef, K, V, NewType> { + unsafe fn cast_unchecked(self) -> NodeRef, K, V, NewType> { NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData } } @@ -721,7 +721,7 @@ impl Clone for Handle { } impl Handle { - /// Retrieves the node that contains the edge of key/value pair this handle points to. + /// Retrieves the node that contains the edge or key/value pair this handle points to. pub fn into_node(self) -> Node { self.node } @@ -1131,7 +1131,7 @@ impl<'a, K, V> Handle, K, V, marker::Leaf>, marker::KV> } /// Removes the key/value pair pointed to by this handle and returns it, along with the edge - /// between the now adjacent key/value pairs (if any) to the left and right of this handle. + /// that the key/value pair collapsed into. pub fn remove( mut self, ) -> ((K, V), Handle, K, V, marker::Leaf>, marker::Edge>) { @@ -1189,7 +1189,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: /// to by this handle, and the node immediately to the right of this handle into one new /// child of the underlying node, returning an edge referencing that new child. /// - /// Assumes that this edge `.can_merge()`. + /// Panics unless this edge `.can_merge()`. pub fn merge( mut self, ) -> Handle, K, V, marker::Internal>, marker::Edge> { @@ -1197,10 +1197,9 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: let self2 = unsafe { ptr::read(&self) }; let mut left_node = self1.left_edge().descend(); let left_len = left_node.len(); - let mut right_node = self2.right_edge().descend(); + let right_node = self2.right_edge().descend(); let right_len = right_node.len(); - // necessary for correctness, but in a private module assert!(left_len + right_len < CAPACITY); unsafe { @@ -1231,28 +1230,25 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: (*left_node.as_leaf_mut()).len += right_len as u16 + 1; - let layout = if self.node.height > 1 { + if self.node.height > 1 { + // SAFETY: the height of the nodes being merged is one below the height + // of the node of this edge, thus above zero, so they are internal. + let mut left_node = left_node.cast_unchecked(); + let right_node = right_node.cast_unchecked(); ptr::copy_nonoverlapping( - right_node.cast_unchecked().as_internal().edges.as_ptr(), - left_node - .cast_unchecked() - .as_internal_mut() - .edges - .as_mut_ptr() - .add(left_len + 1), + right_node.reborrow().as_internal().edges.as_ptr(), + left_node.reborrow_mut().as_internal_mut().edges.as_mut_ptr().add(left_len + 1), right_len + 1, ); for i in left_len + 1..left_len + right_len + 2 { - Handle::new_edge(left_node.cast_unchecked().reborrow_mut(), i) - .correct_parent_link(); + Handle::new_edge(left_node.reborrow_mut(), i).correct_parent_link(); } - Layout::new::>() + Global.dealloc(right_node.node.cast(), Layout::new::>()); } else { - Layout::new::>() - }; - Global.dealloc(right_node.node.cast(), layout); + Global.dealloc(right_node.node.cast(), Layout::new::>()); + } Handle::new_edge(self.node, self.idx) }