Skip to content

Commit e41f55e

Browse files
author
Markus Westerlind
committed
Massage extend_desugared to reduce the compiletime impact
1 parent a092fe1 commit e41f55e

File tree

1 file changed

+22
-19
lines changed

1 file changed

+22
-19
lines changed

src/liballoc/vec.rs

+22-19
Original file line numberDiff line numberDiff line change
@@ -2123,20 +2123,35 @@ where
21232123

21242124
fn extend_fold<T>(self_: &mut Vec<T>) -> impl FnMut((), T) -> Result<(), T> + '_ {
21252125
move |(), element| {
2126-
let len = self_.len();
2127-
if len < self_.capacity() {
2126+
if self_.len() < self_.capacity() {
21282127
unsafe {
2129-
ptr::write(self_.get_unchecked_mut(len), element);
2130-
self_.set_len(len + 1);
2131-
Ok(())
2128+
self_.push_unchecked(element);
21322129
}
2130+
Ok(())
21332131
} else {
21342132
Err(element)
21352133
}
21362134
}
21372135
}
21382136

21392137
impl<T> Vec<T> {
2138+
unsafe fn push_unchecked(&mut self, value: T) {
2139+
let end = self.as_mut_ptr().add(self.len);
2140+
ptr::write(end, value);
2141+
// NB can't overflow since we would have had to alloc the address space
2142+
self.len += 1;
2143+
}
2144+
2145+
#[cold]
2146+
#[inline(never)]
2147+
fn extend_desugared_fallback<I: Iterator<Item = T>>(&mut self, iterator: &I, element: T) {
2148+
let (lower, _) = iterator.size_hint();
2149+
self.reserve(lower.saturating_add(1));
2150+
unsafe {
2151+
self.push_unchecked(element);
2152+
}
2153+
}
2154+
21402155
fn extend_desugared<I: Iterator<Item = T>>(&mut self, mut iterator: I) {
21412156
// This is the case for a general iterator.
21422157
//
@@ -2147,20 +2162,8 @@ impl<T> Vec<T> {
21472162
// }
21482163
let (lower, _) = iterator.size_hint();
21492164
self.reserve(lower);
2150-
loop {
2151-
match iterator.try_fold((), extend_fold(self)) {
2152-
Ok(_) => return,
2153-
Err(element) => {
2154-
let (lower, _) = iterator.size_hint();
2155-
self.reserve(lower.saturating_add(1));
2156-
unsafe {
2157-
let len = self.len();
2158-
ptr::write(self.get_unchecked_mut(len), element);
2159-
// NB can't overflow since we would have had to alloc the address space
2160-
self.set_len(len + 1);
2161-
}
2162-
}
2163-
}
2165+
while let Err(element) = iterator.try_fold((), extend_fold(self)) {
2166+
self.extend_desugared_fallback(&iterator, element);
21642167
}
21652168
}
21662169

0 commit comments

Comments
 (0)