Description
## Summary
`StackVec::retain` committed its new length to `self.len` only after
its internal loop completed. If the retain predicate or a removed
element's `Drop` implementation panicked before the loop finished,
unwinding proceeded with `self.len` still equal to the original,
pre-retain length, leaving either a duplicated or already-destroyed
element inside `0..len`. `StackVec`'s own `Drop` then revisited that
slot, causing a double-drop (and for heap-owning types, a double-free).
## Impact
Affects `StackVec<T, CAP>::retain` for `T: Drop` types where the
predicate or the removed element's destructor can panic, on builds
with unwinding enabled (`panic = "unwind"`). `no_std`/`panic = "abort"`
builds cannot trigger this, since unwinding never occurs.
## Patch
Fixed in 0.3.3 using an unwind-safe backshift guard, matching the
approach `alloc::vec::Vec::retain` uses.
Affected packages
| Ecosystem | Package | Affected | Fixed | Record |
|---|---|---|---|---|
| crates.io | stack_collections | >= 0.3.0, < 0.3.3 | 0.3.3 | RUSTSEC-2026-0301 |