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