select Vec::from_iter impls in a const block to optimize compile times

This commit is contained in:
The 8472 2024-03-07 20:34:32 +01:00
parent a128516cf9
commit 3ff1e448e7

View File

@ -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;
} }
@ -318,7 +329,6 @@ where
let vec = unsafe { Vec::from_raw_parts(dst_buf, len, dst_cap) }; let vec = unsafe { Vec::from_raw_parts(dst_buf, len, dst_cap) };
vec vec
}
} }
fn write_in_place_with_drop<T>( fn write_in_place_with_drop<T>(