Skip to content

Commit 5bbaac3

Browse files
committed
fix and test aliasing in swap_remove
1 parent 8f479e3 commit 5bbaac3

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

src/liballoc/tests/vec.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,11 @@ fn test_stable_pointers() {
13781378
v.remove(1);
13791379
v.pop().unwrap();
13801380
assert_eq!(*v0, 13);
1381+
v.push(1);
1382+
v.swap_remove(1);
1383+
assert_eq!(v.len(), 2);
1384+
v.swap_remove(1); // swap_remove the last element
1385+
assert_eq!(*v0, 13);
13811386

13821387
// Appending
13831388
v.append(&mut vec![27, 19]);

src/liballoc/vec.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -963,12 +963,13 @@ impl<T> Vec<T> {
963963
#[inline]
964964
#[stable(feature = "rust1", since = "1.0.0")]
965965
pub fn swap_remove(&mut self, index: usize) -> T {
966+
assert!(index < self.len);
966967
unsafe {
967968
// We replace self[index] with the last element. Note that if the
968-
// bounds check on hole succeeds there must be a last element (which
969+
// bounds check above succeeds there must be a last element (which
969970
// can be self[index] itself).
970-
let hole: *mut T = &mut self[index];
971-
let last = ptr::read(self.get_unchecked(self.len - 1));
971+
let last = ptr::read(self.as_ptr().add(self.len - 1));
972+
let hole: *mut T = self.as_mut_ptr().add(index);
972973
self.len -= 1;
973974
ptr::replace(hole, last)
974975
}

0 commit comments

Comments
 (0)