From 2547adf7df486fbca473d85125a04d0cc1a59224 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Thu, 17 Oct 2024 16:55:27 +0200 Subject: [PATCH] Minimize diff between `src/arrayvec{,_copy}.rs` --- src/arrayvec.rs | 16 +++--- src/arrayvec_copy.patch | 116 ++++------------------------------------ src/arrayvec_copy.rs | 28 ++++++---- 3 files changed, 35 insertions(+), 125 deletions(-) diff --git a/src/arrayvec.rs b/src/arrayvec.rs index e87b3ef..9a2a5c4 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -499,7 +499,7 @@ impl ArrayVec { let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len }; #[inline(always)] - fn process_one bool, T, const CAP: usize, const DELETED: bool>( + fn process_one bool, const CAP: usize, const DELETED: bool>( f: &mut F, g: &mut BackshiftOnDrop<'_, T, CAP> ) -> bool { @@ -522,14 +522,14 @@ impl ArrayVec { // Stage 1: Nothing was deleted. while g.processed_len != original_len { - if !process_one::(&mut f, &mut g) { + if !process_one::(&mut f, &mut g) { break; } } // Stage 2: Some elements were deleted. while g.processed_len != original_len { - process_one::(&mut f, &mut g); + process_one::(&mut f, &mut g); } drop(g); @@ -1029,16 +1029,16 @@ impl<'a, T: 'a, const CAP: usize> Drop for Drain<'a, T, CAP> { } } -struct ScopeExitGuard - where F: FnMut(&Data, &mut T) +struct ScopeExitGuard + where F: FnMut(&Data, &mut V) { - value: T, + value: V, data: Data, f: F, } -impl Drop for ScopeExitGuard - where F: FnMut(&Data, &mut T) +impl Drop for ScopeExitGuard + where F: FnMut(&Data, &mut V) { fn drop(&mut self) { (self.f)(&self.data, &mut self.value) diff --git a/src/arrayvec_copy.patch b/src/arrayvec_copy.patch index 99fa7dd..c1d06df 100644 --- a/src/arrayvec_copy.patch +++ b/src/arrayvec_copy.patch @@ -1,25 +1,18 @@ diff --git a/src/arrayvec_copy_generated.rs b/src/arrayvec_copy.rs -index 2c32eed..ada0728 100644 +index c4be864..ec5224d 100644 --- a/src/arrayvec_copy_generated.rs +++ b/src/arrayvec_copy.rs -@@ -14,7 +14,6 @@ use std::fmt; - #[cfg(feature="std")] - use std::io; +@@ -27,6 +27,9 @@ use crate::utils::MakeMaybeUninit; --use std::mem::ManuallyDrop; - use std::mem::MaybeUninit; - - #[cfg(feature="serde")] -@@ -25,7 +24,7 @@ use crate::errors::CapacityError; - use crate::arrayvec_impl::ArrayVecImpl; - use crate::utils::MakeMaybeUninit; - --/// A vector with a fixed capacity. -+/// A vector with a fixed capacity which implements `Copy` and its elemenents are constrained to also be `Copy`. + /// A vector with a fixed capacity. /// ++/// **Its only difference to [`ArrayVec`](crate::ArrayVec) is that its elements ++/// are constrained to be `Copy` which allows it to be `Copy` itself.** ++/// /// The `ArrayVecCopy` is a vector backed by a fixed size array. It keeps track of /// the number of initialized elements. The `ArrayVecCopy` is parameterized -@@ -46,14 +45,6 @@ pub struct ArrayVecCopy { + /// by `T` for the element type and `CAP` for the maximum capacity. +@@ -46,14 +49,6 @@ pub struct ArrayVecCopy { xs: [MaybeUninit; CAP], } @@ -34,80 +27,7 @@ index 2c32eed..ada0728 100644 macro_rules! panic_oob { ($method_name:expr, $index:expr, $len:expr) => { panic!(concat!("ArrayVecCopy::", $method_name, ": index {} is out of bounds in vector of length {}"), -@@ -231,8 +222,7 @@ impl ArrayVecCopy { - ArrayVecImpl::push_unchecked(self, element) - } - -- /// Shortens the vector, keeping the first `len` elements and dropping -- /// the rest. -+ /// Shortens the vector, keeping the first `len` elements. - /// - /// If `len` is greater than the vector’s current length this has no - /// effect. -@@ -499,7 +489,7 @@ impl ArrayVecCopy { - let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len }; - - #[inline(always)] -- fn process_one bool, T, const CAP: usize, const DELETED: bool>( -+ fn process_one bool, const CAP: usize, const DELETED: bool>( - f: &mut F, - g: &mut BackshiftOnDrop<'_, T, CAP> - ) -> bool { -@@ -507,7 +497,6 @@ impl ArrayVecCopy { - if !f(unsafe { &mut *cur }) { - g.processed_len += 1; - g.deleted_cnt += 1; -- unsafe { ptr::drop_in_place(cur) }; - return false; - } - if DELETED { -@@ -522,20 +511,20 @@ impl ArrayVecCopy { - - // Stage 1: Nothing was deleted. - while g.processed_len != original_len { -- if !process_one::(&mut f, &mut g) { -+ if !process_one::(&mut f, &mut g) { - break; - } - } - - // Stage 2: Some elements were deleted. - while g.processed_len != original_len { -- process_one::(&mut f, &mut g); -+ process_one::(&mut f, &mut g); - } - - drop(g); - } - -- /// Set the vector’s length without dropping or moving out elements -+ /// Set the vector’s length without moving out elements - /// - /// This method is `unsafe` because it changes the notion of the - /// number of “valid” elements in the vector. Use with care. -@@ -668,8 +657,7 @@ impl ArrayVecCopy { - /// This operation is safe if and only if length equals capacity. - pub unsafe fn into_inner_unchecked(self) -> [T; CAP] { - debug_assert_eq!(self.len(), self.capacity()); -- let self_ = ManuallyDrop::new(self); -- let array = ptr::read(self_.as_ptr() as *const [T; CAP]); -+ let array = ptr::read(self.as_ptr() as *const [T; CAP]); - array - } - -@@ -755,10 +743,9 @@ impl DerefMut for ArrayVecCopy { - impl From<[T; CAP]> for ArrayVecCopy { - #[track_caller] - fn from(array: [T; CAP]) -> Self { -- let array = ManuallyDrop::new(array); - let mut vec = >::new(); - unsafe { -- (&*array as *const [T; CAP] as *const [MaybeUninit; CAP]) -+ (&array as *const [T; CAP] as *const [MaybeUninit; CAP]) - .copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit; CAP], 1); - vec.set_len(CAP); - } -@@ -929,21 +916,6 @@ impl DoubleEndedIterator for IntoIter { +@@ -929,21 +924,6 @@ impl DoubleEndedIterator for IntoIter { impl ExactSizeIterator for IntoIter { } @@ -129,21 +49,3 @@ index 2c32eed..ada0728 100644 impl Clone for IntoIter where T: Clone, { -@@ -1029,7 +1001,7 @@ impl<'a, T: Copy + 'a, const CAP: usize> Drop for Drain<'a, T, CAP> { - } - } - --struct ScopeExitGuard -+struct ScopeExitGuard - where F: FnMut(&Data, &mut T) - { - value: T, -@@ -1037,7 +1009,7 @@ struct ScopeExitGuard - f: F, - } - --impl Drop for ScopeExitGuard -+impl Drop for ScopeExitGuard - where F: FnMut(&Data, &mut T) - { - fn drop(&mut self) { diff --git a/src/arrayvec_copy.rs b/src/arrayvec_copy.rs index df3fa90..ec5224d 100644 --- a/src/arrayvec_copy.rs +++ b/src/arrayvec_copy.rs @@ -14,6 +14,7 @@ use std::fmt; #[cfg(feature="std")] use std::io; +use std::mem::ManuallyDrop; use std::mem::MaybeUninit; #[cfg(feature="serde")] @@ -24,7 +25,10 @@ use crate::errors::CapacityError; use crate::arrayvec_impl::ArrayVecImpl; use crate::utils::MakeMaybeUninit; -/// A vector with a fixed capacity which implements `Copy` and its elemenents are constrained to also be `Copy`. +/// A vector with a fixed capacity. +/// +/// **Its only difference to [`ArrayVec`](crate::ArrayVec) is that its elements +/// are constrained to be `Copy` which allows it to be `Copy` itself.** /// /// The `ArrayVecCopy` is a vector backed by a fixed size array. It keeps track of /// the number of initialized elements. The `ArrayVecCopy` is parameterized @@ -222,7 +226,8 @@ impl ArrayVecCopy { ArrayVecImpl::push_unchecked(self, element) } - /// Shortens the vector, keeping the first `len` elements. + /// Shortens the vector, keeping the first `len` elements and dropping + /// the rest. /// /// If `len` is greater than the vector’s current length this has no /// effect. @@ -497,6 +502,7 @@ impl ArrayVecCopy { if !f(unsafe { &mut *cur }) { g.processed_len += 1; g.deleted_cnt += 1; + unsafe { ptr::drop_in_place(cur) }; return false; } if DELETED { @@ -524,7 +530,7 @@ impl ArrayVecCopy { drop(g); } - /// Set the vector’s length without moving out elements + /// Set the vector’s length without dropping or moving out elements /// /// This method is `unsafe` because it changes the notion of the /// number of “valid” elements in the vector. Use with care. @@ -657,7 +663,8 @@ impl ArrayVecCopy { /// This operation is safe if and only if length equals capacity. pub unsafe fn into_inner_unchecked(self) -> [T; CAP] { debug_assert_eq!(self.len(), self.capacity()); - let array = ptr::read(self.as_ptr() as *const [T; CAP]); + let self_ = ManuallyDrop::new(self); + let array = ptr::read(self_.as_ptr() as *const [T; CAP]); array } @@ -743,9 +750,10 @@ impl DerefMut for ArrayVecCopy { impl From<[T; CAP]> for ArrayVecCopy { #[track_caller] fn from(array: [T; CAP]) -> Self { + let array = ManuallyDrop::new(array); let mut vec = >::new(); unsafe { - (&array as *const [T; CAP] as *const [MaybeUninit; CAP]) + (&*array as *const [T; CAP] as *const [MaybeUninit; CAP]) .copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit; CAP], 1); vec.set_len(CAP); } @@ -1001,16 +1009,16 @@ impl<'a, T: Copy + 'a, const CAP: usize> Drop for Drain<'a, T, CAP> { } } -struct ScopeExitGuard - where F: FnMut(&Data, &mut T) +struct ScopeExitGuard + where F: FnMut(&Data, &mut V) { - value: T, + value: V, data: Data, f: F, } -impl Drop for ScopeExitGuard - where F: FnMut(&Data, &mut T) +impl Drop for ScopeExitGuard + where F: FnMut(&Data, &mut V) { fn drop(&mut self) { (self.f)(&self.data, &mut self.value)