Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions fuzz/fuzz_targets/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ fn test_with_inline_cap<const N: usize>(
small_vec = SmallVec::new();
std_vec = Vec::new();
}
Op::WithCapacity(cap) => {
small_vec = SmallVec::with_capacity(cap.0);
std_vec = Vec::with_capacity(cap.0);
Op::WithCapacity(capacity) => {
small_vec = SmallVec::with_capacity(capacity.0);
std_vec = Vec::with_capacity(capacity.0);
}
#[allow(deprecated)]
Op::FromVec => {
Expand Down
18 changes: 11 additions & 7 deletions src/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,18 @@ impl<Item, const INLINE: usize> From<<Vec<Item, Global> as Like>::Type>
let length = vec.len();

// A heap-allocated `SmallVec` must always observe the invariant
// that `cap > INLINE`.
// that `capacity > INLINE`.
if vec.capacity() <= INLINE {
vec.reserve(INLINE + 1 - length);
}
let cap = vec.capacity();
let capacity = vec.capacity();
// SAFETY: vec.capacity is not `0` (checked above), so the pointer
// can not dangle and thus specifically cannot be null.
let pointer = unsafe { NonNull::new_unchecked(vec.as_mut_ptr()) };

Self {
length: LocatedLength::new(length, true),
raw: RawSmallVec::heap(pointer, cap),
raw: RawSmallVec::heap(pointer, capacity),
allocator: Global
}
}
Expand Down Expand Up @@ -186,14 +186,18 @@ impl<Item, const INLINE: usize, Heap: Allocator> From<SmallVec<Item, INLINE, Hea
// SAFETY:
// - `pointer` was created with the SmallVec's allocator
// - `pointer` was created with the appropriate alignment for `Item`
// - the allocation pointed to by pointer is exactly cap *
// - the allocation pointed to by pointer is exactly capacity *
// sizeof(Item)
// - `length` is less than or equal to `cap`
// - `length` is less than or equal to `capacity`
// - the first `length` entries are proper `Item`-values
// - the allocation is not larger than `isize::MAX`
unsafe {
let (pointer, cap) = this.raw.heap;
<Vec<Item, Global> as Like>::Type::from_raw_parts(pointer.as_ptr(), length, cap)
let (pointer, capacity) = this.raw.heap;
<Vec<Item, Global> as Like>::Type::from_raw_parts(
pointer.as_ptr(),
length,
capacity
)
}
}
}
Expand Down
18 changes: 9 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -660,15 +660,15 @@ impl<Item, const INLINE: usize, Heap: Allocator> SmallVec<Item, INLINE, Heap> {
if on_heap {
unsafe {
// SAFETY: heap member is active
let (pointer, old_cap) = self.raw.heap;
let (pointer, old_capacity) = self.raw.heap;
// inline member is now active

// SAFETY: length <= new_capacity <= Self::inline_size()
// so the copy is within bounds of the inline member
copy_nonoverlapping(pointer.as_ptr(), self.raw.as_mut_ptr_inline(), length);
drop(DropDealloc {
pointer: pointer.cast(),
size_bytes: old_cap * size_of::<Item>(),
size_bytes: old_capacity * size_of::<Item>(),
align: align_of::<Item>(),
allocator: &self.allocator
});
Expand All @@ -695,10 +695,10 @@ impl<Item, const INLINE: usize, Heap: Allocator> SmallVec<Item, INLINE, Heap> {
.checked_add(additional)
.ok_or(SmallVecError::CapacityOverflow)?;

let double_cap = self.capacity().saturating_mul(2);
let double_capacity = self.capacity().saturating_mul(2);

let new_capacity = required
.max(double_cap)
.max(double_capacity)
.checked_next_power_of_two()
.ok_or(SmallVecError::CapacityOverflow)?;

Expand Down Expand Up @@ -1894,12 +1894,12 @@ unsafe impl<const INLINE: usize, Heap: Allocator> BufMut for SmallVec<u8, INLINE

let (length, on_heap) = self.length.parts();
// SAFETY: the tag tells which member is active
let cap = unsafe { self.raw.capacity(on_heap) };
let capacity = unsafe { self.raw.capacity(on_heap) };
let pointer = unsafe { self.raw.as_mut_ptr(on_heap) };
// SAFETY: Since `pointer` is valid for `cap` bytes,
// `pointer.add(length)` must be valid for `cap - length` bytes. The
// subtraction will not underflow since `length <= cap`.
unsafe { UninitSlice::from_raw_parts_mut(pointer.add(length), cap - length) }
// SAFETY: Since `pointer` is valid for `capacity` bytes,
// `pointer.add(length)` must be valid for `capacity - length` bytes.
// The subtraction will not underflow since `length <= capacity`.
unsafe { UninitSlice::from_raw_parts_mut(pointer.add(length), capacity - length) }
}

// Specialize these methods so they can skip checking `remaining_mut`
Expand Down
4 changes: 2 additions & 2 deletions tests/parts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ fn into_from_parts_spilled() {
assert_eq!(length.len(), 3);

// SAFETY: `length` says on heap, so `heap` is the active member.
let (pointer, cap) = unsafe { raw.heap };
assert!(cap > 1);
let (pointer, capacity) = unsafe { raw.heap };
assert!(capacity > 1);

// SAFETY: parts come straight from `into_parts`.
let rebuilt = unsafe { SmallVec::<i32, 1>::from_parts(raw, length) };
Expand Down
Loading