use core::marker::PhantomData; use core::ptr::{self, NonNull, drop_in_place}; use core::slice::{self}; use crate::alloc::Global; use crate::raw_vec::RawVec; // A helper struct for in-place iteration that drops the destination slice of iteration, // i.e. the head. The source slice (the tail) is dropped by IntoIter. pub(super) struct InPlaceDrop { pub(super) inner: *mut T, pub(super) dst: *mut T, } impl InPlaceDrop { fn len(&self) -> usize { unsafe { self.dst.offset_from_unsigned(self.inner) } } } impl Drop for InPlaceDrop { #[inline] fn drop(&mut self) { unsafe { ptr::drop_in_place(slice::from_raw_parts_mut(self.inner, self.len())); } } } // A helper struct for in-place collection that drops the destination items together with // the source allocation - i.e. before the reallocation happened - to avoid leaking them // if some other destructor panics. pub(super) struct InPlaceDstDataSrcBufDrop { pub(super) ptr: NonNull, pub(super) len: usize, pub(super) src_cap: usize, pub(super) src: PhantomData, } impl Drop for InPlaceDstDataSrcBufDrop { #[inline] fn drop(&mut self) { unsafe { let _drop_allocation = RawVec::::from_nonnull_in(self.ptr.cast::(), self.src_cap, Global); drop_in_place(core::ptr::slice_from_raw_parts_mut::(self.ptr.as_ptr(), self.len)); }; } }