What changed, and why it matters
This commit adds a new, safer way to insert items into a fixed-size array-like container called ArrayVec. The existing method panics when full; the new method returns a normal error instead. It does not change any existing behavior and does not fix a known security bug.
No immediate action required. Treat as routine defensive enhancement. If auditing, verify that future code uses try_push in security-relevant paths rather than the panicking push.
Security signals we found
Adds fallible API to avoid panic-on-full behavior
No unsafe code changes
No existing callers modified
No memory-safety boundary changes
Evidence from the diff
The patch introduces ArrayVec::try_push, a fallible alternative to the existing infallible/panicking push. It also adds a public error::Error enum with a CapacityExceeded variant and Display/std::error::Error implementations. No callers are changed, no unsafe code is added, and no existing API is modified. It is a defensive API improvement that may help future callers avoid panic paths.
Changed components
internals/src/array_vec.rsArrayVec::try_pusharray_vec::error::ErrorInspect captured patch +45 / −0
diff --git a/internals/src/array_vec.rs b/internals/src/array_vec.rs
index a49477de..ab5a977a 100644
--- a/internals/src/array_vec.rs
+++ b/internals/src/array_vec.rs
@@ -12,6 +12,8 @@ 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> {
@@ -70,6 +72,20 @@ mod safety_boundary {
self.len += 1;
}
+ /// Adds an element into `self`.
+ ///
+ /// # Errors
+ ///
+ /// Returns `CAPSizeExceeded` if the `ArrayVec` is full.
+ pub fn try_push(&mut self, element: T) -> Result<(), Error> {
+ if self.len >= CAP {
+ return Err(Error::CapacityExceeded(CAP));
+ }
+ self.data[self.len] = MaybeUninit::new(element);
+ self.len += 1;
+ Ok(())
+ }
+
/// Removes the last element, returning it.
///
/// # Returns
@@ -178,6 +194,35 @@ impl<T: Copy + core::hash::Hash, const CAP: usize> core::hash::Hash for ArrayVec
fn hash<H: core::hash::Hasher>(&self, state: &mut H) { core::hash::Hash::hash(&**self, state); }
}
+/// Error types for `ArrayVec`.
+pub mod error {
+ use core::fmt;
+
+ /// Errors encountered when inserting or removing elements from an `ArrayVec`.
+ #[derive(Copy, Clone, Debug, PartialEq, Eq)]
+ pub enum Error {
+ /// Attempting to push additional element beyond the `ArrayVec`'s capacity.
+ CapacityExceeded(usize),
+ }
+
+ impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::CapacityExceeded(cap) => write!(f, "Capacity exceeded: {}", cap),
+ }
+ }
+ }
+
+ #[cfg(feature = "std")]
+ impl std::error::Error for Error {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ Self::CapacityExceeded(_) => None,
+ }
+ }
+ }
+}
+
#[cfg(feature = "serde")]
impl<T: Copy + crate::serde::Serialize, const CAP: usize> crate::serde::Serialize
for ArrayVec<T, CAP>
Why this scored 18/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.