]> git.lizzy.rs Git - rust.git/blob - src/test/ui/issues/issue-30018-nopanic.rs
Auto merge of #78066 - bugadani:wat, r=jonas-schievink
[rust.git] / src / test / ui / issues / issue-30018-nopanic.rs
1 // run-pass
2 #![allow(unreachable_code)]
3 // More thorough regression test for Issues #30018 and #30822. This
4 // attempts to explore different ways that array element construction
5 // (for both scratch arrays and non-scratch ones) interacts with
6 // breaks in the control-flow, in terms of the order of evaluation of
7 // the destructors (which may change; see RFC Issue 744) and the
8 // number of times that the destructor evaluates for each value (which
9 // should never exceed 1; this latter case is what #30822 is about).
10
11 use std::cell::RefCell;
12
13 struct D<'a>(&'a RefCell<Vec<i32>>, i32);
14
15 impl<'a> Drop for D<'a> {
16     fn drop(&mut self) {
17         println!("Dropping D({})", self.1);
18         (self.0).borrow_mut().push(self.1);
19     }
20 }
21
22 fn main() {
23     println!("Start");
24     break_during_elem();
25     break_after_whole();
26     println!("Finis");
27 }
28
29 fn break_during_elem() {
30     let log = &RefCell::new(Vec::new());
31
32     // CASE 1: Fixed-size array itself is stored in _r slot.
33     loop {
34         let _r = [D(log, 10),
35                   D(log, 11),
36                   { D(log, 12); break; },
37                   D(log, 13)];
38     }
39     assert_eq!(&log.borrow()[..], &[12, 11, 10]);
40     log.borrow_mut().clear();
41
42     // CASE 2: Slice (borrow of array) is stored in _r slot.
43     // This is the case that is actually being reported in #30018.
44     loop {
45         let _r = &[D(log, 20),
46                    D(log, 21),
47                    { D(log, 22); break; },
48                    D(log, 23)];
49     }
50     assert_eq!(&log.borrow()[..], &[22, 21, 20]);
51     log.borrow_mut().clear();
52
53     // CASE 3: (Borrow of) slice-index of array is stored in _r slot.
54     loop {
55         let _r = &[D(log, 30),
56                   D(log, 31),
57                   { D(log, 32); break; },
58                   D(log, 33)][..];
59     }
60     assert_eq!(&log.borrow()[..], &[32, 31, 30]);
61     log.borrow_mut().clear();
62 }
63
64 // The purpose of these functions is to test what happens when we
65 // panic after an array has been constructed in its entirety.
66 //
67 // It is meant to act as proof that we still need to continue
68 // scheduling the destruction of an array even after we've scheduling
69 // drop for its elements during construction; the latter is tested by
70 // `fn break_during_elem()`.
71 fn break_after_whole() {
72     let log = &RefCell::new(Vec::new());
73
74     // CASE 1: Fixed-size array itself is stored in _r slot.
75     loop {
76         let _r = [D(log, 10),
77                   D(log, 11),
78                   D(log, 12)];
79         break;
80     }
81     assert_eq!(&log.borrow()[..], &[10, 11, 12]);
82     log.borrow_mut().clear();
83
84     // CASE 2: Slice (borrow of array) is stored in _r slot.
85     loop {
86         let _r = &[D(log, 20),
87                    D(log, 21),
88                    D(log, 22)];
89         break;
90     }
91     assert_eq!(&log.borrow()[..], &[20, 21, 22]);
92     log.borrow_mut().clear();
93
94     // CASE 3: (Borrow of) slice-index of array is stored in _r slot.
95     loop {
96         let _r = &[D(log, 30),
97                    D(log, 31),
98                    D(log, 32)][..];
99         break;
100     }
101     assert_eq!(&log.borrow()[..], &[30, 31, 32]);
102     log.borrow_mut().clear();
103 }