Skip to content

Commit 6cf243a

Browse files
committed
extract IntoIter drop/forget used by specialization into separate methods
1 parent 96cbc9d commit 6cf243a

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

src/liballoc/vec.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2121,9 +2121,9 @@ where
21212121
return SpecFromNested::from_iter(iterator);
21222122
}
21232123

2124-
let (src_buf, src_end) = {
2124+
let (src_buf, src_end, cap) = {
21252125
let inner = unsafe { iterator.as_inner().as_into_iter() };
2126-
(inner.buf.as_ptr(), inner.end)
2126+
(inner.buf.as_ptr(), inner.end, inner.cap)
21272127
};
21282128
let dst = src_buf;
21292129

@@ -2173,23 +2173,15 @@ where
21732173
debug_assert_eq!(src_buf, src.buf.as_ptr());
21742174
debug_assert!(dst as *const _ <= src.ptr, "InPlaceIterable contract violation");
21752175

2176-
if mem::needs_drop::<T>() {
2177-
// drop tail if iterator was only partially exhausted
2178-
unsafe {
2179-
ptr::drop_in_place(src.as_mut_slice());
2180-
}
2181-
}
2176+
// drop any remaining values at the tail of the source
2177+
src.drop_in_place();
2178+
// but prevent drop of the allocation itself once IntoIter goes out of scope
2179+
src.forget_in_place();
21822180

21832181
let vec = unsafe {
21842182
let len = dst.offset_from(src_buf) as usize;
2185-
Vec::from_raw_parts(src.buf.as_ptr(), len, src.cap)
2183+
Vec::from_raw_parts(src_buf, len, cap)
21862184
};
2187-
// prevent drop of the underlying storage by turning the IntoIter into
2188-
// the equivalent of Vec::new().into_iter()
2189-
src.cap = 0;
2190-
src.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
2191-
src.ptr = src.buf.as_ptr();
2192-
src.end = src.buf.as_ptr();
21932185

21942186
vec
21952187
}
@@ -2705,6 +2697,24 @@ impl<T> IntoIter<T> {
27052697
pub fn as_mut_slice(&mut self) -> &mut [T] {
27062698
unsafe { slice::from_raw_parts_mut(self.ptr as *mut T, self.len()) }
27072699
}
2700+
2701+
fn drop_in_place(&mut self) {
2702+
if mem::needs_drop::<T>() {
2703+
unsafe {
2704+
ptr::drop_in_place(self.as_mut_slice());
2705+
}
2706+
}
2707+
self.ptr = self.end;
2708+
}
2709+
2710+
/// Relinquishes the backing allocation, equivalent to
2711+
/// `ptr::write(&mut self, Vec::new().into_iter())`
2712+
fn forget_in_place(&mut self) {
2713+
self.cap = 0;
2714+
self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
2715+
self.ptr = self.buf.as_ptr();
2716+
self.end = self.buf.as_ptr();
2717+
}
27082718
}
27092719

27102720
#[stable(feature = "rust1", since = "1.0.0")]

0 commit comments

Comments
 (0)