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.
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.
11 // compile-flags: -Z identify_regions -Z span_free_formats -Z emit-end-regions
12 // ignore-tidy-linelength
14 // A scenario with significant destruction code extents (which have
15 // suffix "dce" in current `-Z identify_regions` rendering).
17 #![feature(dropck_eyepatch)]
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
23 (D1(&S1("ex1"), &S1("dang1"))).0;
27 struct S1(&'static str);
30 struct D1<'a, 'b>(&'a S1, &'b S1);
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> {
38 println!("D1({:?}, _)", self.0);
42 // Notes on the MIR output below:
44 // 1. The `EndRegion('10s)` is allowed to precede the `drop(_3)`
45 // solely because of the #[may_dangle] mentioned above.
47 // 2. Regarding the occurrence of `EndRegion('12ds)` *after* `StorageDead(_6)`
48 // (where we have borrows `&'12ds _6`): Eventually:
50 // i. this code should be rejected (by mir-borrowck), or
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
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
66 // START rustc.main.QualifyAndPromoteConstants.before.mir
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;
74 // let mut _6: &'10s S1;
75 // let mut _7: &'10s S1;
82 // _5 = S1::{{constructor}}(const "ex1",);
88 // _8 = S1::{{constructor}}(const "dang1",);
91 // _2 = D1<'12ds, '10s>::{{constructor}}(move _3, move _6);
95 // _1 = (_2.0: &'12ds S1);
96 // drop(_2) -> [return: bb2, unwind: bb1];
112 // END rustc.main.QualifyAndPromoteConstants.before.mir
114 // START rustc.main.QualifyAndPromoteConstants.after.mir
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;
122 // let mut _6: &'10s S1;
123 // let mut _7: &'10s S1;
125 // let mut _9: &'10s S1;
126 // let mut _10: &'12ds S1;
131 // _10 = promoted[1];
132 // _4 = &'12ds (*_10);
133 // _3 = &'12ds (*_4);
139 // _2 = D1<'12ds, '10s>::{{constructor}}(move _3, move _6);
143 // _1 = (_2.0: &'12ds S1);
144 // drop(_2) -> [return: bb2, unwind: bb1];
158 // END rustc.main.QualifyAndPromoteConstants.after.mir