From 2bd4a0d6154ffea3534c584219493e1df240676c Mon Sep 17 00:00:00 2001 From: bolshoytoster Date: Sat, 29 Aug 2026 11:38:01 +0100 Subject: [PATCH 1/2] Implement `TryFrom> for [T; M]` and deprecate into_inner --- src/lib.rs | 20 ++++++++++++++++++++ src/tests.rs | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index af12044..6bb412c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1668,6 +1668,7 @@ impl SmallVec { } #[inline] + #[deprecated(since = "2.0.0-alpha.13", note = "use `TryInto::<[T; N]>::into` instead")] pub fn into_inner(self) -> Result<[T; N], Self> { if self.len() != N { Err(self) @@ -2689,6 +2690,25 @@ impl From<[T; M]> for SmallVec { } } +impl TryFrom> for [T; M] { + type Error = SmallVec; + + #[inline] + fn try_from(mut this: SmallVec) -> Result<[T; M], SmallVec> { + if this.len() != M { + Err(this) + } else { + // SAFETY: we release ownership of the elements we hold + unsafe { + this.set_len(0); + } + let ptr = this.as_ptr() as *const [T; M]; + // SAFETY: these elements are initialized since the length was `M` + unsafe { Ok(ptr.read()) } + } + } +} + impl From> for SmallVec { fn from(array: Vec) -> Self { Self::from_vec(array) diff --git a/src/tests.rs b/src/tests.rs index e05f24d..803dc4f 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -712,6 +712,26 @@ fn test_into_inner() { assert_eq!(vec.clone().into_inner(), Err(vec)); } +fn test_try_into_array() { + // Inline < capacity + let vec = SmallVec::::from_iter(0..1); + assert_eq!(<[u8; 0]>::try_from(vec.clone()), Err(vec.clone())); + assert_eq!(<[u8; 1]>::try_from(vec.clone()), Ok([0])); + assert_eq!(<[u8; 2]>::try_from(vec.clone()), Err(vec)); + + // Inline == capacity + let vec = SmallVec::::from_iter(0..2); + assert_eq!(<[u8; 1]>::try_from(vec.clone()), Err(vec.clone())); + assert_eq!(<[u8; 2]>::try_from(vec.clone()), Ok([0, 1])); + assert_eq!(<[u8; 3]>::try_from(vec.clone()), Err(vec)); + + // Heap + let vec = SmallVec::::from_iter(0..3); + assert_eq!(<[u8; 2]>::try_from(vec.clone()), Err(vec.clone())); + assert_eq!(<[u8; 3]>::try_from(vec.clone()), Ok([0, 1, 2])); + assert_eq!(<[u8; 4]>::try_from(vec.clone()), Err(vec)); +} + #[test] fn test_from_vec() { let vec = vec![]; From fb4b4543b98e53e883b7244a8d5b22af035b283d Mon Sep 17 00:00:00 2001 From: bolshoytoster Date: Sat, 29 Aug 2026 11:44:17 +0100 Subject: [PATCH 2/2] Run rustfmt --- src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 6bb412c..5018c7b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1668,7 +1668,10 @@ impl SmallVec { } #[inline] - #[deprecated(since = "2.0.0-alpha.13", note = "use `TryInto::<[T; N]>::into` instead")] + #[deprecated( + since = "2.0.0-alpha.13", + note = "use `TryInto::<[T; N]>::into` instead" + )] pub fn into_inner(self) -> Result<[T; N], Self> { if self.len() != N { Err(self)