Skip to content

Commit acdd441

Browse files
committed
remove separate no-drop code path since it resulted in more LLVM IR
1 parent 435219d commit acdd441

File tree

1 file changed

+15
-32
lines changed

1 file changed

+15
-32
lines changed

library/alloc/src/vec.rs

+15-32
Original file line numberDiff line numberDiff line change
@@ -2174,8 +2174,10 @@ impl<T> InPlaceDrop<T> {
21742174
impl<T> Drop for InPlaceDrop<T> {
21752175
#[inline]
21762176
fn drop(&mut self) {
2177-
unsafe {
2178-
ptr::drop_in_place(slice::from_raw_parts_mut(self.inner, self.len()));
2177+
if mem::needs_drop::<T>() {
2178+
unsafe {
2179+
ptr::drop_in_place(slice::from_raw_parts_mut(self.inner, self.len()));
2180+
}
21792181
}
21802182
}
21812183
}
@@ -2206,26 +2208,14 @@ impl<T> SpecFrom<T, IntoIter<T>> for Vec<T> {
22062208
}
22072209
}
22082210

2209-
fn write_in_place<T>(src_end: *const T) -> impl FnMut(*mut T, T) -> Result<*mut T, !> {
2210-
move |mut dst, item| {
2211-
unsafe {
2212-
// the InPlaceIterable contract cannot be verified precisely here since
2213-
// try_fold has an exclusive reference to the source pointer
2214-
// all we can do is check if it's still in range
2215-
debug_assert!(dst as *const _ <= src_end, "InPlaceIterable contract violation");
2216-
ptr::write(dst, item);
2217-
dst = dst.add(1);
2218-
}
2219-
Ok(dst)
2220-
}
2221-
}
2222-
22232211
fn write_in_place_with_drop<T>(
22242212
src_end: *const T,
22252213
) -> impl FnMut(InPlaceDrop<T>, T) -> Result<InPlaceDrop<T>, !> {
22262214
move |mut sink, item| {
22272215
unsafe {
2228-
// same caveat as above
2216+
// the InPlaceIterable contract cannot be verified precisely here since
2217+
// try_fold has an exclusive reference to the source pointer
2218+
// all we can do is check if it's still in range
22292219
debug_assert!(sink.dst as *const _ <= src_end, "InPlaceIterable contract violation");
22302220
ptr::write(sink.dst, item);
22312221
sink.dst = sink.dst.add(1);
@@ -2263,23 +2253,16 @@ where
22632253
(inner.buf.as_ptr(), inner.buf.as_ptr() as *mut T, inner.end as *const T, inner.cap)
22642254
};
22652255

2266-
// use try-fold
2256+
// use try-fold since
22672257
// - it vectorizes better for some iterator adapters
22682258
// - unlike most internal iteration methods methods it only takes a &mut self
2269-
// - lets us thread the write pointer through its innards and get it back in the end
2270-
let dst = if mem::needs_drop::<T>() {
2271-
// special-case drop handling since it forces us to lug that extra field around which
2272-
// can inhibit optimizations
2273-
let sink = InPlaceDrop { inner: dst_buf, dst: dst_buf };
2274-
let sink = iterator
2275-
.try_fold::<_, _, Result<_, !>>(sink, write_in_place_with_drop(dst_end))
2276-
.unwrap();
2277-
// iteration succeeded, don't drop head
2278-
let sink = mem::ManuallyDrop::new(sink);
2279-
sink.dst
2280-
} else {
2281-
iterator.try_fold::<_, _, Result<_, !>>(dst_buf, write_in_place(dst_end)).unwrap()
2282-
};
2259+
// - it lets us thread the write pointer through its innards and get it back in the end
2260+
let sink = InPlaceDrop { inner: dst_buf, dst: dst_buf };
2261+
let sink = iterator
2262+
.try_fold::<_, _, Result<_, !>>(sink, write_in_place_with_drop(dst_end))
2263+
.unwrap();
2264+
// iteration succeeded, don't drop head
2265+
let dst = mem::ManuallyDrop::new(sink).dst;
22832266

22842267
let src = unsafe { iterator.as_inner().as_into_iter() };
22852268
// check if SourceIter and InPlaceIterable contracts were upheld.

0 commit comments

Comments
 (0)