Rollup merge of #82439 - ssomers:btree_fix_unsafety, r=Mark-Simulacrum

BTree: fix untrue safety

Fix needless and missing `unsafe` tags.

r? ````@Mark-Simulacrum````
This commit is contained in:
Yuki Okushi 2021-03-03 16:27:39 +09:00 committed by GitHub
commit 46f9253098
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -77,9 +77,8 @@ impl<K, V> LeafNode<K, V> {
} }
} }
/// Creates a new boxed `LeafNode`. Unsafe because all nodes should really be hidden behind /// Creates a new boxed `LeafNode`.
/// `BoxedNode`, preventing accidental dropping of uninitialized keys and values. fn new() -> Box<Self> {
unsafe fn new() -> Box<Self> {
unsafe { unsafe {
let mut leaf = Box::new_uninit(); let mut leaf = Box::new_uninit();
LeafNode::init(leaf.as_mut_ptr()); LeafNode::init(leaf.as_mut_ptr());
@ -107,10 +106,9 @@ struct InternalNode<K, V> {
impl<K, V> InternalNode<K, V> { impl<K, V> InternalNode<K, V> {
/// Creates a new boxed `InternalNode`. /// Creates a new boxed `InternalNode`.
/// ///
/// This is unsafe for two reasons. First, it returns an owned `InternalNode` in a box, risking /// # Safety
/// dropping of uninitialized fields. Second, an invariant of internal nodes is that `len + 1` /// An invariant of internal nodes is that they have at least one
/// edges are initialized and valid, meaning that even when the node is empty (having a /// initialized and valid edge. This function does not set up
/// `len` of 0), there must be one initialized and valid edge. This function does not set up
/// such an edge. /// such an edge.
unsafe fn new() -> Box<Self> { unsafe fn new() -> Box<Self> {
unsafe { unsafe {
@ -144,7 +142,7 @@ impl<K, V> Root<K, V> {
impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> { impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
fn new_leaf() -> Self { fn new_leaf() -> Self {
Self::from_new_leaf(unsafe { LeafNode::new() }) Self::from_new_leaf(LeafNode::new())
} }
fn from_new_leaf(leaf: Box<LeafNode<K, V>>) -> Self { fn from_new_leaf(leaf: Box<LeafNode<K, V>>) -> Self {
@ -156,10 +154,13 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
fn new_internal(child: Root<K, V>) -> Self { fn new_internal(child: Root<K, V>) -> Self {
let mut new_node = unsafe { InternalNode::new() }; let mut new_node = unsafe { InternalNode::new() };
new_node.edges[0].write(child.node); new_node.edges[0].write(child.node);
NodeRef::from_new_internal(new_node, child.height + 1) unsafe { NodeRef::from_new_internal(new_node, child.height + 1) }
} }
fn from_new_internal(internal: Box<InternalNode<K, V>>, height: usize) -> Self { /// # Safety
/// `height` must not be zero.
unsafe fn from_new_internal(internal: Box<InternalNode<K, V>>, height: usize) -> Self {
debug_assert!(height > 0);
let node = NonNull::from(Box::leak(internal)).cast(); let node = NonNull::from(Box::leak(internal)).cast();
let mut this = NodeRef { height, node, _marker: PhantomData }; let mut this = NodeRef { height, node, _marker: PhantomData };
this.borrow_mut().correct_all_childrens_parent_links(); this.borrow_mut().correct_all_childrens_parent_links();
@ -1080,7 +1081,6 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
/// - All the key-value pairs to the right of this handle are put into a newly /// - All the key-value pairs to the right of this handle are put into a newly
/// allocated node. /// allocated node.
pub fn split(mut self) -> SplitResult<'a, K, V, marker::Leaf> { pub fn split(mut self) -> SplitResult<'a, K, V, marker::Leaf> {
unsafe {
let mut new_node = LeafNode::new(); let mut new_node = LeafNode::new();
let kv = self.split_leaf_data(&mut new_node); let kv = self.split_leaf_data(&mut new_node);
@ -1088,7 +1088,6 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
let right = NodeRef::from_new_leaf(new_node); let right = NodeRef::from_new_leaf(new_node);
SplitResult { left: self.node, kv, right } SplitResult { left: self.node, kv, right }
} }
}
/// Removes the key-value pair pointed to by this handle and returns it, along with the edge /// Removes the key-value pair pointed to by this handle and returns it, along with the edge
/// that the key-value pair collapsed into. /// that the key-value pair collapsed into.