Skip to content

Commit d077778

Browse files
committed
fix some in-place-collect edge-cases
- it's an allocation optimization, so don't attempt to do it on ZSTs - drop the tail of partially exhausted iters
1 parent 14f8894 commit d077778

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

src/liballoc/vec.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2086,6 +2086,12 @@ fn from_into_iter_source<T, I>(mut iterator: I) -> Vec<T>
20862086
where
20872087
I: Iterator<Item = T> + InPlaceIterable + SourceIter<Source = IntoIter<T>>,
20882088
{
2089+
// This specialization only makes sense if we're juggling real allocations.
2090+
// Additionally some of the pointer arithmetic would panic on ZSTs.
2091+
if mem::size_of::<T>() == 0 {
2092+
return SpecFromNested::from_iter(iterator);
2093+
}
2094+
20892095
let src_buf = iterator.as_inner().buf.as_ptr();
20902096
let src_end = iterator.as_inner().end;
20912097
let dst = src_buf;
@@ -2132,6 +2138,13 @@ where
21322138
debug_assert_eq!(src_buf, src.buf.as_ptr());
21332139
debug_assert!(dst as *const _ <= src.ptr, "InPlaceIterable contract violation");
21342140

2141+
if mem::needs_drop::<T>() {
2142+
// drop tail if iterator was only partially exhaused
2143+
unsafe {
2144+
ptr::drop_in_place(src.as_mut_slice());
2145+
}
2146+
}
2147+
21352148
let vec = unsafe {
21362149
let len = dst.offset_from(src_buf) as usize;
21372150
Vec::from_raw_parts(src.buf.as_ptr(), len, src.cap)

0 commit comments

Comments
 (0)