diff --git a/src/vec.rs b/src/vec.rs index bb972336bc..1db505bb8f 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -5,34 +5,37 @@ use core::{ ops, ptr, slice, }; -/// Workaround forbidden specialization of Drop -pub trait VecDrop { - // SAFETY: drop_with_len will be called to call drop in place the first `len` elements of the buffer. - // Only the Owned buffer (`[MaybeUninit; N]`) must drop the items - // and the view (`[MaybeUninit]`) drops nothing. - // `drop_with_len `assumes that the buffer can contain `len` elements. - unsafe fn drop_with_len(&mut self, len: usize); +pub trait VecBuffer { + type T; + + fn as_vecview(vec: &VecInner) -> &VecView; + fn as_mut_vecview(vec: &mut VecInner) -> &mut VecView; } -impl VecDrop for [MaybeUninit] { - unsafe fn drop_with_len(&mut self, len: usize) { - // NOTE(unsafe) avoid bound checks in the slicing operation - // &mut buffer[..len] - // SAFETY: buffer[..len] must be valid to drop given the safety requirement of the trait definition. - let mut_slice = slice::from_raw_parts_mut(self.as_mut_ptr() as *mut T, len); - // We drop each element used in the vector by turning into a `&mut [T]`. - ptr::drop_in_place(mut_slice); +impl VecBuffer for [MaybeUninit; N] { + type T = T; + + fn as_vecview(vec: &VecInner) -> &VecView { + vec + } + fn as_mut_vecview(vec: &mut VecInner) -> &mut VecView { + vec } } -impl VecDrop for [MaybeUninit; N] { - unsafe fn drop_with_len(&mut self, len: usize) { - VecDrop::drop_with_len(self.as_mut_slice(), len) +impl VecBuffer for [MaybeUninit] { + type T = T; + + fn as_vecview(vec: &VecInner) -> &VecView { + vec + } + fn as_mut_vecview(vec: &mut VecInner) -> &mut VecView { + vec } } ///
This is private API and should not be used
-pub struct VecInner { +pub struct VecInner { len: usize, buffer: B, } @@ -1572,10 +1575,12 @@ impl From<[T; M]> for Vec { } } -impl Drop for VecInner { +impl Drop for VecInner { fn drop(&mut self) { + let mut_slice = VecBuffer::as_mut_vecview(self).as_mut_slice(); + // We drop each element used in the vector by turning into a `&mut [T]`. // SAFETY: the buffer contains initialized data for the range 0..self.len - unsafe { self.buffer.drop_with_len(self.len) } + unsafe { ptr::drop_in_place(mut_slice) } } }