@@ -25,12 +25,21 @@ pub struct Node<V> {
2525 pub ( crate ) _marker : PhantomData < V > ,
2626}
2727
28+ // Safety:
29+ // - A `Node<V>` is safe to send across threads if `V` is `Send`
30+ // - The raw pointer is managed by this struct and not exposed
2831unsafe impl < V : Send > Send for Node < V > { }
32+ // Safety:
33+ // - A `Node<V>` is safe to share across threads if `V` is `Sync`
34+ // - The raw pointer is managed by this struct and not exposed
2935unsafe impl < V : Sync > Sync for Node < V > { }
3036
3137impl < V : Clone > Clone for Node < V > {
3238 fn clone ( & self ) -> Self {
3339 let mut new_ptr = self . ptr_data ( ) . allocate ( ) ;
40+ // Safety:
41+ // - `new_ptr` is a freshly allocated and correctly aligned pointer from `allocate`
42+ // - `new_ptr.assume_init()` is safe because all parts of the node have been initialized
3443 unsafe {
3544 new_ptr. write_header ( * self . header ( ) ) ;
3645 new_ptr. write_label ( self . label ( ) ) ;
@@ -67,6 +76,9 @@ impl<V> Node<V> {
6776 children_len : children. len ( ) as u8 ,
6877 } ;
6978 let mut ptr = header. ptr_data ( ) . allocate ( ) ;
79+ // Safety:
80+ // - `ptr` is a freshly allocated and correctly aligned pointer from `allocate`
81+ // - All parts of the node are initialized before `assume_init` is called
7082 unsafe {
7183 ptr. write_header ( header) ;
7284 ptr. write_label ( label) ;
@@ -78,17 +90,29 @@ impl<V> Node<V> {
7890
7991 /// Returns the reference to the value of this node.
8092 pub fn value ( & self ) -> Option < & V > {
93+ // Safety:
94+ // - `self.ptr` points to an allocation with the same valid layout it was allocated with
95+ // - `value_ptr` correctly calculates the offset to the `Option<V>`
8196 unsafe { ( self . ptr_data ( ) . value_ptr ( self . ptr ) ) . as_ref ( ) } . as_ref ( )
8297 }
8398
8499 /// Returns the mutable reference to the value of this node.
85100 pub fn value_mut ( & mut self ) -> Option < & mut V > {
101+ // Safety:
102+ // - `self.ptr` points to an allocation with the same valid layout it was allocated with
103+ // - `value_ptr` correctly calculates the offset to the `Option<V>`
86104 unsafe { ( self . ptr_data ( ) . value_ptr ( self . ptr ) ) . as_mut ( ) } . as_mut ( )
87105 }
88106
89107 /// Returns mutable references to the node itself with its sibling and child
90108 pub fn as_mut ( & mut self ) -> NodeMut < ' _ , V > {
109+ // Safety:
110+ // - `self.ptr` points to an allocation with the same valid layout it was allocated with
111+ // - `value_ptr` correctly calculates the offset to the `Option<V>`
91112 let value = unsafe { self . ptr_data ( ) . value_ptr ( self . ptr ) . as_mut ( ) } . as_mut ( ) ;
113+ // Safety:
114+ // - `self.ptr` points to an allocation with the same valid layout it was allocated with
115+ // - `children_mut_opt` correctly calculates the offset to the children array if it exists
92116 let children = unsafe { self . ptr_data ( ) . children_mut_opt ( self . ptr ) } ;
93117
94118 NodeMut {
@@ -100,6 +124,9 @@ impl<V> Node<V> {
100124
101125 /// Takes the value out of this node.
102126 pub fn take_value ( & mut self ) -> Option < V > {
127+ // Safety:
128+ // - `self.ptr` points to an allocation with the same valid layout it was allocated with
129+ // - `value_ptr` correctly calculates the offset to the `Option<V>`
103130 unsafe {
104131 let ptr = self . ptr_data ( ) . value_ptr ( self . ptr ) ;
105132 ptr. replace ( None )
@@ -108,6 +135,9 @@ impl<V> Node<V> {
108135
109136 /// adds child at i and shifts elements right
110137 /// child index must be at i <= len, len can be 0
138+ // Safety:
139+ // - `i` must be a valid index to insert at, i.e. `i <= self.children_len()`
140+ // - `self.children_len()` must be less than `u8::MAX`
111141 pub ( crate ) unsafe fn add_child ( & mut self , new_child : Node < V > , i : usize ) {
112142 debug_assert ! (
113143 i <= self . children_len( ) ,
@@ -128,6 +158,13 @@ impl<V> Node<V> {
128158 let old_ptr_data = self . ptr_data ( ) ;
129159 let value = self . take_value ( ) ;
130160
161+ // Safety:
162+ // - `realloc` is safe because `self.ptr` points to a valid allocation with `old_ptr_data.layout`.
163+ // The new size is calculated correctly in `new_ptr_data.layout`
164+ // - `copy_to` is safe because `i` is a valid index, `num` is within bounds
165+ // and the source and destination pointers are within the newly allocated block
166+ // - `new_ptr.assume_init()` is safe because all parts of the node have been initialized
167+ // - the pointer is assigned using `forget()` because we reallocated
131168 unsafe {
132169 let raw_ptr = alloc:: alloc:: realloc (
133170 self . ptr . as_ptr ( ) . cast ( ) ,
@@ -200,6 +237,14 @@ impl<V> Node<V> {
200237 "When prefixing label, the size of allocation must increase"
201238 ) ;
202239
240+ // Safety:
241+ // - `realloc` is safe because `self.ptr` points to a valid allocation with `old_ptr_data.layout`.
242+ // The new size is calculated correctly in `new_ptr_data.layout`
243+ // - `new_ptr.write_value(value)` is safe because the space is allocated
244+ // - `copy_from` and `copy_from_nonoverlapping` are safe because the source and destination pointers
245+ // are valid and within the allocated blocks, and the lengths within bounds
246+ // - `new_ptr.assume_init()` is safe because all parts of the node have been initialized
247+ // - the pointer is assigned using `forget()` because we reallocated
203248 unsafe {
204249 let raw_ptr = alloc:: alloc:: realloc (
205250 self . ptr . as_ptr ( ) . cast ( ) ,
@@ -253,6 +298,8 @@ impl<V> Node<V> {
253298
254299 /// removes child at i and shifts elements left
255300 /// node must have children already
301+ // Safety:
302+ // - `i` must be a valid index of a child, i.e. `i < self.children_len()`
256303 pub ( crate ) unsafe fn remove_child ( & mut self , i : usize ) -> Node < V > {
257304 debug_assert ! (
258305 i < self . children_len( ) ,
@@ -281,6 +328,13 @@ impl<V> Node<V> {
281328 ptr_data : new_ptr_data,
282329 } ;
283330
331+ // Safety:
332+ // - `old_ptr.children_ptr().add(i).read()` is safe because `i` is a valid index
333+ // - `copy_from` is safe because the source and destination pointers are valid and the length is correct
334+ // - `realloc` is safe because `self.ptr` points to a valid allocation with `old_layout`
335+ // - `new_ptr.write_value(value)` is safe because the space is allocated
336+ // - `new_ptr.assume_init()` is safe because all parts of the node have been initialized
337+ // - the pointer is assigned using `forget()` because we reallocated
284338 unsafe {
285339 // get child at i
286340 let removed_child = some ! ( old_ptr. children_ptr( ) ) . add ( i) . read ( ) ;
@@ -314,6 +368,9 @@ impl<V> Node<V> {
314368 /// Sets the value of this node.
315369 pub fn set_value ( & mut self , value : V ) {
316370 // self.take_value();
371+ // Safety:
372+ // - `self.ptr` points to an allocation with the same valid layout it was allocated with
373+ // - `value_ptr` correctly calculates the offset to the `Option<V>`
317374 unsafe {
318375 let ptr = self . ptr_data ( ) . value_ptr ( self . ptr ) ;
319376 let _ = ptr. replace ( Some ( value) ) ;
@@ -324,13 +381,19 @@ impl<V> Node<V> {
324381 /// and setting current node to have the suffix child plus optional `new_child`
325382 /// returns index of new_child (if Some(new_child) was passed)
326383 /// otherwise 0
384+ /// # Safety:
385+ /// - `position` must be a valid index within the label, i.e., `position < self.label_len()`
327386 pub ( crate ) unsafe fn split_at ( & mut self , position : usize , new_child : Option < Node < V > > ) -> usize {
328387 debug_assert ! (
329388 position < self . label_len( ) ,
330389 "label offset must be within label bounds"
331390 ) ;
332391 let value = self . take_value ( ) ;
333392
393+ // Safety:
394+ // - `self.label().get_unchecked(position..)` is safe because `position` is checked to be within bounds
395+ // - A new node `child` is allocated and correctly initialized with the suffix of the label and the old children
396+ // - `copy_from_nonoverlapping` is safe because the source and destination are valid and do not overlap
334397 let child = unsafe {
335398 let suffix = self . label ( ) . get_unchecked ( position..) ;
336399 let old_children_len = self . children_len ( ) ;
@@ -363,6 +426,8 @@ impl<V> Node<V> {
363426 let new_layout = new_data. layout ;
364427 let old_layout = self . ptr_data ( ) . layout ;
365428
429+ // Safety:
430+ // - `realloc` is safe because `self.ptr` points to a valid allocation with `old_layout`
366431 let mut new_ptr = unsafe {
367432 let new_ptr =
368433 alloc:: alloc:: realloc ( self . ptr . as_ptr ( ) . cast ( ) , old_layout, new_layout. size ( ) )
@@ -375,6 +440,11 @@ impl<V> Node<V> {
375440 ptr_data : new_data,
376441 }
377442 } ;
443+ // Safety:
444+ // - `new_ptr` is a valid pointer to a newly allocated block of memory
445+ // - `new_ptr.write_children` is safe because the children array is valid and the space is allocated
446+ // - `new_ptr.assume_init()` is safe because all parts of the node have been initialized
447+ // - pointer is assigned to `self.ptr` using `forget()` because we `realloc`ated
378448 unsafe {
379449 new_ptr. write_header ( new_hdr) ;
380450 // index of new_child
0 commit comments