Skip to content

Commit

Permalink
Implement split_at_spare_mut directly
Browse files Browse the repository at this point in the history
The previous implementation used slice::as_mut_ptr_range to derive the
pointer for the spare capacity slice. This is invalid, because that
pointer is derived from the initialized region, so it does not have
provenance over the uninitialized region.
  • Loading branch information
saethlin committed Dec 19, 2021
1 parent daf2204 commit 4f80816
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2141,12 +2141,15 @@ impl<T, A: Allocator> Vec<T, A> {
unsafe fn split_at_spare_mut_with_len(
&mut self,
) -> (&mut [T], &mut [MaybeUninit<T>], &mut usize) {
let Range { start: ptr, end: spare_ptr } = self.as_mut_ptr_range();
let ptr = self.as_mut_ptr();
// SAFETY:
// - `ptr` is guaranteed to be valid for `self.len` elements
let spare_ptr = unsafe { ptr.add(self.len) };
let spare_ptr = spare_ptr.cast::<MaybeUninit<T>>();
let spare_len = self.buf.capacity() - self.len;

// SAFETY:
// - `ptr` is guaranteed to be valid for `len` elements
// - `ptr` is guaranteed to be valid for `self.len` elements
// - `spare_ptr` is pointing one element past the buffer, so it doesn't overlap with `initialized`
unsafe {
let initialized = slice::from_raw_parts_mut(ptr, self.len);
Expand Down

0 comments on commit 4f80816

Please sign in to comment.