]> git.proxmox.com Git - rustc.git/blob - src/test/ui/issues/issue-30018-nopanic.rs
New upstream version 1.49.0+dfsg1
[rustc.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 }