You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This finding was identified during an agentic unsafe Rust code review performed by Gemini AI, followed by human review and verification.
The Issue
In generic-array v1, ArrayLength::ArrayType<T> is a public associated type defined on the public unsafe trait ArrayLength. For any given length N, N::ArrayType<T> resolves statically to internal container structs (GenericArrayImplEven<T, U> or GenericArrayImplOdd<T, U>). These internal struct types implement standard library Clone whenever T: Clone and U: Clone like so:
The accompanying code comment asserts that Clone is never called on these internal types because GenericArray<T, N>::clone delegates to self.map(Clone::clone). However, because ArrayType<T> is a public associated type on a public trait, downstream crates can explicitly name and construct the type <N as ArrayLength>::ArrayType<T>.
Minimal Reproduction
use generic_array::ArrayLength;fnmain(){let arr = unsafe{ std::mem::zeroed::<<typenum::U2asArrayLength>::ArrayType<u8>>()};let _cloned = arr.clone();}
thread 'main' panicked at 'internal error: entered unreachable code'
Note
The full audit report below also contains additional minor findings (such as missing safety comments or undocumented FFI assumptions) that are probably worth fixing as well but not the primary goal of this issue. The audit report has not been human-reviewed, it may contain misleading claims.
Full Gemini Codebase Audit Report Appendix
Unsafe Rust Review: generic_array (v1)
Overall Safety Assessment
generic_array provides a statically allocated generic array structure GenericArray<T, N: ArrayLength>, allowing arrays to be parameterized by type-level unsigned integers (typenum::Unsigned). To bypass legacy compiler restrictions on generic array lengths, the crate constructs a recursive, binary-tree-like type hierarchy at compile time using internal container structs (GenericArrayImplEven and GenericArrayImplOdd). At runtime, these recursive structures are reinterpreted as contiguous memory buffers of size N * size_of::<T>() and alignment align_of::<T>(), functioning interchangeably with native Rust arrays [T; N].
Unsafe Surface & Density
The crate exhibits a substantial density of unsafe code across 11 source files, comprising over 90 distinct unsafe fn, unsafe trait, unsafe impl, or unsafe {} blocks. The core unsafe surface is concentrated in:
src/compat/ (8 items): Layout-preserving transmutes for interoperability with generic-array 0.14 and hybrid-array 0.4.
Soundness & Architectural Evaluation
Despite its central position in the Rust data-structure and cryptographic ecosystem, our rigorous audit grounded in authoritative Rust Reference semantics reveals that generic_array v1 (specifically v1.3.5) is Unsound and contains three severe Critical Findings:
Furthermore, the crate completely lacks formal // SAFETY: proof comments and # Safety docstrings across almost its entire codebase (88 distinct missing proof locations).
Critical Findings
1. Unsound Safe Trait Implementation (Clone) on Nameable Type Executing unreachable_unchecked() (src/lib.rs:370, src/lib.rs:377) 🔴 🤸
Description: ArrayLength::ArrayType<T> is a public associated type defined on the public unsafe trait ArrayLength. For any given length N, N::ArrayType<T> resolves statically to GenericArrayImplEven<T, U> or GenericArrayImplOdd<T, U>. In src/lib.rs:364 and 374, these internal struct types implement standard library Clone whenever T: Clone and U: Clone. However, their clone(&self) method bodies consist entirely of unsafe { core::hint::unreachable_unchecked() }. The authors included a comment stating that Clone is never called on these internal types because GenericArray<T, N>::clone(&self) delegates to self.map(Clone::clone). However, because ArrayType<T> is a public associated type on a public trait, downstream crates can explicitly name the type <N as ArrayLength>::ArrayType<T>. Furthermore, when the crate's const-default feature flag is enabled (as listed in package.metadata.docs.rs.features), GenericArrayImplEven and GenericArrayImplOdd implement ConstDefault. Consequently, 100% safe downstream code can construct an instance via let arr = <typenum::U2 as ArrayLength>::ArrayType<MyType>::DEFAULT and invoke arr.clone(). This compiles purely in safe Rust without warnings or unsafe blocks and immediately triggers unreachable_unchecked() at runtime. Even without const-default, exposing a public type implementing a safe trait (Clone) where invoking the trait method executes unreachable_unchecked() violates fundamental Rust soundness guarantees.
2. Invalid Slice Reference Fabrication on Partially Moved Arrays (src/iter.rs:21, 28, 59, 153, 213, src/internal.rs:283, 320) 🔴 🤦
Description: GenericArrayIter<T, N>, ArrayConsumer<T, N>, and IntrusiveArrayConsumer<T, N> encapsulate underlying array storage (e.g., ManuallyDrop<GenericArray<T, N>>). During iterator traversal (next(), nth(), map()), leading elements at indices [0..self.index] or trailing elements at [self.index_back..N] are consumed by value via ptr::read. Consequently, memory at those consumed indices becomes uninitialized or moved-out storage. However, whenever self.array.get_unchecked(...) or get_unchecked_mut(...) is invoked (in as_slice, as_mut_slice, next, nth, drop), resolving get_unchecked on GenericArray<T, N> forces auto-dereferencing via <GenericArray<T, N> as Deref>::deref or DerefMut::deref_mut. GenericArray::deref and deref_mut execute slice::from_raw_parts / from_raw_parts_mut spanning the entire N::USIZE element range (0..N). According to the Rust Reference (Behavior considered undefined: "Producing an invalid value... when a reference to value is created"), fabricating a safe reference &[T] or &mut [T] covering a contiguous buffer where some T elements are uninitialized or moved out immediately produces references to invalid values. Under Stacked Borrows and Tree Borrows formal aliasing models, this triggers Undefined Behavior.
3. Unchecked Allocator Return Value Leading to Null Pointer Dereference (src/impl_alloc.rs:177) 🔴 🤦
Description: In GenericSequence::generate for Box<GenericArray<T, N>>, raw heap memory is allocated directly via alloc::alloc::alloc(Layout::new::<GenericArray<MaybeUninit<T>, N>>()). Unlike standard library collections (Vec, Box) which check for null pointers and invoke handle_alloc_error upon allocation failure, this crate omits return value validation entirely. On out-of-memory (OOM) or allocation failure, alloc::alloc::alloc returns a null pointer (null_mut()). The immediately subsequent line let mut builder = IntrusiveArrayBuilder::new(&mut *ptr) dereferences the null raw pointer (&mut *null) to construct a mutable reference &mut GenericArray<MaybeUninit<T>, N>. In Rust authoritative semantics and LLVM optimization rules, dereferencing a null pointer or fabricating a null reference is unconditional Undefined Behavior.
Fishy Findings
1. Memory Leak of Raw Heap Allocations on Generator Panics (src/impl_alloc.rs:185) 🟡 🤦
Severity: 🟡 Low
Threat Vector: 🤦 Accidental Misuse
Bug Type: Memory Leak
Observation: In Box<GenericArray<T, N>>::generate, raw heap storage is allocated via alloc::alloc::alloc and passed to IntrusiveArrayBuilder::new(&mut *ptr). A user-supplied closure f(i) is invoked sequentially to initialize array elements.
Analysis: If f(i) panics during initialization, IntrusiveArrayBuilder::drop correctly drops all initialized elements up to position. However, IntrusiveArrayBuilder does not own or free the underlying raw allocation pointer ptr. The raw pointer is only converted into an RAII-managed Box at the very end of the function (Box::from_raw). Therefore, any panic inside f permanently leaks the raw heap allocation buffer. While leaking memory during unwinding does not constitute Undefined Behavior in Rust, failing to wrap raw allocator returns in an RAII cleanup guard on error paths represents fragile low-level design.
2. Implicit Unsafe Operations via Missing #![deny(unsafe_op_in_unsafe_fn)] Enforcement 🟡 🤦
Severity: 🟡 Low
Threat Vector: 🤦 Accidental Misuse
Bug Type: Missing Lint Enforcement
Observation: The crate specifies Rust edition 2021 but omits #![deny(unsafe_op_in_unsafe_fn)].
Analysis: Across src/lib.rs, src/sequence.rs, and src/internal.rs, dozens of internal unsafe fn APIs perform raw pointer dereferences, union field accesses, and type-punning transmutes directly within their function bodies without delineating unsafe {} blocks. Omitting lexical unsafe {} containment within unsafe fn blurs proof boundaries and increases maintainer hazard during security auditing.
Missing Safety Comments
Across the crate, 88 distinct unsafe locations lack required // SAFETY: proof comments or # Safety docstrings. We enumerate every location below along with formal proof obligations.
Module src/lib.rs (24 locations) 🔴
src/lib.rs:274 (unsafe impl ArrayLength for UTerm): Missing // SAFETY: comment.
Proposed Proof: UTerm represents 0 elements; [T; 0] is a valid contiguous layout of 0 elements matching size_of::<[T; 0]>() == 0.
Proposed Proof: By structural induction, GenericArrayImplEven<T, U> contains [U; 2] and PhantomData, possessing exact size 2 * size_of::<U>() and alignment align_of::<T>() with zero internal padding.
Proposed Proof: MaybeUninit::uninit() is valid for uninitialized storage; IntrusiveArrayBuilder tracks element initialization and assumes init only after position == N.
Proposed Proof: IntrusiveArrayConsumer tracks consumed elements and ensures remaining unread items drop if f panics; ptr::read moves elements out exactly once.
Proposed Proof: Division computes exact chunk count; slice pointers are aligned for GenericArray<T, N> due to matching element alignment align_of::<T>().
Proposed Proof: out_ptr spans uninitialized memory for N + 1 elements; writing self (N items) at offset 0 and last at offset N fully initializes Longer.
Note
This finding was identified during an agentic unsafe Rust code review performed by Gemini AI, followed by human review and verification.
The Issue
In
generic-arrayv1,ArrayLength::ArrayType<T>is a public associated type defined on the publicunsafe trait ArrayLength. For any given lengthN,N::ArrayType<T>resolves statically to internal container structs (GenericArrayImplEven<T, U>orGenericArrayImplOdd<T, U>). These internal struct types implement standard libraryClonewheneverT: CloneandU: Clonelike so:generic-array/src/lib.rs
Lines 364 to 379 in 778e6dd
The accompanying code comment asserts that
Cloneis never called on these internal types becauseGenericArray<T, N>::clonedelegates toself.map(Clone::clone). However, becauseArrayType<T>is a public associated type on a public trait, downstream crates can explicitly name and construct the type<N as ArrayLength>::ArrayType<T>.Minimal Reproduction
Note
The full audit report below also contains additional minor findings (such as missing safety comments or undocumented FFI assumptions) that are probably worth fixing as well but not the primary goal of this issue. The audit report has not been human-reviewed, it may contain misleading claims.
Full Gemini Codebase Audit Report Appendix
Unsafe Rust Review:
generic_array(v1)Overall Safety Assessment
generic_arrayprovides a statically allocated generic array structureGenericArray<T, N: ArrayLength>, allowing arrays to be parameterized by type-level unsigned integers (typenum::Unsigned). To bypass legacy compiler restrictions on generic array lengths, the crate constructs a recursive, binary-tree-like type hierarchy at compile time using internal container structs (GenericArrayImplEvenandGenericArrayImplOdd). At runtime, these recursive structures are reinterpreted as contiguous memory buffers of sizeN * size_of::<T>()and alignmentalign_of::<T>(), functioning interchangeably with native Rust arrays[T; N].Unsafe Surface & Density
The crate exhibits a substantial density of
unsafecode across 11 source files, comprising over 90 distinctunsafe fn,unsafe trait,unsafe impl, orunsafe {}blocks. The coreunsafesurface is concentrated in:src/lib.rs(24 items): Core trait implementations (ArrayLength,Send,Sync,GenericSequence), raw slice extractions (as_slice,as_mut_slice), pointer transmutes (from_slice,from_array), and uninitialized memory assumptions (uninit,assume_init).src/sequence.rs(22 items): Sequence manipulation traits (GenericSequence,Lengthen,Shorten,Split,Flatten,Unflatten) performing pointer arithmetic and type-punning transmutes across nested array layouts.src/internal.rs(13 items): Incremental array construction and consumption wrappers (ArrayBuilder,IntrusiveArrayBuilder,ArrayConsumer,IntrusiveArrayConsumer) managing partial initialization and drop-on-panic invariants.src/iter.rs(9 items): By-value iterator traversal (GenericArrayIter) utilizing raw pointer reads/writes andmem::forget.src/hex.rs(5 items): SIMD hex encoding hooks and unchecked UTF-8 string conversions.src/impl_alloc.rs&src/impl_serde.rs(5 items): Heap allocation lifecycles (Box,Vec) and visitor sequence building.src/compat/(8 items): Layout-preserving transmutes for interoperability withgeneric-array 0.14andhybrid-array 0.4.Soundness & Architectural Evaluation
Despite its central position in the Rust data-structure and cryptographic ecosystem, our rigorous audit grounded in authoritative Rust Reference semantics reveals that
generic_arrayv1 (specifically v1.3.5) is Unsound and contains three severe Critical Findings:Clonetrait implementations on publicly nameable associated types executingunreachable_unchecked().&[T]/&mut [T]) over partially moved/uninitialized array elements during iterator drop and traversal.alloc::alloc::allocreturn values triggering null pointer dereferences (&mut *null) upon allocation failure.Furthermore, the crate completely lacks formal
// SAFETY:proof comments and# Safetydocstrings across almost its entire codebase (88 distinct missing proof locations).Critical Findings
1. Unsound Safe Trait Implementation (
Clone) on Nameable Type Executingunreachable_unchecked()(src/lib.rs:370,src/lib.rs:377) 🔴 🤸ArrayLength::ArrayType<T>is a public associated type defined on the publicunsafe trait ArrayLength. For any given lengthN,N::ArrayType<T>resolves statically toGenericArrayImplEven<T, U>orGenericArrayImplOdd<T, U>. Insrc/lib.rs:364and374, these internal struct types implement standard libraryClonewheneverT: CloneandU: Clone. However, theirclone(&self)method bodies consist entirely ofunsafe { core::hint::unreachable_unchecked() }. The authors included a comment stating thatCloneis never called on these internal types becauseGenericArray<T, N>::clone(&self)delegates toself.map(Clone::clone). However, becauseArrayType<T>is a public associated type on a public trait, downstream crates can explicitly name the type<N as ArrayLength>::ArrayType<T>. Furthermore, when the crate'sconst-defaultfeature flag is enabled (as listed inpackage.metadata.docs.rs.features),GenericArrayImplEvenandGenericArrayImplOddimplementConstDefault. Consequently, 100% safe downstream code can construct an instance vialet arr = <typenum::U2 as ArrayLength>::ArrayType<MyType>::DEFAULTand invokearr.clone(). This compiles purely in safe Rust without warnings orunsafeblocks and immediately triggersunreachable_unchecked()at runtime. Even withoutconst-default, exposing a public type implementing a safe trait (Clone) where invoking the trait method executesunreachable_unchecked()violates fundamental Rust soundness guarantees.2. Invalid Slice Reference Fabrication on Partially Moved Arrays (
src/iter.rs:21,28,59,153,213,src/internal.rs:283,320) 🔴 🤦GenericArrayIter<T, N>,ArrayConsumer<T, N>, andIntrusiveArrayConsumer<T, N>encapsulate underlying array storage (e.g.,ManuallyDrop<GenericArray<T, N>>). During iterator traversal (next(),nth(),map()), leading elements at indices[0..self.index]or trailing elements at[self.index_back..N]are consumed by value viaptr::read. Consequently, memory at those consumed indices becomes uninitialized or moved-out storage. However, wheneverself.array.get_unchecked(...)orget_unchecked_mut(...)is invoked (inas_slice,as_mut_slice,next,nth,drop), resolvingget_uncheckedonGenericArray<T, N>forces auto-dereferencing via<GenericArray<T, N> as Deref>::dereforDerefMut::deref_mut.GenericArray::derefandderef_mutexecuteslice::from_raw_parts/from_raw_parts_mutspanning the entireN::USIZEelement range (0..N). According to the Rust Reference (Behavior considered undefined: "Producing an invalid value... when a reference to value is created"), fabricating a safe reference&[T]or&mut [T]covering a contiguous buffer where someTelements are uninitialized or moved out immediately produces references to invalid values. Under Stacked Borrows and Tree Borrows formal aliasing models, this triggers Undefined Behavior.3. Unchecked Allocator Return Value Leading to Null Pointer Dereference (
src/impl_alloc.rs:177) 🔴 🤦GenericSequence::generateforBox<GenericArray<T, N>>, raw heap memory is allocated directly viaalloc::alloc::alloc(Layout::new::<GenericArray<MaybeUninit<T>, N>>()). Unlike standard library collections (Vec,Box) which check for null pointers and invokehandle_alloc_errorupon allocation failure, this crate omits return value validation entirely. On out-of-memory (OOM) or allocation failure,alloc::alloc::allocreturns a null pointer (null_mut()). The immediately subsequent linelet mut builder = IntrusiveArrayBuilder::new(&mut *ptr)dereferences the null raw pointer (&mut *null) to construct a mutable reference&mut GenericArray<MaybeUninit<T>, N>. In Rust authoritative semantics and LLVM optimization rules, dereferencing a null pointer or fabricating a null reference is unconditional Undefined Behavior.Fishy Findings
1. Memory Leak of Raw Heap Allocations on Generator Panics (
src/impl_alloc.rs:185) 🟡 🤦Box<GenericArray<T, N>>::generate, raw heap storage is allocated viaalloc::alloc::allocand passed toIntrusiveArrayBuilder::new(&mut *ptr). A user-supplied closuref(i)is invoked sequentially to initialize array elements.f(i)panics during initialization,IntrusiveArrayBuilder::dropcorrectly drops all initialized elements up toposition. However,IntrusiveArrayBuilderdoes not own or free the underlying raw allocation pointerptr. The raw pointer is only converted into an RAII-managedBoxat the very end of the function (Box::from_raw). Therefore, any panic insidefpermanently leaks the raw heap allocation buffer. While leaking memory during unwinding does not constitute Undefined Behavior in Rust, failing to wrap raw allocator returns in an RAII cleanup guard on error paths represents fragile low-level design.2. Implicit Unsafe Operations via Missing
#![deny(unsafe_op_in_unsafe_fn)]Enforcement 🟡 🤦#![deny(unsafe_op_in_unsafe_fn)].src/lib.rs,src/sequence.rs, andsrc/internal.rs, dozens of internalunsafe fnAPIs perform raw pointer dereferences, union field accesses, and type-punning transmutes directly within their function bodies without delineatingunsafe {}blocks. Omitting lexicalunsafe {}containment withinunsafe fnblurs proof boundaries and increases maintainer hazard during security auditing.Missing Safety Comments
Across the crate, 88 distinct
unsafelocations lack required// SAFETY:proof comments or# Safetydocstrings. We enumerate every location below along with formal proof obligations.Module
src/lib.rs(24 locations) 🔴src/lib.rs:274(unsafe impl ArrayLength for UTerm): Missing// SAFETY:comment.UTermrepresents 0 elements;[T; 0]is a valid contiguous layout of 0 elements matchingsize_of::<[T; 0]>() == 0.src/lib.rs:402(unsafe impl ArrayLength for UInt<N, B0>): Missing// SAFETY:comment.GenericArrayImplEven<T, U>contains[U; 2]andPhantomData, possessing exact size2 * size_of::<U>()and alignmentalign_of::<T>()with zero internal padding.src/lib.rs:410(unsafe impl ArrayLength for UInt<N, B1>): Missing// SAFETY:comment.GenericArrayImplOdd<T, U>contains[U; 2]andT, possessing exact size(2 * size_of::<U>() + size_of::<T>())and alignmentalign_of::<T>()with zero internal padding.src/lib.rs:537(unsafe impl Send for GenericArray<T, N>): Missing// SAFETY:comment.GenericArray<T, N>is transparent overNcontiguous elements ofT; ownership transfer across threads is sound iffT: Send.src/lib.rs:538(unsafe impl Sync for GenericArray<T, N>): Missing// SAFETY:comment.T: Sync.src/lib.rs:598(unsafe impl GenericSequence for GenericArray<T, N>): Missing// SAFETY:comment.GenericArraylength matchesN, andIntrusiveArrayBuilderensures panic safety during generation.src/lib.rs:610(unsafe { ... }inGenericSequence::generate): Missing// SAFETY:comment.MaybeUninit::uninit()is valid for uninitialized storage;IntrusiveArrayBuildertracks element initialization and assumes init only afterposition == N.src/lib.rs:639(unsafe { ... }ininverted_zip): Missing// SAFETY:comment.IntrusiveArrayConsumertracks consumed elements and ensures remaining unread items drop iffpanics;ptr::readmoves elements out exactly once.src/lib.rs:683(unsafe { ... }ininverted_zip2): Missing// SAFETY:comment.inverted_zip.src/lib.rs:726(unsafe { ... }inFunctionalSequence::map): Missing// SAFETY:comment.IntrusiveArrayConsumerwrapsselfto drop unconsumed elements on panic; each element is read exactly once viaptr::read.src/lib.rs:786(unsafe { slice::from_raw_parts(...) }inas_slice): Missing// SAFETY:comment.selfis a valid aligned reference spanningN * size_of::<T>()initialized bytes.src/lib.rs:795(unsafe { slice::from_raw_parts_mut(...) }inas_mut_slice): Missing// SAFETY:comment.selfis a valid exclusive mutable reference spanningNinitialized elements.src/lib.rs:812(unsafe { &*(...) }infrom_slice): Missing// SAFETY:comment.slice.len() == N::USIZEensures length equality;GenericArray<T, N>has identical memory layout to[T; N].src/lib.rs:825(unsafe { &*(...) }intry_from_slice): Missing// SAFETY:comment.from_slice.src/lib.rs:845(unsafe { &mut *(...) }infrom_mut_slice): Missing// SAFETY:comment.src/lib.rs:881(unsafe { ... }inchunks_from_slice): Missing// SAFETY:comment.GenericArray<T, N>due to matching element alignmentalign_of::<T>().src/lib.rs:910(unsafe { ... }inchunks_from_slice_mut): Missing// SAFETY:comment.src/lib.rs:933(unsafe { slice::from_raw_parts_mut(...) }inslice_from_chunks_mut): Missing// SAFETY:comment.slice.len() * N::USIZE; contiguous chunk slice memory is valid for underlying[T].src/lib.rs:944(unsafe { crate::const_transmute(...) }infrom_array): Missing// SAFETY:comment.[T; U]andGenericArray<T, N>have identical size, layout, and alignment whereU == N::USIZE.src/lib.rs:955(unsafe { crate::const_transmute(...) }ininto_array): Missing// SAFETY:comment.src/lib.rs:964(unsafe { mem::transmute(...) }infrom_chunks): Missing// SAFETY:comment.src/lib.rs:976(unsafe { mem::transmute(...) }infrom_chunks_mut): Missing// SAFETY:comment.src/lib.rs:985(unsafe { mem::transmute(...) }ininto_chunks): Missing// SAFETY:comment.GenericArraychunks to native array chunks.src/lib.rs:997(unsafe { mem::transmute(...) }ininto_chunks_mut): Missing// SAFETY:comment.Module
src/arr.rs(2 locations) 🔴src/arr.rs:33(unsafe { $crate::const_transmute(arr) }): Missing// SAFETY:comment.arris an initialized native array of exact lengthN::USIZE; transparent layout transmutation is sound.src/arr.rs:85(unsafe { GenericArray::try_from_vec(vec).unwrap_unchecked() }): Missing// SAFETY:comment.vec.len() == U == N::USIZE; fallible conversion is guaranteed to returnOk.Module
src/iter.rs(9 locations) 🔴src/iter.rs:59(unsafe { ptr::drop_in_place(...) }inDrop for GenericArrayIter): Missing// SAFETY:comment.as_mut_slice()spans remaining unconsumed elements[index..index_back]; dropping them in place exactly once is sound.src/iter.rs:71(unsafe { ptr::read(&self.array) }inClone for GenericArrayIter): Missing// SAFETY:comment.index_backandManuallyDrop.src/iter.rs:75(unsafe { ptr::write(dst, src.clone()) }): Missing// SAFETY:comment.dstpointer is valid and unread in destination allocation.src/iter.rs:93(unsafe { Some(ptr::read(...)) }innext): Missing// SAFETY:comment.self.index < self.index_backconfirms element is alive and unread; moving out viareadis sound.src/iter.rs:108(unsafe { ... }infold): Missing// SAFETY:comment.mem::forgetprevents double-freeing consumed items upon completion.src/iter.rs:153(unsafe { ptr::drop_in_place(...) }innth): Missing// SAFETY:comment.[index..next_index]are alive; dropping them prior to advancingindexis sound.src/iter.rs:175(unsafe { Some(ptr::read(...)) }innext_back): Missing// SAFETY:comment.index_back >= indexconfirms element is alive.src/iter.rs:186(unsafe { ... }inrfold): Missing// SAFETY:comment.mem::forgetprevents double drops.src/iter.rs:213(unsafe { ptr::drop_in_place(...) }innth_back): Missing// SAFETY:comment.[next_back..index_back]are alive and unread.Module
src/sequence.rs(22 locations) 🔴src/sequence.rs:48(unsafe { ... }inGenericSequence::inverted_zip): Missing// SAFETY:comment.IntrusiveArrayConsumerensures panic safety;ptr::readextracts elements sequentially.src/sequence.rs:83(unsafe impl GenericSequence for &S): Missing// SAFETY:comment.src/sequence.rs:99(unsafe impl GenericSequence for &mut S): Missing// SAFETY:comment.src/sequence.rs:202(unsafe impl Lengthen for GenericArray): Missing// SAFETY:comment.Add1<N>length arithmetic is verified bytypenumtrait bounds.src/sequence.rs:218(unsafe { ... }inLengthen::append): Missing// SAFETY:comment.out_ptrspans uninitialized memory forN + 1elements; writingself(Nitems) at offset 0 andlastat offsetNfully initializesLonger.src/sequence.rs:235(unsafe { ... }inLengthen::prepend): Missing// SAFETY:comment.firstat offset 0 andselfat offset 1 fully initializesLonger.src/sequence.rs:246(unsafe impl Shorten for GenericArray): Missing// SAFETY:comment.Sub1<N>length arithmetic verified by trait bounds.src/sequence.rs:259(unsafe { ... }inShorten::pop_back): Missing// SAFETY:comment.wholeis inManuallyDrop; reading firstN - 1elements asShorterand elementN - 1aslastpartitions ownership cleanly.src/sequence.rs:272(unsafe { ... }inShorten::pop_front): Missing// SAFETY:comment.headand remainingN - 1elements astailpartitions ownership cleanly.src/sequence.rs:296(unsafe impl Split for GenericArray): Missing// SAFETY:comment.N: Sub<K>ensures valid split indices; pointer reads partition array memory.src/sequence.rs:595(unsafe impl Flatten for GenericArray): Missing// SAFETY:comment.Prod<N, M>equals exact total contiguous element countN * M.src/sequence.rs:605(unsafe { crate::const_transmute(self) }): Missing// SAFETY:comment.GenericArray<GenericArray<T, N>, M>has exact size and layout equal toGenericArray<T, N * M>.src/sequence.rs:609(unsafe impl Flatten for &GenericArray): Missing// SAFETY:comment.src/sequence.rs:619(unsafe { mem::transmute(self) }): Missing// SAFETY:comment.src/sequence.rs:623(unsafe impl Flatten for &mut GenericArray): Missing// SAFETY:comment.src/sequence.rs:633(unsafe { mem::transmute(self) }): Missing// SAFETY:comment.src/sequence.rs:637(unsafe impl Unflatten for GenericArray): Missing// SAFETY:comment.Quot<NM, N>exact divisibility bounds verify total element equality.src/sequence.rs:647(unsafe { crate::const_transmute(self) }): Missing// SAFETY:comment.src/sequence.rs:651(unsafe impl Unflatten for &GenericArray): Missing// SAFETY:comment.src/sequence.rs:661(unsafe { mem::transmute(self) }): Missing// SAFETY:comment.src/sequence.rs:665(unsafe impl Unflatten for &mut GenericArray): Missing// SAFETY:comment.src/sequence.rs:675(unsafe { mem::transmute(self) }): Missing// SAFETY:comment.Module
src/hex.rs(5 locations) 🔴src/hex.rs:24(unsafe { core::hint::unreachable_unchecked() }): Missing// SAFETY:comment.dst.len() >= src.len() * 2; branch is unreachable.src/hex.rs:48(unsafe { faster_hex::hex_encode_upper(...).unwrap_unchecked() }): Missing// SAFETY:comment.faster_hexreturnsOk.src/hex.rs:49(unsafe { faster_hex::hex_encode(...).unwrap_unchecked() }): Missing// SAFETY:comment.faster_hexreturnsOk.src/hex.rs:73(unsafe { core::hint::unreachable_unchecked() }): Missing// SAFETY:comment.max_bytes <= N::USIZEdue to precision capping; branch is unreachable.src/hex.rs:92(unsafe { str::from_utf8_unchecked(...) }): Missing// SAFETY:comment.0-9a-fA-F), constituting valid UTF-8.Module
src/internal.rs(13 locations) 🔴src/internal.rs:38(pub unsafe fn extend(&mut self, ...)): Missing# Safetydocstring.positionaccurately tracks initialized items.src/internal.rs:77(pub unsafe fn iter_position(...)): Missing# Safetydocstring.positionexactly for each initialized element written.src/internal.rs:89(pub unsafe fn assume_init(self) -> ...): Missing# Safetydocstring.self.is_full()holds.src/internal.rs:100(unsafe { ptr::drop_in_place(...) }inDrop for ArrayBuilder): Missing// SAFETY:comment.[0..self.position]were initialized; dropping them in place is sound.src/internal.rs:151(pub unsafe fn extend(...)onIntrusiveArrayBuilder): Missing# Safetydocstring.extendis called at most once per builder.src/internal.rs:193(pub unsafe fn iter_position(...)onIntrusiveArrayBuilder): Missing# Safetydocstring.positionafter giving ownership todst.write.src/internal.rs:202(pub const unsafe fn finish(self)): Missing# Safetydocstring.self.is_full()holds prior to forgetting cleanup.src/internal.rs:232(pub unsafe fn array_assume_init(...)): Missing# Safetydocstring and// SAFETY:comment on line 233.arraymust be initialized.src/internal.rs:239(unsafe { ptr::drop_in_place(...) }inDrop for IntrusiveArrayBuilder): Missing// SAFETY:comment.[0..self.position]are initialized and dropped exactly once.src/internal.rs:276(pub unsafe fn iter_position(...)onArrayConsumer): Missing# Safetydocstring.positionfor each element consumed by value.src/internal.rs:283(unsafe { ptr::drop_in_place(...) }inDrop for ArrayConsumer): Missing// SAFETY:comment.[self.position..N]remain unconsumed and valid for dropping.src/internal.rs:313(pub unsafe fn iter_position(...)onIntrusiveArrayConsumer): Missing# Safetydocstring.positionfor each element consumed.src/internal.rs:320(unsafe { ptr::drop_in_place(...) }inDrop for IntrusiveArrayConsumer): Missing// SAFETY:comment.[self.position..N]are dropped exactly once.Module
src/compat/generic_array_0_14.rs(4 locations) 🔴src/compat/generic_array_0_14.rs:43(unsafe { core::mem::transmute(self) }): Missing// SAFETY:comment.GenericArray0.14 and v1 share identical transparent representation over[T; N].src/compat/generic_array_0_14.rs:52(unsafe { core::mem::transmute(self) }): Missing// SAFETY:comment.src/compat/generic_array_0_14.rs:58(unsafe { crate::const_transmute(self) }): Missing// SAFETY:comment.src/compat/generic_array_0_14.rs:64(unsafe { crate::const_transmute(value) }): Missing// SAFETY:comment.Module
src/compat/hybrid_array_0_4.rs(4 locations) 🔴src/compat/hybrid_array_0_4.rs:55(unsafe { core::mem::transmute(self) }): Missing// SAFETY:comment.hybrid_array_0_4::Arrayis a#[repr(transparent)]wrapper overGenericArray; layouts match exactly.src/compat/hybrid_array_0_4.rs:64(unsafe { core::mem::transmute(self) }): Missing// SAFETY:comment.src/compat/hybrid_array_0_4.rs:70(unsafe { crate::const_transmute(self) }): Missing// SAFETY:comment.src/compat/hybrid_array_0_4.rs:76(unsafe { crate::const_transmute(value) }): Missing// SAFETY:comment.Module
src/impl_alloc.rs(4 locations) 🔴src/impl_alloc.rs:13(unsafe { ... }inTryFrom<Vec>): Missing// SAFETY:comment.N::USIZE;IntrusiveArrayBuildertracks element transfer from vector iterator.src/impl_alloc.rs:56(unsafe { Box::from_raw(...) }): Missing// SAFETY:comment.Box<[T]>of lengthNandBox<GenericArray<T, N>>possess identical allocator layout.src/impl_alloc.rs:158(unsafe impl GenericSequence for Box<GenericArray<T, N>>): Missing// SAFETY:comment.src/impl_alloc.rs:166(unsafe { ... }ingenerate): Missing// SAFETY:comment.allocreturns non-null (see Critical Findings).IntrusiveArrayBuildertracks partial init.Module
src/impl_serde.rs(1 location) 🔴src/impl_serde.rs:65(unsafe { ... }inGAVisitor::visit_seq): Missing// SAFETY:comment.IntrusiveArrayBuilderensures partially unpacked sequence elements drop cleanly if deserializer returns early error.