diff options
Diffstat (limited to 'rust/alloc/raw_vec.rs')
| -rw-r--r-- | rust/alloc/raw_vec.rs | 18 | 
1 files changed, 12 insertions, 6 deletions
diff --git a/rust/alloc/raw_vec.rs b/rust/alloc/raw_vec.rs index 5db87eac53b7..65d5ce15828e 100644 --- a/rust/alloc/raw_vec.rs +++ b/rust/alloc/raw_vec.rs @@ -6,7 +6,6 @@ use core::alloc::LayoutError;  use core::cmp;  use core::intrinsics;  use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; -use core::ops::Drop;  use core::ptr::{self, NonNull, Unique};  use core::slice; @@ -274,10 +273,15 @@ impl<T, A: Allocator> RawVec<T, A> {          if T::IS_ZST || self.cap == 0 {              None          } else { -            // We have an allocated chunk of memory, so we can bypass runtime -            // checks to get our current layout. +            // We could use Layout::array here which ensures the absence of isize and usize overflows +            // and could hypothetically handle differences between stride and size, but this memory +            // has already been allocated so we know it can't overflow and currently rust does not +            // support such types. So we can do better by skipping some checks and avoid an unwrap. +            let _: () = const { assert!(mem::size_of::<T>() % mem::align_of::<T>() == 0) };              unsafe { -                let layout = Layout::array::<T>(self.cap).unwrap_unchecked(); +                let align = mem::align_of::<T>(); +                let size = mem::size_of::<T>().unchecked_mul(self.cap); +                let layout = Layout::from_size_align_unchecked(size, align);                  Some((self.ptr.cast().into(), layout))              }          } @@ -465,11 +469,13 @@ impl<T, A: Allocator> RawVec<T, A> {          assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity");          let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) }; - +        // See current_memory() why this assert is here +        let _: () = const { assert!(mem::size_of::<T>() % mem::align_of::<T>() == 0) };          let ptr = unsafe {              // `Layout::array` cannot overflow here because it would have              // overflowed earlier when capacity was larger. -            let new_layout = Layout::array::<T>(cap).unwrap_unchecked(); +            let new_size = mem::size_of::<T>().unchecked_mul(cap); +            let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());              self.alloc                  .shrink(ptr, layout, new_layout)                  .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?  | 
