]> git.lizzy.rs Git - rust.git/blob - src/test/mir-opt/end_region_destruction_extents_1.rs
Auto merge of #46393 - kennytm:45861-step-2-3-make-tools-job-not-fail-fast, r=alexcri...
[rust.git] / src / test / mir-opt / end_region_destruction_extents_1.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // compile-flags: -Z identify_regions -Z span_free_formats -Z emit-end-regions
12 // ignore-tidy-linelength
13
14 // A scenario with significant destruction code extents (which have
15 // suffix "dce" in current `-Z identify_regions` rendering).
16
17 #![feature(generic_param_attrs)]
18 #![feature(dropck_eyepatch)]
19
20 fn main() {
21     // Since the second param to `D1` is may_dangle, it is legal for
22     // the region of that parameter to end before the drop code for D1
23     // is executed.
24     (D1(&S1("ex1"), &S1("dang1"))).0;
25 }
26
27 #[derive(Debug)]
28 struct S1(&'static str);
29
30 #[derive(Debug)]
31 struct D1<'a, 'b>(&'a S1, &'b S1);
32
33 // The `#[may_dangle]` means that references of type `&'b _` may be
34 // invalid during the execution of this destructor; i.e. in this case
35 // the destructor code is not allowed to read or write `*self.1`, while
36 // it can read/write `*self.0`.
37 unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> {
38     fn drop(&mut self) {
39         println!("D1({:?}, _)", self.0);
40     }
41 }
42
43 // Notes on the MIR output below:
44 //
45 // 1. The `EndRegion('10s)` is allowed to precede the `drop(_3)`
46 //    solely because of the #[may_dangle] mentioned above.
47 //
48 // 2. Regarding the occurrence of `EndRegion('12ds)` *after* `StorageDead(_6)`
49 //    (where we have borrows `&'12ds _6`): Eventually:
50 //
51 //    i. this code should be rejected (by mir-borrowck), or
52 //
53 //    ii. the MIR code generation should be changed so that the
54 //        EndRegion('12ds)` precedes `StorageDead(_6)` in the
55 //        control-flow.  (Note: arielb1 views drop+storagedead as one
56 //        unit, and does not see this option as a useful avenue to
57 //        explore.), or
58 //
59 //    iii. the presence of EndRegion should be made irrelevant by a
60 //        transformation encoding the effects of rvalue-promotion.
61 //        This may be the simplest and most-likely option; note in
62 //        particular that `StorageDead(_6)` goes away below in
63 //        rustc.main.QualifyAndPromoteConstants.after.mir
64
65 // END RUST SOURCE
66
67 // START rustc.main.QualifyAndPromoteConstants.before.mir
68 // fn main() -> () {
69 //     let mut _0: ();
70 //     let mut _1: &'12ds S1;
71 //     let mut _2: &'12ds S1;
72 //     let mut _3: D1<'12ds, '10s>;
73 //     let mut _4: &'12ds S1;
74 //     let mut _5: &'12ds S1;
75 //     let mut _6: S1;
76 //     let mut _7: &'10s S1;
77 //     let mut _8: &'10s S1;
78 //     let mut _9: S1;
79 //
80 //     bb0: {
81 //         StorageLive(_2);
82 //         StorageLive(_3);
83 //         StorageLive(_4);
84 //         StorageLive(_5);
85 //         StorageLive(_6);
86 //         _6 = S1::{{constructor}}(const "ex1",);
87 //         _5 = &'12ds _6;
88 //         _4 = &'12ds (*_5);
89 //         StorageLive(_7);
90 //         StorageLive(_8);
91 //         StorageLive(_9);
92 //         _9 = S1::{{constructor}}(const "dang1",);
93 //         _8 = &'10s _9;
94 //         _7 = &'10s (*_8);
95 //         _3 = D1<'12ds, '10s>::{{constructor}}(move _4, move _7);
96 //         EndRegion('10s);
97 //         StorageDead(_7);
98 //         StorageDead(_4);
99 //         _2 = (_3.0: &'12ds S1);
100 //         _1 = move _2;
101 //         StorageDead(_2);
102 //         drop(_3) -> [return: bb2, unwind: bb1];
103 //     }
104 //
105 //     bb1: {
106 //         resume;
107 //     }
108 //
109 //     bb2: {
110 //         StorageDead(_3);
111 //         StorageDead(_8);
112 //         StorageDead(_9);
113 //         StorageDead(_5);
114 //         StorageDead(_6);
115 //         EndRegion('12ds);
116 //         _0 = ();
117 //         return;
118 //     }
119 // }
120 // END rustc.main.QualifyAndPromoteConstants.before.mir
121
122 // START rustc.main.QualifyAndPromoteConstants.after.mir
123 // fn main() -> () {
124 //     let mut _0: ();
125 //     let mut _1: &'12ds S1;
126 //     let mut _2: &'12ds S1;
127 //     let mut _3: D1<'12ds, '10s>;
128 //     let mut _4: &'12ds S1;
129 //     let mut _5: &'12ds S1;
130 //     let mut _6: S1;
131 //     let mut _7: &'10s S1;
132 //     let mut _8: &'10s S1;
133 //     let mut _9: S1;
134 //
135 //     bb0: {
136 //         StorageLive(_2);
137 //         StorageLive(_3);
138 //         StorageLive(_4);
139 //         StorageLive(_5);
140 //         _5 = promoted[1];
141 //         _4 = &'12ds (*_5);
142 //         StorageLive(_7);
143 //         StorageLive(_8);
144 //         _8 = promoted[0];
145 //         _7 = &'10s (*_8);
146 //         _3 = D1<'12ds, '10s>::{{constructor}}(move _4, move _7);
147 //         EndRegion('10s);
148 //         StorageDead(_7);
149 //         StorageDead(_4);
150 //         _2 = (_3.0: &'12ds S1);
151 //         _1 = move _2;
152 //         StorageDead(_2);
153 //         drop(_3) -> [return: bb2, unwind: bb1];
154 //     }
155 //
156 //     bb1: {
157 //         resume;
158 //     }
159 //
160 //     bb2: {
161 //         StorageDead(_3);
162 //         StorageDead(_8);
163 //         StorageDead(_5);
164 //         EndRegion('12ds);
165 //         _0 = ();
166 //         return;
167 //     }
168 // }
169 // END rustc.main.QualifyAndPromoteConstants.after.mir