]> git.lizzy.rs Git - rust.git/blob - src/test/mir-opt/end_region_destruction_extents_1.rs
Auto merge of #51159 - pacman82:master, r=oli-obk
[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(dropck_eyepatch)]
18
19 fn main() {
20     // Since the second param to `D1` is may_dangle, it is legal for
21     // the region of that parameter to end before the drop code for D1
22     // is executed.
23     (D1(&S1("ex1"), &S1("dang1"))).0;
24 }
25
26 #[derive(Debug)]
27 struct S1(&'static str);
28
29 #[derive(Debug)]
30 struct D1<'a, 'b>(&'a S1, &'b S1);
31
32 // The `#[may_dangle]` means that references of type `&'b _` may be
33 // invalid during the execution of this destructor; i.e. in this case
34 // the destructor code is not allowed to read or write `*self.1`, while
35 // it can read/write `*self.0`.
36 unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> {
37     fn drop(&mut self) {
38         println!("D1({:?}, _)", self.0);
39     }
40 }
41
42 // Notes on the MIR output below:
43 //
44 // 1. The `EndRegion('10s)` is allowed to precede the `drop(_3)`
45 //    solely because of the #[may_dangle] mentioned above.
46 //
47 // 2. Regarding the occurrence of `EndRegion('12ds)` *after* `StorageDead(_6)`
48 //    (where we have borrows `&'12ds _6`): Eventually:
49 //
50 //    i. this code should be rejected (by mir-borrowck), or
51 //
52 //    ii. the MIR code generation should be changed so that the
53 //        EndRegion('12ds)` precedes `StorageDead(_6)` in the
54 //        control-flow.  (Note: arielb1 views drop+storagedead as one
55 //        unit, and does not see this option as a useful avenue to
56 //        explore.), or
57 //
58 //    iii. the presence of EndRegion should be made irrelevant by a
59 //        transformation encoding the effects of rvalue-promotion.
60 //        This may be the simplest and most-likely option; note in
61 //        particular that `StorageDead(_6)` goes away below in
62 //        rustc.main.QualifyAndPromoteConstants.after.mir
63
64 // END RUST SOURCE
65
66 // START rustc.main.QualifyAndPromoteConstants.before.mir
67 // fn main() -> () {
68 // let mut _0: ();
69 //     let mut _1: &'12ds S1;
70 //     let mut _2: D1<'12ds, '10s>;
71 //     let mut _3: &'12ds S1;
72 //     let mut _4: &'12ds S1;
73 //     let _5: S1;
74 //     let mut _6: &'10s S1;
75 //     let mut _7: &'10s S1;
76 //     let _8: S1;
77 //     bb0: {
78 //         StorageLive(_2);
79 //         StorageLive(_3);
80 //         StorageLive(_4);
81 //         StorageLive(_5);
82 //         _5 = S1::{{constructor}}(const "ex1",);
83 //         _4 = &'12ds _5;
84 //         _3 = &'12ds (*_4);
85 //         StorageLive(_6);
86 //         StorageLive(_7);
87 //         StorageLive(_8);
88 //         _8 = S1::{{constructor}}(const "dang1",);
89 //         _7 = &'10s _8;
90 //         _6 = &'10s (*_7);
91 //         _2 = D1<'12ds, '10s>::{{constructor}}(move _3, move _6);
92 //         EndRegion('10s);
93 //         StorageDead(_6);
94 //         StorageDead(_3);
95 //         _1 = (_2.0: &'12ds S1);
96 //         drop(_2) -> [return: bb2, unwind: bb1];
97 //     }
98 //     bb1: {
99 //         resume;
100 //     }
101 //     bb2: {
102 //         StorageDead(_2);
103 //         StorageDead(_7);
104 //         StorageDead(_8);
105 //         StorageDead(_4);
106 //         StorageDead(_5);
107 //         EndRegion('12ds);
108 //         _0 = ();
109 //         return;
110 //     }
111 // }
112 // END rustc.main.QualifyAndPromoteConstants.before.mir
113
114 // START rustc.main.QualifyAndPromoteConstants.after.mir
115 // fn main() -> (){
116 //     let mut _0: ();
117 //     let mut _1: &'12ds S1;
118 //     let mut _2: D1<'12ds, '10s>;
119 //     let mut _3: &'12ds S1;
120 //     let mut _4: &'12ds S1;
121 //     let _5: S1;
122 //     let mut _6: &'10s S1;
123 //     let mut _7: &'10s S1;
124 //     let _8: S1;
125 //     bb0: {
126 //         StorageLive(_2);
127 //         StorageLive(_3);
128 //         StorageLive(_4);
129 //         _4 = &'12ds (promoted[1]: S1);
130 //         _3 = &'12ds (*_4);
131 //         StorageLive(_6);
132 //         StorageLive(_7);
133 //         _7 = &'10s (promoted[0]: S1);
134 //         _6 = &'10s (*_7);
135 //         _2 = D1<'12ds, '10s>::{{constructor}}(move _3, move _6);
136 //         EndRegion('10s);
137 //         StorageDead(_6);
138 //         StorageDead(_3);
139 //         _1 = (_2.0: &'12ds S1);
140 //         drop(_2) -> [return: bb2, unwind: bb1];
141 //     }
142 //     bb1: {
143 //         resume;
144 //     }
145 //     bb2: {
146 //         StorageDead(_2);
147 //         StorageDead(_7);
148 //         StorageDead(_4);
149 //         EndRegion('12ds);
150 //         _0 = ();
151 //         return;
152 //     }
153 // }
154 // END rustc.main.QualifyAndPromoteConstants.after.mir