extract IntoIter drop/forget used by specialization into separate methods
This commit is contained in:
parent
6ad133443a
commit
771b8ecc83
1 changed files with 25 additions and 15 deletions
|
@ -2226,9 +2226,9 @@ where
|
||||||
return SpecFromNested::from_iter(iterator);
|
return SpecFromNested::from_iter(iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (src_buf, src_end) = {
|
let (src_buf, src_end, cap) = {
|
||||||
let inner = unsafe { iterator.as_inner().as_into_iter() };
|
let inner = unsafe { iterator.as_inner().as_into_iter() };
|
||||||
(inner.buf.as_ptr(), inner.end)
|
(inner.buf.as_ptr(), inner.end, inner.cap)
|
||||||
};
|
};
|
||||||
let dst = src_buf;
|
let dst = src_buf;
|
||||||
|
|
||||||
|
@ -2278,23 +2278,15 @@ where
|
||||||
debug_assert_eq!(src_buf, src.buf.as_ptr());
|
debug_assert_eq!(src_buf, src.buf.as_ptr());
|
||||||
debug_assert!(dst as *const _ <= src.ptr, "InPlaceIterable contract violation");
|
debug_assert!(dst as *const _ <= src.ptr, "InPlaceIterable contract violation");
|
||||||
|
|
||||||
if mem::needs_drop::<T>() {
|
// drop any remaining values at the tail of the source
|
||||||
// drop tail if iterator was only partially exhausted
|
src.drop_in_place();
|
||||||
unsafe {
|
// but prevent drop of the allocation itself once IntoIter goes out of scope
|
||||||
ptr::drop_in_place(src.as_mut_slice());
|
src.forget_in_place();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let vec = unsafe {
|
let vec = unsafe {
|
||||||
let len = dst.offset_from(src_buf) as usize;
|
let len = dst.offset_from(src_buf) as usize;
|
||||||
Vec::from_raw_parts(src.buf.as_ptr(), len, src.cap)
|
Vec::from_raw_parts(src_buf, len, cap)
|
||||||
};
|
};
|
||||||
// prevent drop of the underlying storage by turning the IntoIter into
|
|
||||||
// the equivalent of Vec::new().into_iter()
|
|
||||||
src.cap = 0;
|
|
||||||
src.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
|
|
||||||
src.ptr = src.buf.as_ptr();
|
|
||||||
src.end = src.buf.as_ptr();
|
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
@ -2839,6 +2831,24 @@ impl<T> IntoIter<T> {
|
||||||
fn as_raw_mut_slice(&mut self) -> *mut [T] {
|
fn as_raw_mut_slice(&mut self) -> *mut [T] {
|
||||||
ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len())
|
ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn drop_in_place(&mut self) {
|
||||||
|
if mem::needs_drop::<T>() {
|
||||||
|
unsafe {
|
||||||
|
ptr::drop_in_place(self.as_mut_slice());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.ptr = self.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Relinquishes the backing allocation, equivalent to
|
||||||
|
/// `ptr::write(&mut self, Vec::new().into_iter())`
|
||||||
|
fn forget_in_place(&mut self) {
|
||||||
|
self.cap = 0;
|
||||||
|
self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
|
||||||
|
self.ptr = self.buf.as_ptr();
|
||||||
|
self.end = self.buf.as_ptr();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "vec_intoiter_as_ref", since = "1.46.0")]
|
#[stable(feature = "vec_intoiter_as_ref", since = "1.46.0")]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue