Move high-level methods out of safety boundary
What changed, and why it matters
This commit is a code cleanup: it moves several helper methods (push, try_push, pop, extend_from_slice) out of a special 'safety_boundary' module into a normal implementation block. The actual behavior of the code does not change, and no security bug is fixed or introduced. The change is meant to make future safety reviews easier by keeping only truly low-level unsafe code inside the safety boundary.
No security action needed. Treat as routine refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors internals/src/array_vec.rs by relocating high-level ArrayVec methods from the safety_boundary module to a separate impl block outside it. The methods still call the same low-level unsafe primitives (set_len, spare_capacity_mut). No logic, bounds checks, unsafe blocks, or public API semantics are altered. The import of MaybeUninit and Error is adjusted accordingly. This is a structural/readability change, not a functional or security patch.
Changed components
internals/src/array_vec.rsInspect captured patch +61 / −59
diff --git a/internals/src/array_vec.rs b/internals/src/array_vec.rs
index 4465c7b0..322bdca7 100644
--- a/internals/src/array_vec.rs
+++ b/internals/src/array_vec.rs
@@ -3,7 +3,9 @@
//! A simplified `Copy` version of `arrayvec::ArrayVec`.
use core::fmt;
+use core::mem::MaybeUninit;
+use error::Error;
pub use safety_boundary::ArrayVec;
/// Limits the scope of `unsafe` auditing.
@@ -12,8 +14,6 @@ pub use safety_boundary::ArrayVec;
mod safety_boundary {
use core::mem::MaybeUninit;
- use crate::array_vec::error::Error;
-
/// A growable contiguous collection backed by array.
#[derive(Copy)]
pub struct ArrayVec<T: Copy, const CAP: usize> {
@@ -76,67 +76,69 @@ mod safety_boundary {
debug_assert!(new_len <= CAP);
self.len = new_len;
}
+ }
+}
- /// Adds an element into `self`.
- ///
- /// # Panics
- ///
- /// If the length would increase past CAP.
- #[track_caller]
- pub fn push(&mut self, element: T) {
- self.try_push(element).expect("push past the capacity of the array");
- }
+impl<T: Copy, const CAP: usize> ArrayVec<T, CAP> {
+ /// Adds an element into `self`.
+ ///
+ /// # Panics
+ ///
+ /// If the length would increase past CAP.
+ #[track_caller]
+ pub fn push(&mut self, element: T) {
+ self.try_push(element).expect("push past the capacity of the array");
+ }
- /// Adds an element into `self`.
- ///
- /// # Errors
- ///
- /// Returns `CapacityExceeded` if the `ArrayVec` is full.
- pub fn try_push(&mut self, element: T) -> Result<(), Error> {
- let first = self.spare_capacity_mut().first_mut().ok_or(Error::CapacityExceeded(CAP))?;
- *first = MaybeUninit::new(element);
- let old_len = self.len();
- // SOUNDNESS:
- // * first being non-None implies the element exists therefore one-past the length <=
- // CAP
- // * all elements up to old_len were already filled and we just added one
- unsafe { self.set_len(old_len + 1); }
- Ok(())
- }
+ /// Adds an element into `self`.
+ ///
+ /// # Errors
+ ///
+ /// Returns `CapacityExceeded` if the `ArrayVec` is full.
+ pub fn try_push(&mut self, element: T) -> Result<(), Error> {
+ let first = self.spare_capacity_mut().first_mut().ok_or(Error::CapacityExceeded(CAP))?;
+ *first = MaybeUninit::new(element);
+ let old_len = self.len();
+ // SOUNDNESS:
+ // * first being non-None implies the element exists therefore one-past the length <=
+ // CAP
+ // * all elements up to old_len were already filled and we just added one
+ unsafe { self.set_len(old_len + 1); }
+ Ok(())
+ }
- /// Removes the last element, returning it.
- ///
- /// # Returns
- ///
- /// None if the `ArrayVec` is empty.
- pub fn pop(&mut self) -> Option<T> {
- let res = *self.last()?;
- let old_len = self.len();
- // SOUNDNESS:
- // * decreasing the already-valid len keeps the len <= CAP invariant
- // * decreasing the already-valid len does not mark any new elements as initialized
- unsafe { self.set_len(old_len - 1) }
- Some(res)
- }
+ /// Removes the last element, returning it.
+ ///
+ /// # Returns
+ ///
+ /// None if the `ArrayVec` is empty.
+ pub fn pop(&mut self) -> Option<T> {
+ let res = *self.last()?;
+ let old_len = self.len();
+ // SOUNDNESS:
+ // * decreasing the already-valid len keeps the len <= CAP invariant
+ // * decreasing the already-valid len does not mark any new elements as initialized
+ unsafe { self.set_len(old_len - 1) }
+ Some(res)
+ }
- /// Copies and appends all elements from `slice` into `self`.
- ///
- /// # Panics
- ///
- /// If the length would increase past CAP.
- pub fn extend_from_slice(&mut self, slice: &[T]) {
- // SAFETY: MaybeUninit<T> has the same layout as T
- let slice = unsafe {
- let ptr = slice.as_ptr();
- core::slice::from_raw_parts(ptr.cast::<MaybeUninit<T>>(), slice.len())
- };
- self.spare_capacity_mut()
- .get_mut(..slice.len())
- .expect("buffer overflow")
- .copy_from_slice(slice);
- let old_len = self.len();
- unsafe { self.set_len(old_len + slice.len()) }
- }
+ /// Copies and appends all elements from `slice` into `self`.
+ ///
+ /// # Panics
+ ///
+ /// If the length would increase past CAP.
+ pub fn extend_from_slice(&mut self, slice: &[T]) {
+ // SAFETY: MaybeUninit<T> has the same layout as T
+ let slice = unsafe {
+ let ptr = slice.as_ptr();
+ core::slice::from_raw_parts(ptr.cast::<MaybeUninit<T>>(), slice.len())
+ };
+ self.spare_capacity_mut()
+ .get_mut(..slice.len())
+ .expect("buffer overflow")
+ .copy_from_slice(slice);
+ let old_len = self.len();
+ unsafe { self.set_len(old_len + slice.len()) }
}
}
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.