From 0c148eb3707878daa00934a94c57093553aab8a1 Mon Sep 17 00:00:00 2001 From: Alejandro Vaz Date: Sat, 29 Aug 2026 02:12:26 +0200 Subject: [PATCH 1/8] feat: added defmt for smallvec --- Cargo.lock | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 11 +++++------ src/defmt.rs | 15 +++++++++++++++ src/lib.rs | 2 ++ 4 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 src/defmt.rs diff --git a/Cargo.lock b/Cargo.lock index cc011d5..664064d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -179,6 +179,37 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + [[package]] name = "either" version = "1.18.0" @@ -502,6 +533,7 @@ version = "2.0.0-alpha.12" dependencies = [ "bytes", "criterion", + "defmt", "malloc_size_of", "serde_core", "serde_test", @@ -535,6 +567,26 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" +[[package]] +name = "thiserror" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + [[package]] name = "tinytemplate" version = "1.2.1" diff --git a/Cargo.toml b/Cargo.toml index 912a2ed..135a24f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,6 @@ repository = "https://github.com/servo/rust-smallvec" description = "'Small vector' optimization: store up to a small number of items on the stack" keywords = ["small", "vec", "vector", "stack", "no_std"] categories = ["data-structures"] -readme = "README.md" -documentation = "https://docs.rs/smallvec/" exclude = [".gitignore", "tests/", "fuzz/", "benches/", ".github/"] [features] @@ -21,13 +19,14 @@ serde = ["dep:serde_core"] internals = [] [dependencies] -bytes = { version = "1", optional = true, default-features = false } -serde_core = { version = "1.0.221", optional = true, default-features = false } -malloc_size_of = { version = "0.1.1", optional = true, default-features = false } +bytes = { version = "1.12", optional = true, default-features = false } +defmt = { version = "1.1", optional = true, default-features = false} +serde_core = { version = "1.0", optional = true, default-features = false } +malloc_size_of = { version = "0.1", optional = true, default-features = false } [dev-dependencies] serde_test = "1.0" -criterion = "0.4.0" +criterion = "0.4" [[bench]] name = "bench" diff --git a/src/defmt.rs b/src/defmt.rs new file mode 100644 index 0000000..645ffbb --- /dev/null +++ b/src/defmt.rs @@ -0,0 +1,15 @@ +use defmt::Format; +use defmt::Formatter; +use defmt::write; +use super::SmallVec; + +impl Format for SmallVec { + fn format(&self, fmt: Formatter) { + write!(fmt, "["); + for (index, element) in self.iter().enumerate() { + if index != 0 {write!(fmt, ", ")} + write!(fmt, "{:?}", element); + } + write!(fmt, "]"); + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index af12044..75b0477 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,6 +65,8 @@ pub extern crate alloc; #[cfg(any(test, feature = "std"))] extern crate std; +#[cfg(feature = "defmt")] +mod defmt; mod rawsmallvec; #[cfg(test)] mod tests; From 9ca7b9f61f4ec7900872e812ac59d8ec59ad930a Mon Sep 17 00:00:00 2001 From: Alejandro Vaz Date: Sat, 29 Aug 2026 02:12:49 +0200 Subject: [PATCH 2/8] fix: ran formatter --- src/defmt.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/defmt.rs b/src/defmt.rs index 645ffbb..4684e64 100644 --- a/src/defmt.rs +++ b/src/defmt.rs @@ -1,15 +1,17 @@ +use super::SmallVec; +use defmt::write; use defmt::Format; use defmt::Formatter; -use defmt::write; -use super::SmallVec; impl Format for SmallVec { fn format(&self, fmt: Formatter) { write!(fmt, "["); for (index, element) in self.iter().enumerate() { - if index != 0 {write!(fmt, ", ")} + if index != 0 { + write!(fmt, ", ") + } write!(fmt, "{:?}", element); } write!(fmt, "]"); } -} \ No newline at end of file +} From b43f14b9e3b0dc863727426db4c7b2254773b605 Mon Sep 17 00:00:00 2001 From: Alejandro Vaz Date: Sat, 29 Aug 2026 04:05:52 +0200 Subject: [PATCH 3/8] refactor: removed API boundary --- src/defmt.rs | 17 ----------------- src/lib.rs | 22 ++++++++++++++++++++-- 2 files changed, 20 insertions(+), 19 deletions(-) delete mode 100644 src/defmt.rs diff --git a/src/defmt.rs b/src/defmt.rs deleted file mode 100644 index 4684e64..0000000 --- a/src/defmt.rs +++ /dev/null @@ -1,17 +0,0 @@ -use super::SmallVec; -use defmt::write; -use defmt::Format; -use defmt::Formatter; - -impl Format for SmallVec { - fn format(&self, fmt: Formatter) { - write!(fmt, "["); - for (index, element) in self.iter().enumerate() { - if index != 0 { - write!(fmt, ", ") - } - write!(fmt, "{:?}", element); - } - write!(fmt, "]"); - } -} diff --git a/src/lib.rs b/src/lib.rs index 75b0477..48bb808 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,8 +65,6 @@ pub extern crate alloc; #[cfg(any(test, feature = "std"))] extern crate std; -#[cfg(feature = "defmt")] -mod defmt; mod rawsmallvec; #[cfg(test)] mod tests; @@ -102,6 +100,12 @@ use serde_core::{ }; #[cfg(feature = "std")] use std::io; +#[cfg(feature = "defmt")] +use defmt::{ + Format, + write, + Formatter +}; /// Error type for APIs with fallible heap allocation #[derive(Debug)] @@ -3130,3 +3134,17 @@ unsafe impl BufMut for SmallVec { self.resize(new_len, val); } } + +#[cfg(feature = "defmt")] +impl Format for SmallVec { + fn format(&self, fmt: Formatter) { + write!(fmt, "["); + for (index, element) in self.iter().enumerate() { + if index != 0 { + write!(fmt, ", ") + } + write!(fmt, "{:?}", element); + } + write!(fmt, "]"); + } +} From 13b3a94585eabd225ebecb488f6b2953c7a6bdf9 Mon Sep 17 00:00:00 2001 From: Alejandro Vaz Date: Sat, 29 Aug 2026 04:08:29 +0200 Subject: [PATCH 4/8] fix: ran formatter --- src/lib.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 48bb808..1af6c2f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -87,6 +87,8 @@ use core::mem::MaybeUninit; use core::ptr::copy; use core::ptr::copy_nonoverlapping; use core::ptr::NonNull; +#[cfg(feature = "defmt")] +use defmt::{write, Format, Formatter}; #[cfg(feature = "malloc_size_of")] use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps}; #[cfg(feature = "internals")] @@ -100,12 +102,6 @@ use serde_core::{ }; #[cfg(feature = "std")] use std::io; -#[cfg(feature = "defmt")] -use defmt::{ - Format, - write, - Formatter -}; /// Error type for APIs with fallible heap allocation #[derive(Debug)] From 7fa85c2d91447cd98cf4e99bb526cbdee74262a5 Mon Sep 17 00:00:00 2001 From: Alejandro Vaz Date: Sat, 29 Aug 2026 04:12:23 +0200 Subject: [PATCH 5/8] fix: renamed imports to avoid namespace conflicts --- src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1af6c2f..1e46292 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,7 +88,7 @@ use core::ptr::copy; use core::ptr::copy_nonoverlapping; use core::ptr::NonNull; #[cfg(feature = "defmt")] -use defmt::{write, Format, Formatter}; +use defmt::{write as dewrite, Format, Formatter as DeFormatter}; #[cfg(feature = "malloc_size_of")] use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps}; #[cfg(feature = "internals")] @@ -3133,14 +3133,14 @@ unsafe impl BufMut for SmallVec { #[cfg(feature = "defmt")] impl Format for SmallVec { - fn format(&self, fmt: Formatter) { - write!(fmt, "["); + fn format(&self, fmt: DeFormatter) { + dewrite!(fmt, "["); for (index, element) in self.iter().enumerate() { if index != 0 { - write!(fmt, ", ") + dewrite!(fmt, ", ") } - write!(fmt, "{:?}", element); + dewrite!(fmt, "{:?}", element); } - write!(fmt, "]"); + dewrite!(fmt, "]"); } } From 7e477f62e089c6829315a033e0930f3d52ecbc9f Mon Sep 17 00:00:00 2001 From: Alejandro Vaz Date: Sat, 29 Aug 2026 12:08:23 +0200 Subject: [PATCH 6/8] refactor: simplified format for smallvec --- src/lib.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1e46292..657b48e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3134,13 +3134,6 @@ unsafe impl BufMut for SmallVec { #[cfg(feature = "defmt")] impl Format for SmallVec { fn format(&self, fmt: DeFormatter) { - dewrite!(fmt, "["); - for (index, element) in self.iter().enumerate() { - if index != 0 { - dewrite!(fmt, ", ") - } - dewrite!(fmt, "{:?}", element); - } - dewrite!(fmt, "]"); + dewrite!(fmt, "{=[?]}", self.as_ref()); } } From 6501a0f32f34aa123f7e23afe375635e5644b643 Mon Sep 17 00:00:00 2001 From: Alejandro Vaz Date: Sun, 30 Aug 2026 15:05:50 +0200 Subject: [PATCH 7/8] fix: style formatting --- src/lib.rs | 200 +++++++++++++++++++++++++-------------------- tests/arbitrary.rs | 3 +- tests/main.rs | 8 +- 3 files changed, 119 insertions(+), 92 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 03d4488..778de19 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -192,9 +192,9 @@ impl RawSmallVec { #[inline] const fn as_ptr_inline(&self) -> *const T { - // SAFETY: it is safe because we aren't reading the value, just getting a - // reference to it. reading it would be UB potentially, but for that downstream - // unsafe is required + // SAFETY: it is safe because we aren't reading the value, just getting + // a reference to it. reading it would be UB potentially, but + // for that downstream unsafe is required (unsafe { &raw const self.inline }) as *mut T } @@ -250,7 +250,8 @@ impl RawSmallVec { let new_ptr = if !was_on_heap { // get a fresh allocation - let new_ptr = alloc(new_layout) as *mut T; // `new_layout` has nonzero size. + let new_ptr = alloc(new_layout) as *mut T; // `new_layout` has + // nonzero size. let new_ptr = NonNull::new(new_ptr).ok_or(CollectionAllocErr::AllocErr { layout: new_layout })?; copy_nonoverlapping(ptr, new_ptr.as_ptr(), len); @@ -258,15 +259,16 @@ impl RawSmallVec { } else { // use realloc - // this can't overflow since we already constructed an equivalent layout during - // the previous allocation + // this can't overflow since we already constructed an equivalent + // layout during the previous allocation let old_layout = Layout::from_size_align_unchecked(self.heap.1 * size_of::(), align_of::()); // SAFETY: ptr was allocated with this allocator - // old_layout is the same as the layout used to allocate the previous memory - // block new_layout.size() is greater than zero - // does not overflow when rounded up to alignment. since it was constructed + // old_layout is the same as the layout used to allocate the + // previous memory block new_layout.size() is greater + // than zero does not overflow when rounded up to + // alignment. since it was constructed // with Layout::array let new_ptr = realloc(ptr as *mut u8, old_layout, new_layout.size()) as *mut T; NonNull::new(new_ptr).ok_or(CollectionAllocErr::AllocErr { layout: new_layout })? @@ -379,8 +381,8 @@ impl<'a, T: 'a, const N: usize> Iterator for Drain<'a, T, N> { #[inline] fn next(&mut self) -> Option { - // SAFETY: we shrunk the length of the vector so it no longer owns these items, - // and we can take ownership of them. + // SAFETY: we shrunk the length of the vector so it no longer owns these + // items, and we can take ownership of them. self.iter .next() .map(|reference| unsafe { core::ptr::read(reference) }) @@ -442,9 +444,10 @@ impl<'a, T: 'a, const N: usize> Drop for Drain<'a, T, N> { let mut vec = self.vec; if SmallVec::::IS_ZST { - // ZSTs have no identity, so we don't need to move them around, we only need to - // drop the correct amount. this can be achieved by manipulating the - // Vec length instead of moving values out from `iter`. + // ZSTs have no identity, so we don't need to move them around, we + // only need to drop the correct amount. this can be + // achieved by manipulating the Vec length instead of + // moving values out from `iter`. unsafe { let vec = vec.as_mut(); let old_len = vec.len(); @@ -455,8 +458,8 @@ impl<'a, T: 'a, const N: usize> Drop for Drain<'a, T, N> { return; } - // ensure elements are moved back into their appropriate places, even when - // drop_in_place panics + // ensure elements are moved back into their appropriate places, even + // when drop_in_place panics let _guard = DropGuard(self); if drop_len == 0 { @@ -464,20 +467,23 @@ impl<'a, T: 'a, const N: usize> Drop for Drain<'a, T, N> { } // as_slice() must only be called when iter.len() is > 0 because - // it also gets touched by vec::Splice which may turn it into a dangling pointer - // which would make it and the vec pointer point to different allocations which - // would lead to invalid pointer arithmetic below. + // it also gets touched by vec::Splice which may turn it into a dangling + // pointer which would make it and the vec pointer point to + // different allocations which would lead to invalid pointer + // arithmetic below. let drop_ptr = iter.as_slice().as_ptr(); unsafe { - // drop_ptr comes from a slice::Iter which only gives us a &[T] but for - // drop_in_place a pointer with mutable provenance is necessary. - // Therefore we must reconstruct it from the original vec but also - // avoid creating a &mut to the front since that could invalidate - // raw pointers to it which some unsafe code might rely on. + // drop_ptr comes from a slice::Iter which only gives us a &[T] but + // for drop_in_place a pointer with mutable provenance + // is necessary. Therefore we must reconstruct it from + // the original vec but also avoid creating a &mut to + // the front since that could invalidate raw pointers to + // it which some unsafe code might rely on. let vec_ptr = vec.as_mut().as_mut_ptr(); - // May be replaced with the line below later, once this crate's MSRV is >= 1.87. - //let drop_offset = drop_ptr.offset_from_unsigned(vec_ptr); + // May be replaced with the line below later, once this crate's MSRV + // is >= 1.87. let drop_offset = + // drop_ptr.offset_from_unsigned(vec_ptr); let drop_offset = drop_ptr.offset_from(vec_ptr) as usize; let to_drop = core::ptr::slice_from_raw_parts_mut(vec_ptr.add(drop_offset), drop_len); core::ptr::drop_in_place(to_drop); @@ -588,9 +594,10 @@ where let i = self.idx; let v = core::slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); let drained = (self.pred)(&mut v[i]); - // 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; @@ -621,8 +628,9 @@ where // 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 + // 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.vec.as_mut_ptr(); let src = ptr.add(self.idx); @@ -673,11 +681,12 @@ impl ExactSizeIterator for Splice<'_, I, N> {} impl Drop for Splice<'_, I, N> { fn drop(&mut self) { self.drain.by_ref().for_each(drop); - // At this point draining is done and the only remaining tasks are splicing - // and moving things into the final place. - // Which means we can replace the slice::Iter with pointers that won't point to - // deallocated memory, so that Drain::drop is still allowed to call - // iter.len(), otherwise it would break the ptr.sub_ptr contract. + // At this point draining is done and the only remaining tasks are + // splicing and moving things into the final place. + // Which means we can replace the slice::Iter with pointers that won't + // point to deallocated memory, so that Drain::drop is still + // allowed to call iter.len(), otherwise it would break the + // ptr.sub_ptr contract. self.drain.iter = [].iter(); unsafe { @@ -767,8 +776,9 @@ impl IntoIter { #[inline] pub const fn as_slice(&self) -> &[T] { - // SAFETY: The members in self.begin..self.end.value() are all initialized - // So the pointer arithmetic is valid, and so is the construction of the slice + // SAFETY: The members in self.begin..self.end.value() are all + // initialized So the pointer arithmetic is valid, and so is the + // construction of the slice unsafe { let ptr = self.as_ptr(); core::slice::from_raw_parts(ptr.add(self.begin), self.end.value() - self.begin) @@ -857,9 +867,9 @@ impl SmallVec { assert!(S <= N); } - // Although we create a new buffer, since S and N are known at compile time, - // even with `-C opt-level=1`, it gets optimized as best as it could be. - // (Checked with ) + // Although we create a new buffer, since S and N are known at compile + // time, even with `-C opt-level=1`, it gets optimized as best + // as it could be. (Checked with ) let mut buf: MaybeUninit<[T; N]> = MaybeUninit::uninit(); // SAFETY: buf and elements do not overlap, are aligned and have space @@ -891,12 +901,13 @@ impl SmallVec { }; // Deallocate the remaining elements so no memory is leaked. unsafe { - // SAFETY: both the input and output pointers are in range of the stack - // allocation + // SAFETY: both the input and output pointers are in range of the + // stack allocation let remainder_ptr = vec.raw.as_mut_ptr_inline().add(len); let remainder_len = N - len; - // SAFETY: the values are initialized, so dropping them here is fine. + // SAFETY: the values are initialized, so dropping them here is + // fine. core::ptr::drop_in_place(core::ptr::slice_from_raw_parts_mut( remainder_ptr, remainder_len, @@ -946,15 +957,17 @@ impl SmallVec { } if Self::IS_ZST { - // "Move" elements to stack buffer. They're ZST so we don't actually have to do - // anything. Just make sure they're not dropped. - // We don't wrap the vector in ManuallyDrop so that when it's dropped, the - // memory is deallocated, if it needs to be. + // "Move" elements to stack buffer. They're ZST so we don't actually + // have to do anything. Just make sure they're not + // dropped. We don't wrap the vector in ManuallyDrop so + // that when it's dropped, the memory is deallocated, if + // it needs to be. let mut vec = vec; let len = vec.len(); // SAFETY: `0` is less than the vector's capacity. - // old_len..new_len is an empty range. So there are no uninitialized elements + // old_len..new_len is an empty range. So there are no uninitialized + // elements unsafe { vec.set_len(0) }; Self { len: TaggedLen::new(len, false), @@ -1254,15 +1267,15 @@ impl SmallVec { // SAFETY: `len < capacity` after the reserve, // so the offset stays in bounds of the allocation. let ptr = unsafe { self.as_mut_ptr().add(len) }; - // SAFETY: we allocated enough space in case it wasn't enough, so the address is - // valid for writes. + // SAFETY: we allocated enough space in case it wasn't enough, so the + // address is valid for writes. unsafe { ptr.write(value) }; // LEGAL: all elements in `0..len + 1` are initialized. { // This block is an exact copy of `self.set_len`. - // We have to do this so that Miri doesn't report a "Stacked Borrows" - // rule violation. See PR/406 + // We have to do this so that Miri doesn't report a "Stacked + // Borrows" rule violation. See PR/406 let new_len = len + 1; debug_assert!(new_len <= self.capacity()); @@ -1270,8 +1283,9 @@ impl SmallVec { self.len = TaggedLen::new(new_len, on_heap); } - // SAFETY: `ptr` is aligned, non-null and points to the element initialized - // above; the borrow is tied to `&mut self`, so it is exclusive. + // SAFETY: `ptr` is aligned, non-null and points to the element + // initialized above; the borrow is tied to `&mut self`, + // so it is exclusive. unsafe { &mut *ptr } } @@ -1284,8 +1298,8 @@ impl SmallVec { let new_len = len - 1; // SAFETY: new_len < len since len is non-zero unsafe { self.set_len(new_len) }; - // SAFETY: this element was initialized and we just gave up ownership of it, so - // we can give it away + // SAFETY: this element was initialized and we just gave up ownership of + // it, so we can give it away let value = unsafe { self.as_mut_ptr().add(new_len).read() }; Some(value) } @@ -1302,8 +1316,8 @@ impl SmallVec { #[inline] pub fn append(&mut self, other: &mut SmallVec) { - // can't overflow since both are smaller than isize::MAX and 2 * isize::MAX < - // usize::MAX + // can't overflow since both are smaller than isize::MAX and 2 * + // isize::MAX < usize::MAX let len = self.len(); let other_len = other.len(); let total_len = len + other_len; @@ -1314,8 +1328,8 @@ impl SmallVec { // SAFETY: see `Self::push` let ptr = unsafe { self.as_mut_ptr().add(len) }; unsafe { other.set_len(0) } - // SAFETY: we have a mutable reference to each vector and each uniquely owns its - // memory. so the ranges can't overlap + // SAFETY: we have a mutable reference to each vector and each uniquely + // owns its memory. so the ranges can't overlap unsafe { copy_nonoverlapping(other.as_ptr(), ptr, other_len) }; unsafe { self.set_len(total_len) } } @@ -1339,7 +1353,8 @@ impl SmallVec { let result = unsafe { self.raw.try_grow_raw(self.len, new_capacity) }; if result.is_ok() { - // SAFETY: the allocation succeeded, so self.raw.heap is now active + // SAFETY: the allocation succeeded, so self.raw.heap is now + // active unsafe { self.set_on_heap() }; } result @@ -1570,9 +1585,9 @@ impl SmallVec { if index < len { // SAFETY: `reserve(1)` guarantees capacity for `len + 1` elements, - // so shifting `len - index` elements one slot up stays in bounds. - // Source and destination overlap, hence `copy` instead of - // `copy_nonoverlapping`. + // so shifting `len - index` elements one slot up stays in + // bounds. Source and destination overlap, hence + // `copy` instead of `copy_nonoverlapping`. unsafe { copy(ptr, ptr.add(1), len - index) }; } @@ -1582,8 +1597,8 @@ impl SmallVec { // LEGAL: all elements in `0..len + 1` are initialized. { // This block is an exact copy of `self.set_len`. - // We have to do this so that Miri doesn't report a "Stacked Borrows" - // rule violation. See PR/406 + // We have to do this so that Miri doesn't report a "Stacked + // Borrows" rule violation. See PR/406 let new_len = len + 1; debug_assert!(new_len <= self.capacity()); @@ -1591,8 +1606,9 @@ impl SmallVec { self.len = TaggedLen::new(new_len, on_heap); } - // SAFETY: `ptr` is aligned, non-null and points to the element initialized - // above; the borrow is tied to `&mut self`, so it is exclusive. + // SAFETY: `ptr` is aligned, non-null and points to the element + // initialized above; the borrow is tied to `&mut self`, + // so it is exclusive. unsafe { &mut *ptr } } @@ -1638,9 +1654,10 @@ impl SmallVec { if !self.spilled() { let mut vec = Vec::with_capacity(len); let this = ManuallyDrop::new(self); - // SAFETY: we create a new vector with sufficient capacity, copy our elements - // into it to transfer ownership and then set the length - // we don't drop the elements we previously held + // SAFETY: we create a new vector with sufficient capacity, copy our + // elements into it to transfer ownership and then set + // the length we don't drop the elements we previously + // held unsafe { copy_nonoverlapping(this.raw.as_ptr_inline(), vec.as_mut_ptr(), len); vec.set_len(len); @@ -1676,7 +1693,8 @@ impl SmallVec { if self.len() != N { Err(self) } else { - // when `this` is dropped, the memory is released if it's on the heap. + // when `this` is dropped, the memory is released if it's on the + // heap. let mut this = self; // SAFETY: we release ownership of the elements we hold unsafe { @@ -1916,8 +1934,9 @@ impl SmallVec { let src = slice_range(src, ..self.len()); self.reserve(src.len()); - // SAFETY: The call to `reserve` ensures that the capacity is large enough. - // The range is within bounds through the use of `core::slice::range`. + // SAFETY: The call to `reserve` ensures that the capacity is large + // enough. The range is within bounds through the use of + // `core::slice::range`. unsafe { #[cfg(feature = "specialization")] { @@ -1961,8 +1980,9 @@ impl SmallVec { let len = end - start; self.reserve(len); - // SAFETY: The call to `reserve` ensures that the capacity is large enough. - // The range is within bounds through the use of `core::slice::range`. + // SAFETY: The call to `reserve` ensures that the capacity is large + // enough. The range is within bounds through the use of + // `core::slice::range`. unsafe { let l = self.len(); let ptr = self.as_mut_ptr(); @@ -1983,7 +2003,8 @@ impl SmallVec { let base_ptr = self.as_mut_ptr(); let ith_ptr = base_ptr.add(index); let shifted_ptr = base_ptr.add(index + len); - // elements at `index + other_len..len + other_len` are now initialized + // elements at `index + other_len..len + other_len` are now + // initialized copy(ith_ptr, shifted_ptr, l - index); // elements at `index..index + other_len` are now initialized copy_nonoverlapping(other.as_ptr(), ith_ptr, len); @@ -2003,7 +2024,8 @@ impl SmallVec { let len = slice.len(); let mut result = Self::with_capacity(len); - // SAFETY: By using `with_capacity`, the pointer will point to valid memory. + // SAFETY: By using `with_capacity`, the pointer will point to valid + // memory. unsafe { let dst = result.as_mut_ptr(); copy_nonoverlapping(src, dst, len); @@ -2143,13 +2165,15 @@ pub fn from_elem(elem: T, n: usize) -> SmallVec } else { #[cfg(feature = "specialization")] { - // SAFETY: The precondition is checked in the initial comparison above. + // SAFETY: The precondition is checked in the initial comparison + // above. unsafe { as spec_traits::SpecFromElem>::spec_from_elem(elem, n) } } #[cfg(not(feature = "specialization"))] { - // SAFETY: The precondition is checked in the initial comparison above. + // SAFETY: The precondition is checked in the initial comparison + // above. unsafe { SmallVec::::from_elem_fallback(elem, n) } } } @@ -2351,8 +2375,8 @@ mod spec_traits { let len = src.len(); // SAFETY: The caller ensures that the vector has spare capacity - // for at least `src.len()` elements. This is also the amount of memory - // accessed when the data is copied. + // for at least `src.len()` elements. This is also the amount of + // memory accessed when the data is copied. unsafe { let ptr = self.as_mut_ptr(); let dst = ptr.add(old_len); @@ -2635,7 +2659,8 @@ impl From<&[T]> for SmallVec { // Standard Rust vectors are already specialized. Self::from_vec(Vec::from(slice)) } else { - // SAFETY: The precondition is checked in the initial comparison above. + // SAFETY: The precondition is checked in the initial comparison + // above. unsafe { #[cfg(feature = "specialization")] { @@ -2816,10 +2841,11 @@ impl IntoIterator for SmallVec { type IntoIter = IntoIter; type Item = T; fn into_iter(self) -> Self::IntoIter { - // SAFETY: we move out of this.raw by reading the value at its address, which is - // fine since we don't drop it + // SAFETY: we move out of this.raw by reading the value at its address, + // which is fine since we don't drop it 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 this = ManuallyDrop::new(self); IntoIter { raw: (&this.raw as *const RawSmallVec).read(), diff --git a/tests/arbitrary.rs b/tests/arbitrary.rs index 8bc7bb4..ca5580c 100644 --- a/tests/arbitrary.rs +++ b/tests/arbitrary.rs @@ -3,7 +3,8 @@ use smallvec::SmallVec; #[test] fn test_arbitrary() { - // Deterministic for fixed input bytes; assert it builds a consistent SmallVec. + // Deterministic for fixed input bytes; assert it builds a consistent + // SmallVec. let mut u = Unstructured::new(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); let v = SmallVec::::arbitrary(&mut u).unwrap(); assert_eq!(v.len(), v.iter().count()); diff --git a/tests/main.rs b/tests/main.rs index a1a0508..aef3a18 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -641,8 +641,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::::from_iter(0..3).into_iter(); let mut clone_iter = iter.clone(); while let Some(x) = iter.next() { @@ -994,8 +994,8 @@ fn collect_from_iter() { self.0.next() } - // no implementation of size_hint means it returns (0, None) - which forces - // from_iter to grow the allocated space iteratively. + // no implementation of size_hint means it returns (0, None) - which + // forces from_iter to grow the allocated space iteratively. } // A length of 3 is fine to trigger this bug under valgrind, but making the From db7830ffe3488d81ed2d2906860bdee3ba6b59e4 Mon Sep 17 00:00:00 2001 From: Alejandro Vaz Date: Sun, 30 Aug 2026 15:23:37 +0200 Subject: [PATCH 8/8] fix: imports --- src/lib.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0accd1a..c155f31 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,9 +60,9 @@ #![cfg_attr(feature = "may_dangle", feature(dropck_eyepatch))] #[doc(hidden)] -pub extern crate alloc; +extern crate alloc; -#[cfg(any(test, feature = "std"))] +#[cfg(feature = "std")] extern crate std; mod rawsmallvec; @@ -72,6 +72,12 @@ use bytes::{ BufMut, buf::UninitSlice }; +#[cfg(feature = "defmt")] +use defmt::{ + Format, + Formatter as DeFormatter, + write as dewrite +}; #[cfg(feature = "malloc_size_of")] use malloc_size_of::{ MallocShallowSizeOf,