Skip to content

Commit 085eb20

Browse files
committed
move free-standing method into trait impl
1 parent 0f122e1 commit 085eb20

File tree

1 file changed

+75
-79
lines changed

1 file changed

+75
-79
lines changed

library/alloc/src/vec.rs

Lines changed: 75 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -2188,83 +2188,6 @@ impl<T> Drop for InPlaceDrop<T> {
21882188
}
21892189
}
21902190

2191-
fn from_into_iter_source<T, I>(mut iterator: I) -> Vec<T>
2192-
where
2193-
I: Iterator<Item = T> + InPlaceIterable + SourceIter<Source = IntoIter<T>>,
2194-
{
2195-
// This specialization only makes sense if we're juggling real allocations.
2196-
// Additionally some of the pointer arithmetic would panic on ZSTs.
2197-
if mem::size_of::<T>() == 0 {
2198-
return SpecFromNested::from_iter(iterator);
2199-
}
2200-
2201-
let src_buf = iterator.as_inner().buf.as_ptr();
2202-
let src_end = iterator.as_inner().end;
2203-
let dst = src_buf;
2204-
2205-
let dst = if mem::needs_drop::<T>() {
2206-
// special-case drop handling since it prevents vectorization
2207-
let mut sink = InPlaceDrop { inner: src_buf, dst, did_panic: true };
2208-
let _ = iterator.try_for_each::<_, Result<_, !>>(|item| {
2209-
unsafe {
2210-
debug_assert!(
2211-
sink.dst as *const _ <= src_end,
2212-
"InPlaceIterable contract violation"
2213-
);
2214-
ptr::write(sink.dst, item);
2215-
sink.dst = sink.dst.add(1);
2216-
}
2217-
Ok(())
2218-
});
2219-
sink.did_panic = false;
2220-
sink.dst
2221-
} else {
2222-
// use try-fold
2223-
// - it vectorizes better
2224-
// - unlike most internal iteration methods methods it only takes a &mut self
2225-
// - lets us thread the write pointer through its innards and get it back in the end
2226-
iterator
2227-
.try_fold::<_, _, Result<_, !>>(dst, move |mut dst, item| {
2228-
unsafe {
2229-
// the InPlaceIterable contract cannot be verified precisely here since
2230-
// try_fold has an exclusive reference to the source pointer
2231-
// all we can do is check if it's still in range
2232-
debug_assert!(dst as *const _ <= src_end, "InPlaceIterable contract violation");
2233-
ptr::write(dst, item);
2234-
dst = dst.add(1);
2235-
}
2236-
Ok(dst)
2237-
})
2238-
.unwrap()
2239-
};
2240-
2241-
let src = iterator.as_inner();
2242-
// check if SourceIter and InPlaceIterable contracts were upheld.
2243-
// caveat: if they weren't we may not even make it to this point
2244-
debug_assert_eq!(src_buf, src.buf.as_ptr());
2245-
debug_assert!(dst as *const _ <= src.ptr, "InPlaceIterable contract violation");
2246-
2247-
if mem::needs_drop::<T>() {
2248-
// drop tail if iterator was only partially exhaused
2249-
unsafe {
2250-
ptr::drop_in_place(src.as_mut_slice());
2251-
}
2252-
}
2253-
2254-
let vec = unsafe {
2255-
let len = dst.offset_from(src_buf) as usize;
2256-
Vec::from_raw_parts(src.buf.as_ptr(), len, src.cap)
2257-
};
2258-
// prevent drop of the underlying storage by turning the IntoIter into
2259-
// the equivalent of Vec::new().into_iter()
2260-
src.cap = 0;
2261-
src.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
2262-
src.ptr = src.buf.as_ptr();
2263-
src.end = src.buf.as_ptr();
2264-
2265-
vec
2266-
}
2267-
22682191
impl<T> SpecFrom<T, IntoIter<T>> for Vec<T> {
22692192
fn from_iter(iterator: IntoIter<T>) -> Self {
22702193
// A common case is passing a vector into a function which immediately
@@ -2298,8 +2221,81 @@ impl<T, I> SpecFrom<T, I> for Vec<T>
22982221
where
22992222
I: Iterator<Item = T> + InPlaceIterable + SourceIter<Source = IntoIter<T>>,
23002223
{
2301-
default fn from_iter(iterator: I) -> Self {
2302-
from_into_iter_source(iterator)
2224+
default fn from_iter(mut iterator: I) -> Self {
2225+
// This specialization only makes sense if we're juggling real allocations.
2226+
// Additionally some of the pointer arithmetic would panic on ZSTs.
2227+
if mem::size_of::<T>() == 0 {
2228+
return SpecFromNested::from_iter(iterator);
2229+
}
2230+
2231+
let src_buf = iterator.as_inner().buf.as_ptr();
2232+
let src_end = iterator.as_inner().end;
2233+
let dst = src_buf;
2234+
2235+
let dst = if mem::needs_drop::<T>() {
2236+
// special-case drop handling since it prevents vectorization
2237+
let mut sink = InPlaceDrop { inner: src_buf, dst, did_panic: true };
2238+
let _ = iterator.try_for_each::<_, Result<_, !>>(|item| {
2239+
unsafe {
2240+
debug_assert!(
2241+
sink.dst as *const _ <= src_end,
2242+
"InPlaceIterable contract violation"
2243+
);
2244+
ptr::write(sink.dst, item);
2245+
sink.dst = sink.dst.add(1);
2246+
}
2247+
Ok(())
2248+
});
2249+
sink.did_panic = false;
2250+
sink.dst
2251+
} else {
2252+
// use try-fold
2253+
// - it vectorizes better
2254+
// - unlike most internal iteration methods methods it only takes a &mut self
2255+
// - lets us thread the write pointer through its innards and get it back in the end
2256+
iterator
2257+
.try_fold::<_, _, Result<_, !>>(dst, move |mut dst, item| {
2258+
unsafe {
2259+
// the InPlaceIterable contract cannot be verified precisely here since
2260+
// try_fold has an exclusive reference to the source pointer
2261+
// all we can do is check if it's still in range
2262+
debug_assert!(
2263+
dst as *const _ <= src_end,
2264+
"InPlaceIterable contract violation"
2265+
);
2266+
ptr::write(dst, item);
2267+
dst = dst.add(1);
2268+
}
2269+
Ok(dst)
2270+
})
2271+
.unwrap()
2272+
};
2273+
2274+
let src = iterator.as_inner();
2275+
// check if SourceIter and InPlaceIterable contracts were upheld.
2276+
// caveat: if they weren't we may not even make it to this point
2277+
debug_assert_eq!(src_buf, src.buf.as_ptr());
2278+
debug_assert!(dst as *const _ <= src.ptr, "InPlaceIterable contract violation");
2279+
2280+
if mem::needs_drop::<T>() {
2281+
// drop tail if iterator was only partially exhaused
2282+
unsafe {
2283+
ptr::drop_in_place(src.as_mut_slice());
2284+
}
2285+
}
2286+
2287+
let vec = unsafe {
2288+
let len = dst.offset_from(src_buf) as usize;
2289+
Vec::from_raw_parts(src.buf.as_ptr(), len, src.cap)
2290+
};
2291+
// prevent drop of the underlying storage by turning the IntoIter into
2292+
// the equivalent of Vec::new().into_iter()
2293+
src.cap = 0;
2294+
src.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
2295+
src.ptr = src.buf.as_ptr();
2296+
src.end = src.buf.as_ptr();
2297+
2298+
vec
23032299
}
23042300
}
23052301

0 commit comments

Comments
 (0)