Skip to main content

alloc/vec/
in_place_drop.rs

1use core::marker::PhantomData;
2use core::ptr::NonNull;
3
4use crate::alloc::Global;
5use crate::raw_vec::RawVec;
6
7// A helper struct for in-place iteration that drops the destination slice of iteration,
8// i.e. the head. The source slice (the tail) is dropped by IntoIter.
9pub(super) struct InPlaceDrop<T> {
10    pub(super) inner: *mut T,
11    pub(super) dst: *mut T,
12}
13
14impl<T> InPlaceDrop<T> {
15    fn len(&self) -> usize {
16        unsafe { self.dst.offset_from_unsigned(self.inner) }
17    }
18}
19
20impl<T> Drop for InPlaceDrop<T> {
21    #[inline]
22    fn drop(&mut self) {
23        unsafe { self.inner.cast_slice(self.len()).drop_in_place() }
24    }
25}
26
27// A helper struct for in-place collection that drops the destination items together with
28// the source allocation - i.e. before the reallocation happened - to avoid leaking them
29// if some other destructor panics.
30pub(super) struct InPlaceDstDataSrcBufDrop<Src, Dest> {
31    pub(super) ptr: NonNull<Dest>,
32    pub(super) len: usize,
33    pub(super) src_cap: usize,
34    pub(super) src: PhantomData<Src>,
35}
36
37impl<Src, Dest> Drop for InPlaceDstDataSrcBufDrop<Src, Dest> {
38    #[inline]
39    fn drop(&mut self) {
40        unsafe {
41            let _drop_allocation =
42                RawVec::<Src>::from_nonnull_in(self.ptr.cast::<Src>(), self.src_cap, Global);
43            self.ptr.as_ptr().cast_slice(self.len).drop_in_place();
44        };
45    }
46}