mirror of
https://github.com/openharmony/third_party_rust_tinyvec.git
synced 2026-07-18 12:25:35 -04:00
Modify tiny_vec! to avoid error on non-Copy types (#74)
* Modify tiny_vec! to avoid error on non-Copy types Using $elem in two closures in the previous version of the macro created errors when using types that don't implement Copy. Moving the decision of whether to allocate or use an inline array to the macro invocation resolves this error as the borrow checker can see that both branches are never taken together. * Add test for tiny_vec! using non-Copy types * Fix inference issue * Use full crate path in tiny_vec!
This commit is contained in:
+13
-12
@@ -46,11 +46,10 @@ macro_rules! tiny_vec {
|
||||
const INVOKED_ELEM_COUNT: usize = 0 $( + { let _ = stringify!($elem); 1 })*;
|
||||
// If we have more `$elem` than the `CAPACITY` we will simply go directly
|
||||
// to constructing on the heap.
|
||||
let av: $crate::TinyVec<$array_type> = $crate::TinyVec::from_either_with_capacity(
|
||||
INVOKED_ELEM_COUNT,
|
||||
#[inline(always)] || $crate::array_vec!($array_type, $($elem),*),
|
||||
#[inline(always)] || vec!($($elem),*));
|
||||
av
|
||||
match $crate::TinyVec::constructor_for_capacity(INVOKED_ELEM_COUNT) {
|
||||
$crate::TinyVecConstructor::Inline(f) => f($crate::array_vec!($array_type, $($elem),*)),
|
||||
$crate::TinyVecConstructor::Heap(f) => f(vec!($($elem),*)),
|
||||
}
|
||||
}
|
||||
};
|
||||
() => {
|
||||
@@ -61,6 +60,12 @@ macro_rules! tiny_vec {
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)] // Internal implementation details of `tiny_vec!`
|
||||
pub enum TinyVecConstructor<A: Array> {
|
||||
Inline(fn(ArrayVec<A>) -> TinyVec<A>),
|
||||
Heap(fn(Vec<A::Item>) -> TinyVec<A>),
|
||||
}
|
||||
|
||||
/// A vector that starts inline, but can automatically move to the heap.
|
||||
///
|
||||
/// * Requires the `alloc` feature
|
||||
@@ -344,15 +349,11 @@ impl<A: Array> TinyVec<A> {
|
||||
|
||||
#[inline(always)]
|
||||
#[doc(hidden)] // Internal implementation details of `tiny_vec!`
|
||||
pub fn from_either_with_capacity(
|
||||
cap: usize,
|
||||
make_array: impl FnOnce() -> ArrayVec<A>,
|
||||
make_vec: impl FnOnce() -> Vec<A::Item>,
|
||||
) -> Self {
|
||||
pub fn constructor_for_capacity(cap: usize) -> TinyVecConstructor<A> {
|
||||
if cap <= A::CAPACITY {
|
||||
TinyVec::Inline(make_array())
|
||||
TinyVecConstructor::Inline(TinyVec::Inline)
|
||||
} else {
|
||||
TinyVec::Heap(make_vec())
|
||||
TinyVecConstructor::Heap(TinyVec::Heap)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,3 +93,10 @@ fn TinyVec_from_array() {
|
||||
let tv = TinyVec::from(array);
|
||||
assert_eq!(&array, &tv[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn TinyVec_macro_non_copy() {
|
||||
// must use a variable here to avoid macro shenanigans
|
||||
let s = String::new();
|
||||
let _: TinyVec<[String; 10]> = tiny_vec!([String; 10], s);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user