From 40eb93f8b4e64b36899eb5cc60d3f27448e4533d Mon Sep 17 00:00:00 2001 From: Josh Bowman-Matthews Date: Tue, 1 Sep 2026 11:03:34 -0400 Subject: [PATCH 1/2] Bump v1 to 1.16.0. Signed-off-by: Josh Bowman-Matthews --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 445f2880..b8a9062b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smallvec" -version = "1.15.2" +version = "1.16.0" edition = "2018" authors = ["The Servo Project Developers"] license = "MIT OR Apache-2.0" @@ -35,4 +35,4 @@ bincode1 = { package = "bincode", version = "1.0.1" } [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"] \ No newline at end of file +rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"] From 5ff80b56e218f29b9539aeeb89946697b92cc3d0 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 1 Sep 2026 11:12:51 -0400 Subject: [PATCH 2/2] Formatting. Signed-off-by: Josh Matthews --- src/lib.rs | 121 ++++++++++++++++++++++++++++----------------------- src/tests.rs | 4 +- 2 files changed, 69 insertions(+), 56 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f1191082..b0572e45 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -421,7 +421,8 @@ impl<'a, T: 'a + Array> Drop for Drain<'a, T> { let tail = self.tail_start; if tail != start { // as_mut_ptr creates a &mut, invalidating other pointers. - // This pattern avoids calling it with a pointer already present. + // This pattern avoids calling it with a pointer already + // present. let ptr = source_vec.as_mut_ptr(); let src = ptr.add(tail); let dst = ptr.add(start); @@ -492,9 +493,10 @@ where self.panic_flag = true; let drained = (self.pred)(&mut v[i]); self.panic_flag = false; - // Update the index *after* the predicate is called. If the index - // is updated prior and the predicate panics, the element at this - // index would be leaked. + // Update the index *after* the predicate is called. If the + // index is updated prior and the predicate + // panics, the element at this index would be + // leaked. self.idx += 1; if drained { self.del += 1; @@ -538,12 +540,15 @@ where fn drop(&mut self) { unsafe { if self.drain.idx < self.drain.old_len && self.drain.del > 0 { - // This is a pretty messed up state, and there isn't really an - // obviously right thing to do. We don't want to keep trying - // to execute `pred`, so we just backshift all the unprocessed - // elements and tell the vec that they still exist. The backshift - // is required to prevent a double-drop of the last successfully - // drained item prior to a panic in the predicate. + // This is a pretty messed up state, and there isn't + // really an obviously right + // thing to do. We don't want to keep trying + // to execute `pred`, so we just backshift all the + // unprocessed elements and tell + // the vec that they still exist. The backshift + // is required to prevent a double-drop of the last + // successfully drained item + // prior to a panic in the predicate. let ptr = self.drain.vec.as_mut_ptr(); let src = ptr.add(self.drain.idx); let dst = src.sub(self.drain.del); @@ -600,14 +605,14 @@ where // \_______/ ^-- idx // \-- del // - // Normally `Drop` impl would drop [tail] (via .for_each(drop), ie still calling - // `pred`) + // Normally `Drop` impl would drop [tail] (via .for_each(drop), ie still + // calling `pred`) // // 1. Move [tail] after [kept] - // 2. Update length of the original vec to `old_len - del` a. In case of ZST, - // this is the only thing we want to do - // 3. Do *not* drop self, as everything is put in a consistent state already, - // there is nothing to do + // 2. Update length of the original vec to `old_len - del` a. In case of + // ZST, this is the only thing we want to do + // 3. Do *not* drop self, as everything is put in a consistent state + // already, there is nothing to do let mut this = ManuallyDrop::new(self); unsafe { @@ -662,18 +667,19 @@ impl SmallVecData { } } // Workaround for https://github.com/rust-lang/rust/issues/157743: when from_inline is - // called with MaybeUninit::uninit(), rustc 1.93+ GVN propagates const - // into the ManuallyDrop::new() aggregate, causing LLVM to materialize a - // global constant that MemCpyOpt then collapses into a memset over the - // whole struct. Using assume_init() of a doubly-wrapped MaybeUninit - // produces Immediate::Uninit instead of const , which - // codegen handles as undef without emitting any global. This function also - // avoids introducing an intermediate local that would inflate stack frames - // in debug builds. + // called with MaybeUninit::uninit(), rustc 1.93+ GVN propagates const + // into the ManuallyDrop::new() aggregate, causing LLVM to + // materialize a global constant that MemCpyOpt then collapses into a + // memset over the whole struct. Using assume_init() of a doubly-wrapped + // MaybeUninit produces Immediate::Uninit instead of const , + // which codegen handles as undef without emitting any global. This + // function also avoids introducing an intermediate local that would + // inflate stack frames in debug builds. #[inline] fn empty() -> SmallVecData { - // SAFETY: ManuallyDrop> is valid for any bit pattern including - // uninitialized bytes, so assume_init() on a MaybeUninit of that type is sound. + // SAFETY: ManuallyDrop> is valid for any bit pattern + // including uninitialized bytes, so assume_init() on a + // MaybeUninit of that type is sound. SmallVecData { inline: unsafe { MaybeUninit::uninit().assume_init() }, } @@ -743,8 +749,9 @@ impl SmallVecData { // See the comment on the union variant's empty() for why this exists. #[inline] fn empty() -> SmallVecData { - // SAFETY: MaybeUninit is valid for any bit pattern including uninitialized - // bytes, so assume_init() on a MaybeUninit of that type is sound. + // SAFETY: MaybeUninit is valid for any bit pattern including + // uninitialized bytes, so assume_init() on a MaybeUninit of + // that type is sound. SmallVecData::Inline(unsafe { MaybeUninit::uninit().assume_init() }) } #[inline] @@ -969,17 +976,18 @@ impl SmallVec { if mem::size_of::() > 0 { A::size() } else { - // For zero-size items code like `ptr.add(offset)` always returns the same - // pointer. Therefore all items are at the same address, - // and any array size has capacity for infinitely many items. - // The capacity is limited by the bit width of the length field. + // For zero-size items code like `ptr.add(offset)` always returns + // the same pointer. Therefore all items are at the same + // address, and any array size has capacity for + // infinitely many items. The capacity is limited by the + // bit width of the length field. // // `Vec` also does this: // https://github.com/rust-lang/rust/blob/1.44.0/src/liballoc/raw_vec.rs#L186 // - // In our case, this also ensures that a smallvec of zero-size items never - // spills, and we never try to allocate zero bytes which - // `std::alloc::alloc` disallows. + // In our case, this also ensures that a smallvec of zero-size items + // never spills, and we never try to allocate zero bytes + // which `std::alloc::alloc` disallows. core::usize::MAX } } @@ -1304,8 +1312,8 @@ impl SmallVec { /// /// May reserve more space to avoid frequent reallocations. pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { - // prefer triple_mut() even if triple() would work so that the optimizer removes - // duplicated calls to it from callers. + // prefer triple_mut() even if triple() would work so that the optimizer + // removes duplicated calls to it from callers. let (_, &mut len, cap) = self.triple_mut(); if cap - len >= additional { return Ok(()); @@ -1469,7 +1477,8 @@ impl SmallVec { } let (lower_size_bound, _) = iter.size_hint(); - assert!(lower_size_bound <= core::isize::MAX as usize); // Ensure offset is indexable + assert!(lower_size_bound <= core::isize::MAX as usize); // Ensure offset + // is indexable assert!(index + lower_size_bound >= index); // Protect against overflow let mut num_added = 0; @@ -1485,8 +1494,8 @@ impl SmallVec { // Move the trailing elements. ptr::copy(ptr, ptr.add(lower_size_bound), old_len - index); - // In case the iterator panics, don't double-drop the items we just copied - // above. + // In case the iterator panics, don't double-drop the items we just + // copied above. self.set_len(0); let mut guard = DropOnPanic { start, @@ -1494,8 +1503,8 @@ impl SmallVec { len: old_len + lower_size_bound, }; - // The set_len above invalidates the previous pointers, so we must re-create - // them. + // The set_len above invalidates the previous pointers, so we must + // re-create them. let start = self.as_mut_ptr(); let ptr = start.add(index); @@ -1511,15 +1520,16 @@ impl SmallVec { } if num_added < lower_size_bound { - // Iterator provided fewer elements than the hint. Move the tail backward. + // Iterator provided fewer elements than the hint. Move the tail + // backward. ptr::copy( ptr.add(lower_size_bound), ptr.add(num_added), old_len - index, ); } - // There are no more duplicate or uninitialized slots, so the guard is not - // needed. + // There are no more duplicate or uninitialized slots, so the guard + // is not needed. self.set_len(old_len + num_added); mem::forget(guard); } @@ -2401,7 +2411,8 @@ impl IntoIterator for SmallVec { type Item = A::Item; fn into_iter(mut self) -> Self::IntoIter { unsafe { - // Set SmallVec len to zero as `IntoIter` drop handles dropping of the elements + // Set SmallVec len to zero as `IntoIter` drop handles dropping of + // the elements let len = self.len(); self.set_len(0); IntoIter { @@ -2613,11 +2624,12 @@ where let mut vec = SmallVec::with_capacity(len); if unty::type_equal::() { - // Initialize the smallvec's buffer. Note that we need to do this through - // the raw pointer as we cannot name the type [u8; N] even though A::Item is u8. + // Initialize the smallvec's buffer. Note that we need to do this + // through the raw pointer as we cannot name the type + // [u8; N] even though A::Item is u8. let ptr = vec.as_mut_ptr(); - // SAFETY: A::Item is u8 and the smallvec has been allocated with enough - // capacity + // SAFETY: A::Item is u8 and the smallvec has been allocated with + // enough capacity unsafe { core::ptr::write_bytes(ptr, 0, len); vec.set_len(len); @@ -2655,11 +2667,12 @@ where let mut vec = SmallVec::with_capacity(len); if unty::type_equal::() { - // Initialize the smallvec's buffer. Note that we need to do this through - // the raw pointer as we cannot name the type [u8; N] even though A::Item is u8. + // Initialize the smallvec's buffer. Note that we need to do this + // through the raw pointer as we cannot name the type + // [u8; N] even though A::Item is u8. let ptr = vec.as_mut_ptr(); - // SAFETY: A::Item is u8 and the smallvec has been allocated with enough - // capacity + // SAFETY: A::Item is u8 and the smallvec has been allocated with + // enough capacity unsafe { core::ptr::write_bytes(ptr, 0, len); vec.set_len(len); diff --git a/src/tests.rs b/src/tests.rs index 221a6735..e12ba9fa 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -657,8 +657,8 @@ fn test_into_iter_as_slice() { #[test] fn test_into_iter_clone() { - // Test that the cloned iterator yields identical elements and that it owns its - // own copy (i.e. no use after move errors). + // Test that the cloned iterator yields identical elements and that it owns + // its own copy (i.e. no use after move errors). let mut iter = SmallVec::<[u8; 2]>::from_iter(0..3).into_iter(); let mut clone_iter = iter.clone(); while let Some(x) = iter.next() {