From a1835bcb01fc345653fd9e9ce02b0d103032c58d Mon Sep 17 00:00:00 2001 From: Waffle Date: Wed, 3 Mar 2021 01:04:20 +0300 Subject: [PATCH] Make Vec::split_at_spare_mut impl safer & simplier --- library/alloc/src/vec/mod.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index e5545d2a77f..ff401b33832 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1944,20 +1944,16 @@ impl Vec { #[unstable(feature = "vec_split_at_spare", issue = "81944")] #[inline] pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit]) { - let ptr = self.as_mut_ptr(); - - // SAFETY: - // - `ptr` is guaranteed to be in bounds for `capacity` elements - // - `len` is guaranteed to less or equal to `capacity` - // - `MaybeUninit` has the same layout as `T` - let spare_ptr = unsafe { ptr.cast::>().add(self.len) }; + let Range { start: ptr, end: spare_ptr } = self.as_mut_ptr_range(); + let spare_ptr = spare_ptr.cast::>(); + let spare_len = self.buf.capacity() - self.len; // SAFETY: // - `ptr` is guaranteed to be valid for `len` elements - // - `spare_ptr` is offseted from `ptr` by `len`, so it doesn't overlap `initialized` slice + // - `spare_ptr` is pointing one element past the buffer, so it doesn't overlap with `initialized` slice unsafe { let initialized = slice::from_raw_parts_mut(ptr, self.len); - let spare = slice::from_raw_parts_mut(spare_ptr, self.buf.capacity() - self.len); + let spare = slice::from_raw_parts_mut(spare_ptr, spare_len); (initialized, spare) }