about summary refs log tree commit diff
path: root/src/liballoc/tests
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2019-12-13 14:51:37 +0100
committerJonas Schievink <jonasschievink@gmail.com>2020-01-19 20:23:07 +0100
commita859ca5c87ddfaa635fb4cacf8a41e04fd9b02e8 (patch)
tree6f8e33d410f21eec6fafc586b6775af1c4fd0bc6 /src/liballoc/tests
parentc0e02ad724f05f73b957b3d6f6314a9a2e5c284e (diff)
downloadrust-a859ca5c87ddfaa635fb4cacf8a41e04fd9b02e8.tar.gz
rust-a859ca5c87ddfaa635fb4cacf8a41e04fd9b02e8.zip
Fix `binary_heap::DrainSorted` drop leak on panics
Diffstat (limited to 'src/liballoc/tests')
-rw-r--r--src/liballoc/tests/binary_heap.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs
index f49ca713921..be5516f54f3 100644
--- a/src/liballoc/tests/binary_heap.rs
+++ b/src/liballoc/tests/binary_heap.rs
@@ -1,6 +1,8 @@
 use std::collections::binary_heap::{Drain, PeekMut};
 use std::collections::BinaryHeap;
 use std::iter::TrustedLen;
+use std::panic::{catch_unwind, AssertUnwindSafe};
+use std::sync::atomic::{AtomicU32, Ordering};
 
 #[test]
 fn test_iterator() {
@@ -276,6 +278,37 @@ fn test_drain_sorted() {
 }
 
 #[test]
+fn test_drain_sorted_leak() {
+    static DROPS: AtomicU32 = AtomicU32::new(0);
+
+    #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
+    struct D(u32, bool);
+
+    impl Drop for D {
+        fn drop(&mut self) {
+            DROPS.fetch_add(1, Ordering::SeqCst);
+
+            if self.1 {
+                panic!("panic in `drop`");
+            }
+        }
+    }
+
+    let mut q = BinaryHeap::from(vec![
+        D(0, false),
+        D(1, false),
+        D(2, false),
+        D(3, true),
+        D(4, false),
+        D(5, false),
+    ]);
+
+    catch_unwind(AssertUnwindSafe(|| drop(q.drain_sorted()))).ok();
+
+    assert_eq!(DROPS.load(Ordering::SeqCst), 6);
+}
+
+#[test]
 fn test_extend_ref() {
     let mut a = BinaryHeap::new();
     a.push(1);