2018-08-30 07:18:55 -05:00
|
|
|
// run-pass
|
2018-09-25 16:51:35 -05:00
|
|
|
#![allow(unreachable_code)]
|
2016-01-11 11:32:28 -06:00
|
|
|
// 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();
|
|
|
|
}
|