1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
// 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();
}
|