]> git.nega.tv - josh/narcissus/commitdiff
narcissus-core: Remove unsafe refs from virtual_vec
authorJoshua Simmons <josh@nega.tv>
Sat, 4 Oct 2025 20:55:39 +0000 (22:55 +0200)
committerJoshua Simmons <josh@nega.tv>
Sat, 4 Oct 2025 21:04:06 +0000 (23:04 +0200)
engine/narcissus-core/src/virtual_vec/vec.rs

index 23535da36db5e228b0240b1c2e83d2d199496b0f..345ae48ecad9d913eb2aa02444e8e5c5042e9f6c 100644 (file)
@@ -58,21 +58,26 @@ impl<T> VirtualVec<T> {
         }
     }
 
-    pub fn append(&mut self, other: &mut Self) {
-        unsafe {
-            self.append_elements(other.as_slice() as _);
-            other.set_len(0);
-        }
-    }
+    pub fn append(&mut self, src: &mut Self) {
+        let src_len = src.len();
+        let dst_len = self.len();
+
+        // Addition here cannot overflow as both len's are less-than `isize::MAX`
+        let new_len = dst_len + src_len;
+
+        // Will panic if additional size is beyond the max capacity.
+        self.reserve(src_len);
 
-    #[inline]
-    unsafe fn append_elements(&mut self, other: *const [T]) {
         unsafe {
-            let count = (*other).len();
-            self.reserve(count);
-            let len = self.len();
-            ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count);
-            self.len += count;
+            // SAFETY: Cannot be out of bounds as VirtualVec len cannot exceed
+            // `isize::MAX`.
+            let dst_ptr = self.as_mut_ptr().add(dst_len);
+            let src_ptr = src.as_ptr();
+
+            src.set_len(0);
+            ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
+
+            self.set_len(new_len);
         }
     }