|  | 
| 33 | 33 | 
 | 
| 34 | 34 | use core::marker::PhantomData; | 
| 35 | 35 | use core::mem::{self, MaybeUninit}; | 
|  | 36 | +use core::num::NonZero; | 
| 36 | 37 | use core::ptr::{self, NonNull}; | 
| 37 | 38 | use core::slice::SliceIndex; | 
| 38 | 39 | 
 | 
| @@ -143,7 +144,7 @@ type BoxedNode<K, V> = NonNull<LeafNode<K, V>>; | 
| 143 | 144 | /// | 
| 144 | 145 | /// A reference to a node. | 
| 145 | 146 | /// | 
| 146 |  | -/// This type has a number of parameters that controls how it acts: | 
|  | 147 | +/// This type has a number of parameters that control how it acts: | 
| 147 | 148 | /// - `BorrowType`: A dummy type that describes the kind of borrow and carries a lifetime. | 
| 148 | 149 | ///    - When this is `Immut<'a>`, the `NodeRef` acts roughly like `&'a Node`. | 
| 149 | 150 | ///    - When this is `ValMut<'a>`, the `NodeRef` acts roughly like `&'a Node` | 
| @@ -226,33 +227,27 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> { | 
| 226 | 227 | 
 | 
| 227 | 228 |     fn from_new_leaf<A: Allocator + Clone>(leaf: Box<LeafNode<K, V>, A>) -> Self { | 
| 228 | 229 |         // The allocator must be dropped, not leaked.  See also `BTreeMap::alloc`. | 
| 229 |  | -        let (leaf, _alloc) = Box::into_raw_with_allocator(leaf); | 
| 230 |  | -        // SAFETY: the node was just allocated. | 
| 231 |  | -        let node = unsafe { NonNull::new_unchecked(leaf) }; | 
|  | 230 | +        let (node, _alloc) = Box::into_non_null_with_allocator(leaf); | 
| 232 | 231 |         NodeRef { height: 0, node, _marker: PhantomData } | 
| 233 | 232 |     } | 
| 234 | 233 | } | 
| 235 | 234 | 
 | 
| 236 | 235 | impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> { | 
|  | 236 | +    /// Creates a new internal (height > 0) `NodeRef` | 
| 237 | 237 |     fn new_internal<A: Allocator + Clone>(child: Root<K, V>, alloc: A) -> Self { | 
| 238 | 238 |         let mut new_node = unsafe { InternalNode::new(alloc) }; | 
| 239 | 239 |         new_node.edges[0].write(child.node); | 
| 240 |  | -        unsafe { NodeRef::from_new_internal(new_node, child.height + 1) } | 
|  | 240 | +        NodeRef::from_new_internal(new_node, NonZero::new(child.height + 1).unwrap()) | 
| 241 | 241 |     } | 
| 242 | 242 | 
 | 
| 243 |  | -    /// # Safety | 
| 244 |  | -    /// `height` must not be zero. | 
| 245 |  | -    unsafe fn from_new_internal<A: Allocator + Clone>( | 
|  | 243 | +    /// Creates a new internal (height > 0) `NodeRef` from an existing internal node | 
|  | 244 | +    fn from_new_internal<A: Allocator + Clone>( | 
| 246 | 245 |         internal: Box<InternalNode<K, V>, A>, | 
| 247 |  | -        height: usize, | 
|  | 246 | +        height: NonZero<usize>, | 
| 248 | 247 |     ) -> Self { | 
| 249 |  | -        debug_assert!(height > 0); | 
| 250 | 248 |         // The allocator must be dropped, not leaked.  See also `BTreeMap::alloc`. | 
| 251 |  | -        let (internal, _alloc) = Box::into_raw_with_allocator(internal); | 
| 252 |  | -        // SAFETY: the node was just allocated. | 
| 253 |  | -        let internal = unsafe { NonNull::new_unchecked(internal) }; | 
| 254 |  | -        let node = internal.cast(); | 
| 255 |  | -        let mut this = NodeRef { height, node, _marker: PhantomData }; | 
|  | 249 | +        let (node, _alloc) = Box::into_non_null_with_allocator(internal); | 
|  | 250 | +        let mut this = NodeRef { height: height.into(), node: node.cast(), _marker: PhantomData }; | 
| 256 | 251 |         this.borrow_mut().correct_all_childrens_parent_links(); | 
| 257 | 252 |         this | 
| 258 | 253 |     } | 
| @@ -625,9 +620,8 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> { | 
| 625 | 620 |         let top = self.node; | 
| 626 | 621 | 
 | 
| 627 | 622 |         // SAFETY: we asserted to be internal. | 
| 628 |  | -        let internal_self = unsafe { self.borrow_mut().cast_to_internal_unchecked() }; | 
| 629 |  | -        // SAFETY: we borrowed `self` exclusively and its borrow type is exclusive. | 
| 630 |  | -        let internal_node = unsafe { &mut *NodeRef::as_internal_ptr(&internal_self) }; | 
|  | 623 | +        let mut internal_self = unsafe { self.borrow_mut().cast_to_internal_unchecked() }; | 
|  | 624 | +        let internal_node = internal_self.as_internal_mut(); | 
| 631 | 625 |         // SAFETY: the first edge is always initialized. | 
| 632 | 626 |         self.node = unsafe { internal_node.edges[0].assume_init_read() }; | 
| 633 | 627 |         self.height -= 1; | 
| @@ -1305,7 +1299,8 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, | 
| 1305 | 1299 |                 &mut new_node.edges[..new_len + 1], | 
| 1306 | 1300 |             ); | 
| 1307 | 1301 | 
 | 
| 1308 |  | -            let height = self.node.height; | 
|  | 1302 | +            // SAFETY: self is `marker::Internal`, so `self.node.height` is positive | 
|  | 1303 | +            let height = NonZero::new_unchecked(self.node.height); | 
| 1309 | 1304 |             let right = NodeRef::from_new_internal(new_node, height); | 
| 1310 | 1305 | 
 | 
| 1311 | 1306 |             SplitResult { left: self.node, kv, right } | 
|  | 
0 commit comments