//@ run-pass #![allow(unreachable_code)] // More thorough regression test for Issues #30018 and #30822. This // attempts to explore different ways that array element construction // (for both scratch arrays and non-scratch ones) interacts with // breaks in the control-flow, in terms of the order of evaluation of // the destructors (which may change; see RFC Issue 744) and the // number of times that the destructor evaluates for each value (which // should never exceed 1; this latter case is what #30822 is about). use std::cell::RefCell; struct D<'a>(&'a RefCell>, i32); impl<'a> Drop for D<'a> { fn drop(&mut self) { println!("Dropping D({})", self.1); (self.0).borrow_mut().push(self.1); } } fn main() { println!("Start"); break_during_elem(); break_after_whole(); println!("Finis"); } fn break_during_elem() { let log = &RefCell::new(Vec::new()); // CASE 1: Fixed-size array itself is stored in _r slot. loop { let _r = [D(log, 10), D(log, 11), { D(log, 12); break; }, D(log, 13)]; } assert_eq!(&log.borrow()[..], &[12, 11, 10]); log.borrow_mut().clear(); // CASE 2: Slice (borrow of array) is stored in _r slot. // This is the case that is actually being reported in #30018. loop { let _r = &[D(log, 20), D(log, 21), { D(log, 22); break; }, D(log, 23)]; } assert_eq!(&log.borrow()[..], &[22, 21, 20]); log.borrow_mut().clear(); // CASE 3: (Borrow of) slice-index of array is stored in _r slot. loop { let _r = &[D(log, 30), D(log, 31), { D(log, 32); break; }, D(log, 33)][..]; } assert_eq!(&log.borrow()[..], &[32, 31, 30]); log.borrow_mut().clear(); } // The purpose of these functions is to test what happens when we // panic after an array has been constructed in its entirety. // // It is meant to act as proof that we still need to continue // scheduling the destruction of an array even after we've scheduling // drop for its elements during construction; the latter is tested by // `fn break_during_elem()`. fn break_after_whole() { let log = &RefCell::new(Vec::new()); // CASE 1: Fixed-size array itself is stored in _r slot. loop { let _r = [D(log, 10), D(log, 11), D(log, 12)]; break; } assert_eq!(&log.borrow()[..], &[10, 11, 12]); log.borrow_mut().clear(); // CASE 2: Slice (borrow of array) is stored in _r slot. loop { let _r = &[D(log, 20), D(log, 21), D(log, 22)]; break; } assert_eq!(&log.borrow()[..], &[20, 21, 22]); log.borrow_mut().clear(); // CASE 3: (Borrow of) slice-index of array is stored in _r slot. loop { let _r = &[D(log, 30), D(log, 31), D(log, 32)][..]; break; } assert_eq!(&log.borrow()[..], &[30, 31, 32]); log.borrow_mut().clear(); }