Skip to content

Commit 771b8ec

Browse files
committed
extract IntoIter drop/forget used by specialization into separate methods
1 parent 6ad1334 commit 771b8ec

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

library/alloc/src/vec.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2226,9 +2226,9 @@ where
22262226
return SpecFromNested::from_iter(iterator);
22272227
}
22282228

2229-
let (src_buf, src_end) = {
2229+
let (src_buf, src_end, cap) = {
22302230
let inner = unsafe { iterator.as_inner().as_into_iter() };
2231-
(inner.buf.as_ptr(), inner.end)
2231+
(inner.buf.as_ptr(), inner.end, inner.cap)
22322232
};
22332233
let dst = src_buf;
22342234

@@ -2278,23 +2278,15 @@ where
22782278
debug_assert_eq!(src_buf, src.buf.as_ptr());
22792279
debug_assert!(dst as *const _ <= src.ptr, "InPlaceIterable contract violation");
22802280

2281-
if mem::needs_drop::<T>() {
2282-
// drop tail if iterator was only partially exhausted
2283-
unsafe {
2284-
ptr::drop_in_place(src.as_mut_slice());
2285-
}
2286-
}
2281+
// drop any remaining values at the tail of the source
2282+
src.drop_in_place();
2283+
// but prevent drop of the allocation itself once IntoIter goes out of scope
2284+
src.forget_in_place();
22872285

22882286
let vec = unsafe {
22892287
let len = dst.offset_from(src_buf) as usize;
2290-
Vec::from_raw_parts(src.buf.as_ptr(), len, src.cap)
2288+
Vec::from_raw_parts(src_buf, len, cap)
22912289
};
2292-
// prevent drop of the underlying storage by turning the IntoIter into
2293-
// the equivalent of Vec::new().into_iter()
2294-
src.cap = 0;
2295-
src.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
2296-
src.ptr = src.buf.as_ptr();
2297-
src.end = src.buf.as_ptr();
22982290

22992291
vec
23002292
}
@@ -2839,6 +2831,24 @@ impl<T> IntoIter<T> {
28392831
fn as_raw_mut_slice(&mut self) -> *mut [T] {
28402832
ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len())
28412833
}
2834+
2835+
fn drop_in_place(&mut self) {
2836+
if mem::needs_drop::<T>() {
2837+
unsafe {
2838+
ptr::drop_in_place(self.as_mut_slice());
2839+
}
2840+
}
2841+
self.ptr = self.end;
2842+
}
2843+
2844+
/// Relinquishes the backing allocation, equivalent to
2845+
/// `ptr::write(&mut self, Vec::new().into_iter())`
2846+
fn forget_in_place(&mut self) {
2847+
self.cap = 0;
2848+
self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
2849+
self.ptr = self.buf.as_ptr();
2850+
self.end = self.buf.as_ptr();
2851+
}
28422852
}
28432853

28442854
#[stable(feature = "vec_intoiter_as_ref", since = "1.46.0")]

0 commit comments

Comments
 (0)