| //@ 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)); | |
| } |