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(generic_param_attrs)]
18 #![feature(dropck_eyepatch)]
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
24 (D1(&S1("ex1"), &S1("dang1"))).0;
28 struct S1(&'static str);
31 struct D1<'a, 'b>(&'a S1, &'b S1);
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> {
39 println!("D1({:?}, _)", self.0);
43 // Notes on the MIR output below:
45 // 1. The `EndRegion('10s)` is allowed to precede the `drop(_3)`
46 // solely because of the #[may_dangle] mentioned above.
48 // 2. Regarding the occurrence of `EndRegion('12ds)` *after* `StorageDead(_6)`
49 // (where we have borrows `&'12ds _6`): Eventually:
51 // i. this code should be rejected (by mir-borrowck), or
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
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
67 // START rustc.main.QualifyAndPromoteConstants.before.mir
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;
76 // let mut _7: &'10s S1;
77 // let mut _8: &'10s S1;
86 // _6 = S1::{{constructor}}(const "ex1",);
92 // _9 = S1::{{constructor}}(const "dang1",);
95 // _3 = D1<'12ds, '10s>::{{constructor}}(_4, _7);
99 // _2 = (_3.0: &'12ds S1);
116 // END rustc.main.QualifyAndPromoteConstants.before.mir
118 // START rustc.main.QualifyAndPromoteConstants.after.mir
121 // let mut _1: &'12ds S1;
122 // let mut _2: &'12ds S1;
123 // let mut _3: D1<'12ds, '10s>;
124 // let mut _4: &'12ds S1;
125 // let mut _5: &'12ds S1;
127 // let mut _7: &'10s S1;
128 // let mut _8: &'10s S1;
137 // _4 = &'12ds (*_5);
142 // _3 = D1<'12ds, '10s>::{{constructor}}(_4, _7);
146 // _2 = (_3.0: &'12ds S1);
161 // END rustc.main.QualifyAndPromoteConstants.after.mir