Skip to content

Commit a2c7214

Browse files
committed
Relax From<array> for SmallVec to allow different length arrays.
1 parent f8136b8 commit a2c7214

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

src/lib.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -2016,10 +2016,18 @@ impl<A: Array> From<Vec<A::Item>> for SmallVec<A> {
20162016
}
20172017
}
20182018

2019-
impl<A: Array> From<A> for SmallVec<A> {
2019+
impl<A1: Array, A2: Array<Item = A1::Item>> From<A2> for SmallVec<A1> {
20202020
#[inline]
2021-
fn from(array: A) -> SmallVec<A> {
2022-
SmallVec::from_buf(array)
2021+
fn from(array: A2) -> SmallVec<A1> {
2022+
let m = A2::size();
2023+
let mut this = Self::with_capacity(m);
2024+
let array = mem::ManuallyDrop::new(array);
2025+
// SAFETY: m <= this.capacity()
2026+
unsafe {
2027+
ptr::copy_nonoverlapping(&*array as *const A2 as *const A2::Item, this.as_mut_ptr(), m);
2028+
this.set_len(m);
2029+
}
2030+
this
20232031
}
20242032
}
20252033

src/tests.rs

+10
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,16 @@ fn test_from() {
623623
let small_vec: SmallVec<[u8; 128]> = SmallVec::from(array);
624624
assert_eq!(&*small_vec, vec![99u8; 128].as_slice());
625625
drop(small_vec);
626+
627+
let array = [1; 128];
628+
let small_vec: SmallVec<[u8; 1]> = SmallVec::from(array);
629+
assert_eq!(&*small_vec, vec![1; 128].as_slice());
630+
drop(small_vec);
631+
632+
let array = [99];
633+
let small_vec: SmallVec<[u8; 128]> = SmallVec::from(array);
634+
assert_eq!(&*small_vec, &[99u8]);
635+
drop(small_vec);
626636
}
627637

628638
#[test]

0 commit comments

Comments
 (0)