From 00a32eb54f65c11cd2f4d10c2414dd633fab3c5b Mon Sep 17 00:00:00 2001 From: The8472 Date: Sat, 23 Nov 2019 14:32:20 +0100 Subject: [PATCH] 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 --- library/alloc/src/vec.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index fdc7738e733..1e7f95a25cc 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -2192,6 +2192,12 @@ fn from_into_iter_source(mut iterator: I) -> Vec where I: Iterator + InPlaceIterable + SourceIter>, { + // This specialization only makes sense if we're juggling real allocations. + // Additionally some of the pointer arithmetic would panic on ZSTs. + if mem::size_of::() == 0 { + return SpecFromNested::from_iter(iterator); + } + let src_buf = iterator.as_inner().buf.as_ptr(); let src_end = iterator.as_inner().end; let dst = src_buf; @@ -2238,6 +2244,13 @@ where debug_assert_eq!(src_buf, src.buf.as_ptr()); debug_assert!(dst as *const _ <= src.ptr, "InPlaceIterable contract violation"); + if mem::needs_drop::() { + // drop tail if iterator was only partially exhaused + unsafe { + ptr::drop_in_place(src.as_mut_slice()); + } + } + let vec = unsafe { let len = dst.offset_from(src_buf) as usize; Vec::from_raw_parts(src.buf.as_ptr(), len, src.cap)