1 // run-pass
2
3 //! Test that let bindings and destructuring assignments have consistent drop orders
4
5 #![allow(unused_variables, unused_assignments)]
6
7 use std::cell::RefCell;
8
9 thread_local! {
10 static DROP_ORDER: RefCell<Vec<usize>> = RefCell::new(Vec::new());
11 }
12
13 struct DropRecorder(usize);
14 impl Drop for DropRecorder {
drop(&mut self)15 fn drop(&mut self) {
16 DROP_ORDER.with(|d| d.borrow_mut().push(self.0));
17 }
18 }
19
main()20 fn main() {
21 let expected_drop_order = vec![1, 4, 5, 3, 2];
22 // Check the drop order for let bindings:
23 {
24 let _ = DropRecorder(1);
25 let _val = DropRecorder(2);
26 let (x, _) = (DropRecorder(3), DropRecorder(4));
27 drop(DropRecorder(5));
28 }
29 DROP_ORDER.with(|d| {
30 assert_eq!(&*d.borrow(), &expected_drop_order);
31 d.borrow_mut().clear();
32 });
33 // Check that the drop order for destructuring assignment is the same:
34 {
35 let _val;
36 let x;
37 _ = DropRecorder(1);
38 _val = DropRecorder(2);
39 (x, _) = (DropRecorder(3), DropRecorder(4));
40 drop(DropRecorder(5));
41 }
42 DROP_ORDER.with(|d| assert_eq!(&*d.borrow(), &expected_drop_order));
43 }
44