Rename VecDrop to VecBuffer

This represent more clearly the role of the trait now that it's not used
to work around drop specialization.
This commit is contained in:
Sosthène Guédon 2024-04-05 15:24:45 +02:00
parent ec6700a96b
commit fc133a9f48
No known key found for this signature in database
GPG Key ID: 36DA48A4C827B354

View File

@ -5,34 +5,37 @@ use core::{
ops, ptr, slice, ops, ptr, slice,
}; };
/// Workaround forbidden specialization of Drop pub trait VecBuffer {
pub trait VecDrop { type T;
// SAFETY: drop_with_len will be called to call drop in place the first `len` elements of the buffer.
// Only the Owned buffer (`[MaybeUninit<T>; N]`) must drop the items fn as_vecview(vec: &VecInner<Self>) -> &VecView<Self::T>;
// and the view (`[MaybeUninit<T>]`) drops nothing. fn as_mut_vecview(vec: &mut VecInner<Self>) -> &mut VecView<Self::T>;
// `drop_with_len `assumes that the buffer can contain `len` elements.
unsafe fn drop_with_len(&mut self, len: usize);
} }
impl<T> VecDrop for [MaybeUninit<T>] { impl<T, const N: usize> VecBuffer for [MaybeUninit<T>; N] {
unsafe fn drop_with_len(&mut self, len: usize) { type T = T;
// NOTE(unsafe) avoid bound checks in the slicing operation
// &mut buffer[..len] fn as_vecview(vec: &VecInner<Self>) -> &VecView<Self::T> {
// SAFETY: buffer[..len] must be valid to drop given the safety requirement of the trait definition. vec
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]`. fn as_mut_vecview(vec: &mut VecInner<Self>) -> &mut VecView<Self::T> {
ptr::drop_in_place(mut_slice); vec
} }
} }
impl<T, const N: usize> VecDrop for [MaybeUninit<T>; N] { impl<T> VecBuffer for [MaybeUninit<T>] {
unsafe fn drop_with_len(&mut self, len: usize) { type T = T;
VecDrop::drop_with_len(self.as_mut_slice(), len)
fn as_vecview(vec: &VecInner<Self>) -> &VecView<Self::T> {
vec
}
fn as_mut_vecview(vec: &mut VecInner<Self>) -> &mut VecView<Self::T> {
vec
} }
} }
/// <div class="warn">This is private API and should not be used</div> /// <div class="warn">This is private API and should not be used</div>
pub struct VecInner<B: ?Sized + VecDrop> { pub struct VecInner<B: ?Sized + VecBuffer> {
len: usize, len: usize,
buffer: B, buffer: B,
} }
@ -1572,10 +1575,12 @@ impl<T, const N: usize, const M: usize> From<[T; M]> for Vec<T, N> {
} }
} }
impl<T: ?Sized + VecDrop> Drop for VecInner<T> { impl<T: ?Sized + VecBuffer> Drop for VecInner<T> {
fn drop(&mut self) { 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 // 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) }
} }
} }