Closed
Description
If grow
is given a size that is within the inline size after a SmallVec has been spilled, the resulting value is corrupted.
let mut v: SmallVec<[u8; 4]> = SmallVec::new();
v.push(1);
v.push(2);
v.push(3);
v.push(4);
// Cause it to spill.
v.push(5);
assert!(v.spilled());
v.clear();
// Shrink to inline.
v.grow(2);
// This should crash with 'entered unreachable code'.
println!("after grow {:?} len={} cap={}", v, v.len(), v.capacity());
This is admittedly unusual, most code would use shrink_to_fit
.
I think the following should fix it.
diff --git a/lib.rs b/lib.rs
index 5af32ba..3767e3b 100644
--- a/lib.rs
+++ b/lib.rs
@@ -654,6 +654,7 @@ impl<A: Array> SmallVec<A> {
}
self.data = SmallVecData::from_inline(mem::uninitialized());
ptr::copy_nonoverlapping(ptr, self.data.inline_mut().ptr_mut(), len);
+ self.capacity = len;
} else if new_cap != cap {
let mut vec = Vec::with_capacity(new_cap);
let new_alloc = vec.as_mut_ptr();