Skip to content

Commit

Permalink
fix and test aliasing in swap_remove
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Mar 30, 2020
1 parent 8f479e3 commit 5bbaac3
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/liballoc/tests/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1378,6 +1378,11 @@ fn test_stable_pointers() {
v.remove(1);
v.pop().unwrap();
assert_eq!(*v0, 13);
v.push(1);
v.swap_remove(1);
assert_eq!(v.len(), 2);
v.swap_remove(1); // swap_remove the last element
assert_eq!(*v0, 13);

// Appending
v.append(&mut vec![27, 19]);
Expand Down
7 changes: 4 additions & 3 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -963,12 +963,13 @@ impl<T> Vec<T> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn swap_remove(&mut self, index: usize) -> T {
assert!(index < self.len);
unsafe {
// We replace self[index] with the last element. Note that if the
// bounds check on hole succeeds there must be a last element (which
// bounds check above succeeds there must be a last element (which
// can be self[index] itself).
let hole: *mut T = &mut self[index];
let last = ptr::read(self.get_unchecked(self.len - 1));
let last = ptr::read(self.as_ptr().add(self.len - 1));
let hole: *mut T = self.as_mut_ptr().add(index);
self.len -= 1;
ptr::replace(hole, last)
}
Expand Down

0 comments on commit 5bbaac3

Please sign in to comment.