Skip to content

Commit a929e60

Browse files
committed
rearrange to be panic safe
Signed-off-by: tabokie <[email protected]>
1 parent a456a55 commit a929e60

File tree

1 file changed

+12
-10
lines changed
  • library/alloc/src/collections/vec_deque

1 file changed

+12
-10
lines changed

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

+12-10
Original file line numberDiff line numberDiff line change
@@ -417,24 +417,23 @@ impl<T, A: Allocator> VecDeque<T, A> {
417417
}
418418
}
419419

420-
/// Append all values from `src` to `self`, wrapping around if needed.
420+
/// Append all values from `src` to `dst`, wrapping around if needed.
421421
/// Assumes capacity is sufficient.
422422
#[inline]
423-
unsafe fn append_slice(&mut self, src: &[T]) {
424-
debug_assert!(self.len() + src.len() + 1 <= self.cap());
425-
let head_room = self.cap() - self.head;
426-
if self.head < self.tail || src.len() <= head_room {
423+
unsafe fn copy_slice(&mut self, dst: usize, src: &[T]) {
424+
debug_assert!(src.len() <= self.cap());
425+
let head_room = self.cap() - dst;
426+
if src.len() <= head_room {
427427
unsafe {
428-
ptr::copy_nonoverlapping(src.as_ptr(), self.ptr().add(self.head), src.len());
428+
ptr::copy_nonoverlapping(src.as_ptr(), self.ptr().add(dst), src.len());
429429
}
430430
} else {
431431
let (left, right) = src.split_at(head_room);
432432
unsafe {
433-
ptr::copy_nonoverlapping(left.as_ptr(), self.ptr().add(self.head), left.len());
433+
ptr::copy_nonoverlapping(left.as_ptr(), self.ptr().add(dst), left.len());
434434
ptr::copy_nonoverlapping(right.as_ptr(), self.ptr(), right.len());
435435
}
436436
}
437-
self.head = self.wrap_add(self.head, src.len());
438437
}
439438

440439
/// Frobs the head and tail sections around to handle the fact that we
@@ -2111,9 +2110,12 @@ impl<T, A: Allocator> VecDeque<T, A> {
21112110
self.reserve(other.len());
21122111
unsafe {
21132112
let (left, right) = other.as_slices();
2114-
self.append_slice(left);
2115-
self.append_slice(right);
2113+
self.copy_slice(self.head, left);
2114+
self.copy_slice(self.wrap_add(self.head, left.len()), right);
21162115
}
2116+
// SAFETY: Update pointers after copying to avoid leaving doppelganger
2117+
// in case of panics.
2118+
self.head = self.wrap_add(self.head, other.len());
21172119
// Silently drop values in `other`.
21182120
other.tail = other.head;
21192121
}

0 commit comments

Comments
 (0)