From 7e2e756adcc2a23e8ff4b0c4a22e03d59842354a Mon Sep 17 00:00:00 2001 From: Rushikesh Garad Date: Fri, 11 Sep 2026 20:07:07 +0530 Subject: [PATCH 1/5] refactor: move rayon.rs into src/iterators/ (fixes #598) --- src/iterators/rayon.rs | 97 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/iterators/rayon.rs diff --git a/src/iterators/rayon.rs b/src/iterators/rayon.rs new file mode 100644 index 0000000..2440f9f --- /dev/null +++ b/src/iterators/rayon.rs @@ -0,0 +1,97 @@ +//! The code is heavily inspired by `rayon/vec.rs`, since it's exactly what we +//! need, except it's all private + +use { + crate::SmallVec, + core::{ + mem::take, + ptr::{ + self, + drop_in_place + }, + slice + }, + rayon::{ + iter::plumbing::{ + Producer, + UnindexedConsumer, + bridge_producer_consumer + }, + prelude::ParallelIterator + } +}; + +struct SliceDrain<'a, T>(slice::IterMut<'a, T>); + +impl Iterator for SliceDrain<'_, T> { + type Item = T; + + fn next(&mut self) -> Option { + self.0.next().map(|val| unsafe { ptr::read(val) }) + } +} + +impl DoubleEndedIterator for SliceDrain<'_, T> { + fn next_back(&mut self) -> Option { + self.0.next_back().map(|val| unsafe { ptr::read(val) }) + } +} + +impl ExactSizeIterator for SliceDrain<'_, T> { + fn len(&self) -> usize { + self.0.len() + } +} + +impl Drop for SliceDrain<'_, T> { + fn drop(&mut self) { + unsafe { drop_in_place(take(&mut self.0).into_slice()) }; + } +} + +struct DrainProducer<'a, T>(&'a mut [T]); + +impl<'a, T: Send> Producer for DrainProducer<'a, T> { + type IntoIter = SliceDrain<'a, T>; + type Item = T; + + fn into_iter(mut self) -> SliceDrain<'a, T> { + SliceDrain(take(&mut self.0).iter_mut()) + } + + fn split_at(mut self, index: usize) -> (Self, Self) { + let (left, right) = take(&mut self.0).split_at_mut(index); + + (DrainProducer(left), DrainProducer(right)) + } +} + +impl Drop for DrainProducer<'_, T> { + fn drop(&mut self) { + unsafe { drop_in_place(self.0) }; + } +} + +impl ParallelIterator for SmallVec { + type Item = T; + + fn drive_unindexed>(mut self, consumer: C) -> C::Result { + let len = self.len(); + + bridge_producer_consumer( + len, + DrainProducer(unsafe { + // SAFETY: set_len(0) is always valid + // All items will either be passed out or dropped by + // DrainProducer/SliceDrop, so there shouldn't + // be any possibility for leakage + self.set_len(0); + + // SAFETY: set_len didn't deallocate/drop the elements, so they + // are still valid. + slice::from_raw_parts_mut(self.as_mut_ptr(), len) + }), + consumer + ) + } +} From 19963bf0e899106ccdaf9d188e090d21e82af348 Mon Sep 17 00:00:00 2001 From: Rushikesh Garad Date: Fri, 11 Sep 2026 20:07:09 +0530 Subject: [PATCH 2/5] refactor: add src/iterators/mod.rs module link (fixes #598) --- src/iterators/mod.rs | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/iterators/mod.rs diff --git a/src/iterators/mod.rs b/src/iterators/mod.rs new file mode 100644 index 0000000..d93782e --- /dev/null +++ b/src/iterators/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "rayon")] +mod rayon; From ada7e47497fbbc5ccc48a123b7f3143a2b26ca36 Mon Sep 17 00:00:00 2001 From: Rushikesh Garad Date: Fri, 11 Sep 2026 20:07:11 +0530 Subject: [PATCH 3/5] refactor: remove top-level src/rayon.rs (fixes #598) --- src/rayon.rs | 97 ---------------------------------------------------- 1 file changed, 97 deletions(-) delete mode 100644 src/rayon.rs diff --git a/src/rayon.rs b/src/rayon.rs deleted file mode 100644 index 2440f9f..0000000 --- a/src/rayon.rs +++ /dev/null @@ -1,97 +0,0 @@ -//! The code is heavily inspired by `rayon/vec.rs`, since it's exactly what we -//! need, except it's all private - -use { - crate::SmallVec, - core::{ - mem::take, - ptr::{ - self, - drop_in_place - }, - slice - }, - rayon::{ - iter::plumbing::{ - Producer, - UnindexedConsumer, - bridge_producer_consumer - }, - prelude::ParallelIterator - } -}; - -struct SliceDrain<'a, T>(slice::IterMut<'a, T>); - -impl Iterator for SliceDrain<'_, T> { - type Item = T; - - fn next(&mut self) -> Option { - self.0.next().map(|val| unsafe { ptr::read(val) }) - } -} - -impl DoubleEndedIterator for SliceDrain<'_, T> { - fn next_back(&mut self) -> Option { - self.0.next_back().map(|val| unsafe { ptr::read(val) }) - } -} - -impl ExactSizeIterator for SliceDrain<'_, T> { - fn len(&self) -> usize { - self.0.len() - } -} - -impl Drop for SliceDrain<'_, T> { - fn drop(&mut self) { - unsafe { drop_in_place(take(&mut self.0).into_slice()) }; - } -} - -struct DrainProducer<'a, T>(&'a mut [T]); - -impl<'a, T: Send> Producer for DrainProducer<'a, T> { - type IntoIter = SliceDrain<'a, T>; - type Item = T; - - fn into_iter(mut self) -> SliceDrain<'a, T> { - SliceDrain(take(&mut self.0).iter_mut()) - } - - fn split_at(mut self, index: usize) -> (Self, Self) { - let (left, right) = take(&mut self.0).split_at_mut(index); - - (DrainProducer(left), DrainProducer(right)) - } -} - -impl Drop for DrainProducer<'_, T> { - fn drop(&mut self) { - unsafe { drop_in_place(self.0) }; - } -} - -impl ParallelIterator for SmallVec { - type Item = T; - - fn drive_unindexed>(mut self, consumer: C) -> C::Result { - let len = self.len(); - - bridge_producer_consumer( - len, - DrainProducer(unsafe { - // SAFETY: set_len(0) is always valid - // All items will either be passed out or dropped by - // DrainProducer/SliceDrop, so there shouldn't - // be any possibility for leakage - self.set_len(0); - - // SAFETY: set_len didn't deallocate/drop the elements, so they - // are still valid. - slice::from_raw_parts_mut(self.as_mut_ptr(), len) - }), - consumer - ) - } -} From 8d78a1ab32f3ac1657f029986abfed7af4ae5706 Mon Sep 17 00:00:00 2001 From: Rushikesh Garad Date: Fri, 11 Sep 2026 20:07:13 +0530 Subject: [PATCH 4/5] refactor: update lib.rs to declare iterators module (closes #598) --- src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 511f58c..c414e22 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,8 +24,7 @@ mod macros; #[cfg(feature = "malloc_size_of")] mod mallocsizeof; mod rawsmallvec; -#[cfg(feature = "rayon")] -mod rayon; +mod iterators; mod references; #[cfg(feature = "serde")] mod serde; From 0a59d22b99d27450ab94489c79aeb9cab95aaf8d Mon Sep 17 00:00:00 2001 From: Alejandro Vaz Date: Fri, 11 Sep 2026 17:00:03 +0200 Subject: [PATCH 5/5] Remove duplicate module declaration for iterators Signed-off-by: Alejandro Vaz --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index c414e22..6197324 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,11 +20,11 @@ mod borsh; mod comparisons; mod conversions; mod errors; +mod iterators; mod macros; #[cfg(feature = "malloc_size_of")] mod mallocsizeof; mod rawsmallvec; -mod iterators; mod references; #[cfg(feature = "serde")] mod serde;