From 259901f9101c726ea32fba195e3236314fd31fb3 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 26 Apr 2022 14:47:56 -0700 Subject: [PATCH] Drop by slice, not one by one --- src/pin_vec.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/pin_vec.rs b/src/pin_vec.rs index a3453e1..8d42418 100644 --- a/src/pin_vec.rs +++ b/src/pin_vec.rs @@ -23,13 +23,25 @@ impl PinVec { } pub fn clear(&mut self) { - for i in 0..self.len { - // Safety: we know the pointer is initialized because its index is in bounds, and it - // can be dropped because we are emptying the container, which means these contents - // will not be accessed again. - unsafe { drop_in_place(self.get_mut(i).unwrap()) } + if mem::needs_drop::() { + let (last_slot, offset, _) = calculate_key(self.len()); + for (i, mut slot) in self.slots.drain(..).enumerate() { + let slice: &mut [MaybeUninit] = if i < last_slot { + &mut *slot + } else { + &mut slot[0..offset] + }; + // Safety: we initialized slice to only point to the already-initialized elements. + // It's safe to drop_in_place because we are draining the Vec. + unsafe { + let slice: &mut [T] = mem::transmute(slice); + drop_in_place(slice); + } + } + } else { + self.slots.clear(); } - self.slots.clear(); + debug_assert_eq!(self.slots.len(), 0); self.len = 0; }