about summary refs log tree commit diff
path: root/library/alloc/src
diff options
context:
space:
mode:
authorBen Kimock <kimockb@gmail.com>2021-12-19 00:18:31 -0500
committerBen Kimock <kimockb@gmail.com>2021-12-19 15:14:52 -0500
commit4f808161bc2852bff52cf3dd1bb4baf3003ef181 (patch)
tree09108ee50e6839e6c3823f64dbe07308d9e3808f /library/alloc/src
parentdaf2204aa4954a9426cee93eb1baa2b26eb69070 (diff)
downloadrust-4f808161bc2852bff52cf3dd1bb4baf3003ef181.tar.gz
rust-4f808161bc2852bff52cf3dd1bb4baf3003ef181.zip
Implement split_at_spare_mut directly
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.
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/vec/mod.rs7
1 files changed, 5 insertions, 2 deletions
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index d24b4bdffde..a55fce2760f 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -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);