about summary refs log tree commit diff
path: root/tests/ui/destructuring-assignment/drop-order.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/destructuring-assignment/drop-order.rs')
-rw-r--r--tests/ui/destructuring-assignment/drop-order.rs43
1 files changed, 43 insertions, 0 deletions
diff --git a/tests/ui/destructuring-assignment/drop-order.rs b/tests/ui/destructuring-assignment/drop-order.rs
new file mode 100644
index 00000000000..79671054ca7
--- /dev/null
+++ b/tests/ui/destructuring-assignment/drop-order.rs
@@ -0,0 +1,43 @@
+// run-pass
+
+//! Test that let bindings and destructuring assignments have consistent drop orders
+
+#![allow(unused_variables, unused_assignments)]
+
+use std::cell::RefCell;
+
+thread_local! {
+    static DROP_ORDER: RefCell<Vec<usize>> = RefCell::new(Vec::new());
+}
+
+struct DropRecorder(usize);
+impl Drop for DropRecorder {
+    fn drop(&mut self) {
+        DROP_ORDER.with(|d| d.borrow_mut().push(self.0));
+    }
+}
+
+fn main() {
+    let expected_drop_order = vec![1, 4, 5, 3, 2];
+    // Check the drop order for let bindings:
+    {
+        let _ = DropRecorder(1);
+        let _val = DropRecorder(2);
+        let (x, _) = (DropRecorder(3), DropRecorder(4));
+        drop(DropRecorder(5));
+    }
+    DROP_ORDER.with(|d| {
+        assert_eq!(&*d.borrow(), &expected_drop_order);
+        d.borrow_mut().clear();
+    });
+    // Check that the drop order for destructuring assignment is the same:
+    {
+        let _val;
+        let x;
+        _ = DropRecorder(1);
+        _val = DropRecorder(2);
+        (x, _) = (DropRecorder(3), DropRecorder(4));
+        drop(DropRecorder(5));
+    }
+    DROP_ORDER.with(|d| assert_eq!(&*d.borrow(), &expected_drop_order));
+}