| //@ 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<Vec<i32>>, 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(); | 
 | } |