diff --git a/lib.rs b/lib.rs index 88a1edc..3772763 100644 --- a/lib.rs +++ b/lib.rs @@ -750,22 +750,30 @@ impl SmallVec { self.data = SmallVecData::from_inline(MaybeUninit::uninit()); ptr::copy_nonoverlapping(ptr, self.data.inline_mut(), len); self.capacity = len; + deallocate(ptr, cap); } else if new_cap != cap { let layout = layout_array::(new_cap)?; - let new_alloc = NonNull::new(alloc::alloc::alloc(layout)) - .ok_or(CollectionAllocErr::AllocErr { layout })? - .cast() - .as_ptr(); - ptr::copy_nonoverlapping(ptr, new_alloc, len); - self.data = SmallVecData::from_heap(new_alloc, len); - self.capacity = new_cap; + let new_alloc; if unspilled { - return Ok(()); + new_alloc = NonNull::new(alloc::alloc::alloc(layout)) + .ok_or(CollectionAllocErr::AllocErr { layout })? + .cast() + .as_ptr(); + ptr::copy_nonoverlapping(ptr, new_alloc, len); + } else { + // This should never fail since the same succeeded + // when previously allocating `ptr`. + let old_layout = layout_array::(cap)?; + + let new_ptr = alloc::alloc::realloc(ptr as *mut u8, old_layout, layout.size()); + new_alloc = NonNull::new(new_ptr) + .ok_or(CollectionAllocErr::AllocErr { layout })? + .cast() + .as_ptr(); } - } else { - return Ok(()); + self.data = SmallVecData::from_heap(new_alloc, len); + self.capacity = new_cap; } - deallocate(ptr, cap); Ok(()) } }