about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2019-05-25 10:11:00 +0200
committerRalf Jung <post@ralfj.de>2019-05-25 10:11:00 +0200
commit9d82826e555e658680cf6ef246ae6d088f300d1d (patch)
treebfb2a1770ec3c5e0df39c327dd173962465cff19 /src/liballoc
parent46805805abe58c287fa16963f897fd09d5d97467 (diff)
downloadrust-9d82826e555e658680cf6ef246ae6d088f300d1d.tar.gz
rust-9d82826e555e658680cf6ef246ae6d088f300d1d.zip
add test checking that Vec push/pop does not invalidate pointers
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/tests/vec.rs21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 3307bdf94f9..5ddac673c9f 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -1152,3 +1152,24 @@ fn test_try_reserve_exact() {
     }
 
 }
+
+#[test]
+fn test_stable_push_pop() {
+    // Test that, if we reserved enough space, adding and removing elements does not
+    // invalidate references into the vector (such as `v0`).  This test also
+    // runs in Miri, which would detect such problems.
+    let mut v = Vec::with_capacity(10);
+    v.push(13);
+
+    // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
+    let v0 = unsafe { &*(&v[0] as *const _) };
+
+    // Now do a bunch of things and occasionally use `v0` again to assert it is still valid.
+    v.push(1);
+    v.push(2);
+    v.insert(1, 1);
+    assert_eq!(*v0, 13);
+    v.remove(1);
+    v.pop().unwrap();
+    assert_eq!(*v0, 13);
+}