Skip to content

Commit f6f2598

Browse files
committed
Don't use Take in SpecExtend impl
1 parent ecca8c5 commit f6f2598

File tree

1 file changed

+23
-21
lines changed

1 file changed

+23
-21
lines changed

library/alloc/src/collections/vec_deque/spec_extend.rs

+23-21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::alloc::Allocator;
22
use crate::vec;
3-
use core::iter::{ByRefSized, TrustedLen};
3+
use core::iter::TrustedLen;
44
use core::slice;
55

66
use super::VecDeque;
@@ -20,28 +20,30 @@ where
2020
// for item in iter {
2121
// self.push_back(item);
2222
// }
23-
loop {
24-
let lower_bound = iter.size_hint().0;
25-
if lower_bound != 0 {
26-
self.reserve(lower_bound);
27-
}
2823

29-
match iter.next() {
30-
Some(val) => self.push_back(val),
31-
None => break,
32-
}
24+
// May only be called if `deque.len() < deque.capacity()`
25+
unsafe fn push_unchecked<T, A: Allocator>(deque: &mut VecDeque<T, A>, element: T) {
26+
// SAFETY: Because of the precondition, it's guaranteed that there is space
27+
// in the logical array after the last element.
28+
unsafe { deque.buffer_write(deque.to_physical_idx(deque.len), element) };
29+
// This can't overflow because `deque.len() < deque.capacity() <= usize::MAX`.
30+
deque.len += 1;
31+
}
32+
33+
while let Some(element) = iter.next() {
34+
let (lower, _) = iter.size_hint();
35+
self.reserve(lower.saturating_add(1));
36+
37+
// SAFETY: We just reserved space for at least one element.
38+
unsafe { push_unchecked(self, element) };
3339

34-
let room = self.capacity() - self.len;
35-
unsafe {
36-
// Safety:
37-
// The iter is at most `room` items long,
38-
// and `room == self.capacity() - self.len`
39-
// => `self.len + room <= self.capacity()`
40-
self.write_iter_wrapping(
41-
self.to_physical_idx(self.len),
42-
ByRefSized(&mut iter).take(room),
43-
room,
44-
);
40+
// Inner loop to avoid repeatedly calling `reserve`.
41+
while self.len < self.capacity() {
42+
let Some(element) = iter.next() else {
43+
return;
44+
};
45+
// SAFETY: The loop condition guarantees that `self.len() < self.capacity()`.
46+
unsafe { push_unchecked(self, element) };
4547
}
4648
}
4749
}

0 commit comments

Comments
 (0)