select Vec::from_iter impls in a const block to optimize compile times
This commit is contained in:
parent
a128516cf9
commit
3ff1e448e7
@ -229,14 +229,28 @@ where
|
|||||||
I: Iterator<Item = T> + InPlaceCollect,
|
I: Iterator<Item = T> + InPlaceCollect,
|
||||||
<I as SourceIter>::Source: AsVecIntoIter,
|
<I as SourceIter>::Source: AsVecIntoIter,
|
||||||
{
|
{
|
||||||
default fn from_iter(mut iterator: I) -> Self {
|
default fn from_iter(iterator: I) -> Self {
|
||||||
// See "Layout constraints" section in the module documentation. We rely on const
|
// Select the implementation in const eval to avoid codegen of the dead branch to improve compile times.
|
||||||
// optimization here since these conditions currently cannot be expressed as trait bounds
|
let fun: fn(I) -> Vec<T> = const {
|
||||||
if const { !in_place_collectible::<T, I::Src>(I::MERGE_BY, I::EXPAND_BY) } {
|
// See "Layout constraints" section in the module documentation. We use const conditions here
|
||||||
// fallback to more generic implementations
|
// since these conditions currently cannot be expressed as trait bounds
|
||||||
return SpecFromIterNested::from_iter(iterator);
|
if in_place_collectible::<T, I::Src>(I::MERGE_BY, I::EXPAND_BY) {
|
||||||
|
from_iter_in_place
|
||||||
|
} else {
|
||||||
|
// fallback
|
||||||
|
SpecFromIterNested::<T, I>::from_iter
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fun(iterator)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_iter_in_place<I, T>(mut iterator: I) -> Vec<T>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = T> + InPlaceCollect,
|
||||||
|
<I as SourceIter>::Source: AsVecIntoIter,
|
||||||
|
{
|
||||||
let (src_buf, src_ptr, src_cap, mut dst_buf, dst_end, dst_cap) = unsafe {
|
let (src_buf, src_ptr, src_cap, mut dst_buf, dst_end, dst_cap) = unsafe {
|
||||||
let inner = iterator.as_inner().as_into_iter();
|
let inner = iterator.as_inner().as_into_iter();
|
||||||
(
|
(
|
||||||
@ -301,11 +315,8 @@ where
|
|||||||
let dst_size = mem::size_of::<T>().unchecked_mul(dst_cap);
|
let dst_size = mem::size_of::<T>().unchecked_mul(dst_cap);
|
||||||
let new_layout = Layout::from_size_align_unchecked(dst_size, dst_align);
|
let new_layout = Layout::from_size_align_unchecked(dst_size, dst_align);
|
||||||
|
|
||||||
let result = alloc.shrink(
|
let result =
|
||||||
NonNull::new_unchecked(dst_buf as *mut u8),
|
alloc.shrink(NonNull::new_unchecked(dst_buf as *mut u8), old_layout, new_layout);
|
||||||
old_layout,
|
|
||||||
new_layout,
|
|
||||||
);
|
|
||||||
let Ok(reallocated) = result else { handle_alloc_error(new_layout) };
|
let Ok(reallocated) = result else { handle_alloc_error(new_layout) };
|
||||||
dst_buf = reallocated.as_ptr() as *mut T;
|
dst_buf = reallocated.as_ptr() as *mut T;
|
||||||
}
|
}
|
||||||
@ -319,7 +330,6 @@ where
|
|||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn write_in_place_with_drop<T>(
|
fn write_in_place_with_drop<T>(
|
||||||
src_end: *const T,
|
src_end: *const T,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user