From bab7b31cf574c99ed636e3ae0304985b3304b6ac Mon Sep 17 00:00:00 2001 From: Ankit-cs Date: Fri, 16 Oct 2026 11:02:29 +0530 Subject: [PATCH 1/2] refactor: deprecate as_slice and as_mut_slice in favor of AsRef/AsMut --- fuzz/fuzz_targets/main.rs | 4 ++-- src/comparisons.rs | 6 +++--- src/iterators/drain.rs | 15 ++++++++++++++- src/iterators/extractif.rs | 2 +- src/iterators/intoiter.rs | 38 ++++++++++++++++++++++++++++++++++++-- src/lib.rs | 10 +++++++++- src/references.rs | 19 +++++++++++++------ src/specialization.rs | 2 +- tests/main.rs | 22 ++++++++++++++++++++++ tests/zeroize.rs | 4 ++-- 10 files changed, 103 insertions(+), 19 deletions(-) diff --git a/fuzz/fuzz_targets/main.rs b/fuzz/fuzz_targets/main.rs index a8565278..1ca02359 100644 --- a/fuzz/fuzz_targets/main.rs +++ b/fuzz/fuzz_targets/main.rs @@ -89,9 +89,9 @@ fn assert_invariants( "`is_empty()` mismatch" ); assert_eq!( - small_vec.as_slice(), + small_vec.as_ref(), std_vec.as_slice(), - "`as_slice()` mismatch" + "`as_ref()` mismatch" ); // Capacity & spilling invariants diff --git a/src/comparisons.rs b/src/comparisons.rs index 79fc6090..bd8be173 100644 --- a/src/comparisons.rs +++ b/src/comparisons.rs @@ -46,7 +46,7 @@ where Item: PartialEq { #[inline] fn eq(&self, other: &SmallVec) -> bool { - let other = other.as_slice(); + let other = other.as_ref(); if self.len() != other.len() { return false; } @@ -63,7 +63,7 @@ where Item: PartialOrd { #[inline] fn partial_cmp(&self, other: &SmallVec) -> Option { - self.as_slice().partial_cmp(other.as_slice()) + self.as_ref().partial_cmp(other.as_ref()) } } @@ -72,6 +72,6 @@ where Item: Ord { #[inline] fn cmp(&self, other: &SmallVec) -> core::cmp::Ordering { - self.as_slice().cmp(other.as_slice()) + self.as_ref().cmp(other.as_ref()) } } diff --git a/src/iterators/drain.rs b/src/iterators/drain.rs index 655caf16..83732f65 100644 --- a/src/iterators/drain.rs +++ b/src/iterators/drain.rs @@ -156,10 +156,23 @@ impl<'valid, Item: 'valid, const INLINE: usize, Heap: Allocator> Drop } } +impl<'valid, Item, const INLINE: usize, Heap: Allocator> AsRef<[Item]> + for Drain<'valid, Item, INLINE, Heap> +{ + #[inline] + fn as_ref(&self) -> &[Item] { + self.iter.as_slice() + } +} + impl Drain<'_, Item, INLINE, Heap> { + #[deprecated( + since = "2.0.0-beta.3", + note = "use ` as AsRef<[Item]>>::as_ref` instead" + )] #[must_use] pub fn as_slice(&self) -> &[Item] { - self.iter.as_slice() + self.as_ref() } /// The range from `self.vec.length` to `self.tail_start` contains elements diff --git a/src/iterators/extractif.rs b/src/iterators/extractif.rs index a539592b..02d0be99 100644 --- a/src/iterators/extractif.rs +++ b/src/iterators/extractif.rs @@ -35,7 +35,7 @@ where { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_tuple("ExtractIf") - .field(&self.vec.as_slice()) + .field(&self.vec.as_ref()) .finish() } } diff --git a/src/iterators/intoiter.rs b/src/iterators/intoiter.rs index 1d305e37..4d13d017 100644 --- a/src/iterators/intoiter.rs +++ b/src/iterators/intoiter.rs @@ -47,7 +47,37 @@ unsafe impl Sync { } +impl AsRef<[Item]> for IntoIter { + #[inline] + fn as_ref(&self) -> &[Item] { + let (end, on_heap) = self.end.parts(); + // SAFETY: `end` tells which buffer is active, and the members in + // `self.begin..end` are all initialized. So the pointer arithmetic is + // valid, and so is the construction of the slice + unsafe { + let ptr = self.raw.as_ptr(on_heap); + core::slice::from_raw_parts(ptr.add(self.begin), end - self.begin) + } + } +} + +impl AsMut<[Item]> for IntoIter { + #[inline] + fn as_mut(&mut self) -> &mut [Item] { + let (end, on_heap) = self.end.parts(); + // SAFETY: see above + unsafe { + let ptr = self.raw.as_mut_ptr(on_heap); + core::slice::from_raw_parts_mut(ptr.add(self.begin), end - self.begin) + } + } +} + impl IntoIter { + #[deprecated( + since = "2.0.0-beta.3", + note = "use ` as AsRef<[Item]>>::as_ref` instead" + )] #[inline] pub const fn as_slice(&self) -> &[Item] { let (end, on_heap) = self.end.parts(); @@ -60,6 +90,10 @@ impl IntoIter { } } + #[deprecated( + since = "2.0.0-beta.3", + note = "use ` as AsMut<[Item]>>::as_mut` instead" + )] #[inline] pub const fn as_mut_slice(&mut self) -> &mut [Item] { let (end, on_heap) = self.end.parts(); @@ -165,7 +199,7 @@ impl Clone allocator: self.allocator.clone() }; - vec.extend(self.as_slice()); + vec.extend(self.as_ref()); vec.into_iter() } @@ -194,6 +228,6 @@ impl IntoIterator for SmallVec Debug for IntoIter { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_tuple("IntoIter").field(&self.as_slice()).finish() + f.debug_tuple("IntoIter").field(&self.as_ref()).finish() } } diff --git a/src/lib.rs b/src/lib.rs index a1e4bae5..008c2fcb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -970,6 +970,10 @@ impl SmallVec { unsafe { &mut *ptr } } + #[deprecated( + since = "2.0.0-beta.3", + note = "use ` as AsRef<[Item]>>::as_ref` instead" + )] #[inline] pub const fn as_slice(&self) -> &[Item] { let (length, on_heap) = self.length.parts(); @@ -977,6 +981,10 @@ impl SmallVec { unsafe { core::slice::from_raw_parts(self.raw.as_ptr(on_heap), length) } } + #[deprecated( + since = "2.0.0-beta.3", + note = "use ` as AsMut<[Item]>>::as_mut` instead" + )] #[inline] pub const fn as_mut_slice(&mut self) -> &mut [Item] { let (length, on_heap) = self.length.parts(); @@ -1817,7 +1825,7 @@ impl<'valid, Item, const INLINE: usize, Heap: Allocator> IntoIterator impl Hash for SmallVec { fn hash(&self, state: &mut H) { - self.as_slice().hash(state) + self.as_ref().hash(state) } } diff --git a/src/references.rs b/src/references.rs index 462ca1f6..e278baaa 100644 --- a/src/references.rs +++ b/src/references.rs @@ -18,28 +18,34 @@ use { impl Borrow<[Item]> for SmallVec { #[inline] fn borrow(&self) -> &[Item] { - self.as_slice() + self.as_ref() } } + impl BorrowMut<[Item]> for SmallVec { #[inline] fn borrow_mut(&mut self) -> &mut [Item] { - self.as_mut_slice() + self.as_mut() } } impl AsRef<[Item]> for SmallVec { #[inline] fn as_ref(&self) -> &[Item] { - self.as_slice() + let (length, on_heap) = self.length.parts(); + // SAFETY: all the elements in `..length` are initialized + unsafe { core::slice::from_raw_parts(self.raw.as_ptr(on_heap), length) } } } + impl AsMut<[Item]> for SmallVec { #[inline] fn as_mut(&mut self) -> &mut [Item] { - self.as_mut_slice() + let (length, on_heap) = self.length.parts(); + // SAFETY: see above + unsafe { core::slice::from_raw_parts_mut(self.raw.as_mut_ptr(on_heap), length) } } } @@ -48,12 +54,13 @@ impl Deref for SmallVec &Self::Target { - self.as_slice() + self.as_ref() } } + impl DerefMut for SmallVec { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { - self.as_mut_slice() + self.as_mut() } } diff --git a/src/specialization.rs b/src/specialization.rs index ced0487f..11041b30 100644 --- a/src/specialization.rs +++ b/src/specialization.rs @@ -112,7 +112,7 @@ impl SpecExtend> for SmallVec { fn spec_extend(&mut self, mut iter: IntoIter) { - let slice = iter.as_slice(); + let slice = iter.as_ref(); let length = slice.len(); let old_len = self.len(); diff --git a/tests/main.rs b/tests/main.rs index 35c3b12a..dc412596 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -710,6 +710,7 @@ fn exact_size_iterator() { } #[test] +#[allow(deprecated)] fn into_iter_as_slice() { let vec = SmallVec::::from(&[1, 2, 3][..]); let mut iter = vec.clone().into_iter(); @@ -723,6 +724,27 @@ fn into_iter_as_slice() { assert_eq!(iter.as_mut_slice(), &[2]); } +#[test] +fn into_iter_as_ref() { + let vec = SmallVec::::from(&[1, 2, 3][..]); + let mut iter = vec.clone().into_iter(); + assert_eq!(iter.as_ref(), &[1, 2, 3]); + assert_eq!(iter.as_mut(), &[1, 2, 3]); + iter.next(); + assert_eq!(iter.as_ref(), &[2, 3]); + assert_eq!(iter.as_mut(), &[2, 3]); + iter.next_back(); + assert_eq!(iter.as_ref(), &[2]); + assert_eq!(iter.as_mut(), &[2]); +} + +#[test] +fn drain_as_ref() { + let mut vec = SmallVec::::from(&[1, 2, 3, 4][..]); + let drain = vec.drain(1..3); + assert_eq!(drain.as_ref(), &[2, 3]); +} + #[test] fn into_iter_clone() { // Test that the cloned iterator yields identical elements and that it owns diff --git a/tests/zeroize.rs b/tests/zeroize.rs index 85cd76f6..6960d840 100644 --- a/tests/zeroize.rs +++ b/tests/zeroize.rs @@ -25,7 +25,7 @@ fn zeroize_inline() { // It is still usable. v.extend_from_slice(&[1, 2, 3]); - assert_eq!(v.as_slice(), &[1, 2, 3]); + assert_eq!(v.as_ref(), &[1, 2, 3]); } #[test] @@ -42,7 +42,7 @@ fn zeroize_spilled() { assert_fully_zeroed(&mut v); v.extend_from_slice(&[10, 11]); - assert_eq!(v.as_slice(), &[10, 11]); + assert_eq!(v.as_ref(), &[10, 11]); } #[test] From 4827e306b75d9c0dd1a58477bf027bbe1cfaef01 Mon Sep 17 00:00:00 2001 From: Ankit-cs Date: Fri, 16 Oct 2026 22:14:36 +0530 Subject: [PATCH 2/2] refactor: simplify deprecated slice methods to delegate to AsRef and AsMut --- src/iterators/intoiter.rs | 20 ++++---------------- src/lib.rs | 12 ++++-------- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/iterators/intoiter.rs b/src/iterators/intoiter.rs index 4d13d017..a2bea0bf 100644 --- a/src/iterators/intoiter.rs +++ b/src/iterators/intoiter.rs @@ -79,15 +79,8 @@ impl IntoIter { note = "use ` as AsRef<[Item]>>::as_ref` instead" )] #[inline] - pub const fn as_slice(&self) -> &[Item] { - let (end, on_heap) = self.end.parts(); - // SAFETY: `end` tells which buffer is active, and the members in - // `self.begin..end` are all initialized. So the pointer arithmetic is - // valid, and so is the construction of the slice - unsafe { - let ptr = self.raw.as_ptr(on_heap); - core::slice::from_raw_parts(ptr.add(self.begin), end - self.begin) - } + pub fn as_slice(&self) -> &[Item] { + self.as_ref() } #[deprecated( @@ -95,13 +88,8 @@ impl IntoIter { note = "use ` as AsMut<[Item]>>::as_mut` instead" )] #[inline] - pub const fn as_mut_slice(&mut self) -> &mut [Item] { - let (end, on_heap) = self.end.parts(); - // SAFETY: see above - unsafe { - let ptr = self.raw.as_mut_ptr(on_heap); - core::slice::from_raw_parts_mut(ptr.add(self.begin), end - self.begin) - } + pub fn as_mut_slice(&mut self) -> &mut [Item] { + self.as_mut() } #[cfg(feature = "specialization")] diff --git a/src/lib.rs b/src/lib.rs index 008c2fcb..fa03ac5e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -975,10 +975,8 @@ impl SmallVec { note = "use ` as AsRef<[Item]>>::as_ref` instead" )] #[inline] - pub const fn as_slice(&self) -> &[Item] { - let (length, on_heap) = self.length.parts(); - // SAFETY: all the elements in `..length` are initialized - unsafe { core::slice::from_raw_parts(self.raw.as_ptr(on_heap), length) } + pub fn as_slice(&self) -> &[Item] { + self.as_ref() } #[deprecated( @@ -986,10 +984,8 @@ impl SmallVec { note = "use ` as AsMut<[Item]>>::as_mut` instead" )] #[inline] - pub const fn as_mut_slice(&mut self) -> &mut [Item] { - let (length, on_heap) = self.length.parts(); - // SAFETY: see above - unsafe { core::slice::from_raw_parts_mut(self.raw.as_mut_ptr(on_heap), length) } + pub fn as_mut_slice(&mut self) -> &mut [Item] { + self.as_mut() } #[inline]