Skip to content

Commit 539f208

Browse files
committed
Auto merge of #44129 - pnkfelix:fix-end-region-emission-order, r=nmatsakis
Fix end region emission order Fix #43481
2 parents 824952f + 5fa0b66 commit 539f208

14 files changed

+319
-23
lines changed

src/librustc_mir/build/scope.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -352,14 +352,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
352352
}
353353
let scope = self.scopes.pop().unwrap();
354354
assert_eq!(scope.region_scope, region_scope.0);
355+
356+
self.cfg.push_end_region(self.hir.tcx(), block, region_scope.1, scope.region_scope);
355357
unpack!(block = build_scope_drops(&mut self.cfg,
356358
&scope,
357359
&self.scopes,
358360
block,
359361
self.arg_count,
360362
false));
361363

362-
self.cfg.push_end_region(self.hir.tcx(), block, region_scope.1, scope.region_scope);
363364
block.unit()
364365
}
365366

@@ -406,15 +407,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
406407
scope.cached_exits.insert((target, region_scope.0), b);
407408
b
408409
};
410+
411+
// End all regions for scopes out of which we are breaking.
412+
self.cfg.push_end_region(self.hir.tcx(), block, region_scope.1, scope.region_scope);
413+
409414
unpack!(block = build_scope_drops(&mut self.cfg,
410415
scope,
411416
rest,
412417
block,
413418
self.arg_count,
414419
false));
415-
416-
// End all regions for scopes out of which we are breaking.
417-
self.cfg.push_end_region(self.hir.tcx(), block, region_scope.1, scope.region_scope);
418420
}
419421
}
420422
let scope = &self.scopes[len - scope_count];

src/test/mir-opt/end_region_1.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ fn main() {
3030
// StorageLive(_2);
3131
// _2 = &'10_1rs _1;
3232
// _0 = ();
33-
// StorageDead(_2);
3433
// EndRegion('10_1rs);
34+
// StorageDead(_2);
3535
// StorageDead(_1);
3636
// return;
3737
// }

src/test/mir-opt/end_region_2.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ fn main() {
4646
// bb2: {
4747
// _0 = ();
4848
// StorageDead(_5);
49-
// StorageDead(_3);
5049
// EndRegion('23_1rs);
50+
// StorageDead(_3);
5151
// StorageDead(_2);
5252
// return;
5353
// }
@@ -56,10 +56,10 @@ fn main() {
5656
// StorageLive(_7);
5757
// _7 = &'23_3rs _2;
5858
// _1 = ();
59-
// StorageDead(_7);
6059
// EndRegion('23_3rs);
61-
// StorageDead(_3);
60+
// StorageDead(_7);
6261
// EndRegion('23_1rs);
62+
// StorageDead(_3);
6363
// StorageDead(_2);
6464
// goto -> bb1;
6565
// }

src/test/mir-opt/end_region_3.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ fn main() {
4949
// bb2: {
5050
// _0 = ();
5151
// StorageDead(_5);
52-
// StorageDead(_3);
5352
// EndRegion('26_1rs);
53+
// StorageDead(_3);
5454
// StorageDead(_1);
5555
// return;
5656
// }
@@ -60,10 +60,10 @@ fn main() {
6060
// StorageLive(_7);
6161
// _7 = &'26_3rs _1;
6262
// _2 = ();
63-
// StorageDead(_7);
6463
// EndRegion('26_3rs);
65-
// StorageDead(_3);
64+
// StorageDead(_7);
6665
// EndRegion('26_1rs);
66+
// StorageDead(_3);
6767
// goto -> bb1;
6868
// }
6969
// END rustc.node4.SimplifyCfg-qualify-consts.after.mir

src/test/mir-opt/end_region_4.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ fn foo(i: i32) {
5353
// StorageLive(_6);
5454
// _6 = &'26_4rs _2;
5555
// _0 = ();
56-
// StorageDead(_6);
5756
// EndRegion('26_4rs);
58-
// StorageDead(_3);
57+
// StorageDead(_6);
5958
// EndRegion('26_2rs);
59+
// StorageDead(_3);
6060
// StorageDead(_2);
6161
// drop(_1) -> bb4;
6262
// }

src/test/mir-opt/end_region_5.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
4444
// _2 = const foo(_3) -> [return: bb1, unwind: bb3];
4545
// }
4646
// bb1: {
47-
// StorageDead(_3);
4847
// EndRegion('14s);
48+
// StorageDead(_3);
4949
// _0 = ();
5050
// drop(_1) -> bb4;
5151
// }

src/test/mir-opt/end_region_6.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
4444
// _2 = const foo(_3) -> [return: bb1, unwind: bb3];
4545
// }
4646
// bb1: {
47-
// StorageDead(_3);
4847
// EndRegion('19s);
48+
// StorageDead(_3);
4949
// _0 = ();
5050
// drop(_1) -> bb4;
5151
// }
@@ -75,8 +75,8 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
7575
// _3 = ((*_2).0: i32);
7676
// _0 = _3;
7777
// StorageDead(_3);
78-
// StorageDead(_2);
7978
// EndRegion('15_0rs);
79+
// StorageDead(_2);
8080
// return;
8181
// }
8282
// END rustc.node22.SimplifyCfg-qualify-consts.after.mir

src/test/mir-opt/end_region_7.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
8484
// _3 = ((*_2).0: i32);
8585
// _0 = _3;
8686
// StorageDead(_3);
87-
// StorageDead(_2);
8887
// EndRegion('15_0rs);
88+
// StorageDead(_2);
8989
// drop(_1) -> bb1;
9090
// }
9191
// bb1: {

src/test/mir-opt/end_region_8.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
5050
// bb1: {
5151
// StorageDead(_4);
5252
// _0 = ();
53-
// StorageDead(_2);
5453
// EndRegion('21_1rs);
54+
// StorageDead(_2);
5555
// drop(_1) -> bb4;
5656
// }
5757
// bb2: {

src/test/mir-opt/end_region_9.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ fn main() {
4242
// let mut _0: ();
4343
// let mut _1: bool;
4444
// let _2: i32;
45-
// let mut _4: &'13_0rs i32;
45+
// let mut _4: &'33_0rs i32;
4646
// let mut _3: ();
4747
// let mut _5: !;
4848
// let mut _6: ();
@@ -67,19 +67,20 @@ fn main() {
6767
// bb2: {
6868
// _0 = ();
6969
// StorageDead(_7);
70+
// EndRegion('33_0rs);
7071
// StorageDead(_4);
71-
// EndRegion('13_0rs);
7272
// StorageDead(_2);
7373
// StorageDead(_1);
7474
// return;
7575
// }
7676
//
7777
// bb3: {
78-
// _4 = &'13_0rs _2;
78+
// _4 = &'33_0rs _2;
7979
// _6 = ();
8080
// StorageDead(_7);
8181
// _1 = const true;
8282
// _3 = ();
8383
// goto -> bb1;
8484
// }
8585
// }
86+
// END rustc.node4.SimplifyCfg-qualify-consts.after.mir

src/test/mir-opt/end_region_cyclic.rs

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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+
// This test models a scenario with a cyclic reference. Rust obviously
15+
// needs to handle such cases.
16+
//
17+
// The interesting part about this test is that such case shows that
18+
// one cannot generally force all references to be dead before you hit
19+
// their EndRegion; at least, not without breaking the more important
20+
// property that all borrowed storage locations have their regions
21+
// ended strictly before their StorageDeads. (This test was inspired
22+
// by discussion on Issue #43481.)
23+
24+
use std::cell::Cell;
25+
26+
struct S<'a> {
27+
r: Cell<Option<&'a S<'a>>>,
28+
}
29+
30+
fn main() {
31+
loop {
32+
let x = S { r: Cell::new(None) };
33+
x.r.set(Some(&x));
34+
if query() { break; }
35+
x.r.set(Some(&x));
36+
}
37+
}
38+
39+
fn query() -> bool { true }
40+
41+
// END RUST SOURCE
42+
// START rustc.node16.SimplifyCfg-qualify-consts.after.mir
43+
// fn main() -> () {
44+
// let mut _0: ();
45+
// scope 1 {
46+
// let _2: S<'35_0rs>;
47+
// }
48+
// let mut _1: ();
49+
// let mut _3: std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>;
50+
// let mut _4: std::option::Option<&'35_0rs S<'35_0rs>>;
51+
// let mut _5: ();
52+
// let mut _6: &'16s std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>;
53+
// let mut _7: std::option::Option<&'35_0rs S<'35_0rs>>;
54+
// let mut _8: &'35_0rs S<'35_0rs>;
55+
// let mut _9: &'35_0rs S<'35_0rs>;
56+
// let mut _10: ();
57+
// let mut _11: bool;
58+
// let mut _12: !;
59+
// let mut _13: ();
60+
// let mut _14: &'33s std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>;
61+
// let mut _15: std::option::Option<&'35_0rs S<'35_0rs>>;
62+
// let mut _16: &'35_0rs S<'35_0rs>;
63+
// let mut _17: &'35_0rs S<'35_0rs>;
64+
// bb0: {
65+
// goto -> bb1;
66+
// }
67+
// bb1: {
68+
// StorageLive(_2);
69+
// StorageLive(_3);
70+
// StorageLive(_4);
71+
// _4 = std::option::Option<&'35_0rs S<'35_0rs>>::None;
72+
// _3 = const <std::cell::Cell<T>>::new(_4) -> bb2;
73+
// }
74+
// bb2: {
75+
// StorageDead(_4);
76+
// _2 = S<'35_0rs> { r: _3 };
77+
// StorageDead(_3);
78+
// StorageLive(_6);
79+
// _6 = &'16s (_2.0: std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>);
80+
// StorageLive(_7);
81+
// StorageLive(_8);
82+
// StorageLive(_9);
83+
// _9 = &'35_0rs _2;
84+
// _8 = &'35_0rs (*_9);
85+
// _7 = std::option::Option<&'35_0rs S<'35_0rs>>::Some(_8,);
86+
// StorageDead(_8);
87+
// _5 = const <std::cell::Cell<T>>::set(_6, _7) -> bb3;
88+
// }
89+
// bb3: {
90+
// EndRegion('16s);
91+
// StorageDead(_7);
92+
// StorageDead(_6);
93+
// StorageDead(_9);
94+
// StorageLive(_11);
95+
// _11 = const query() -> bb4;
96+
// }
97+
// bb4: {
98+
// switchInt(_11) -> [0u8: bb6, otherwise: bb5];
99+
// }
100+
// bb5: {
101+
// _0 = ();
102+
// StorageDead(_11);
103+
// EndRegion('35_0rs);
104+
// StorageDead(_2);
105+
// return;
106+
// }
107+
// bb6: {
108+
// _10 = ();
109+
// StorageDead(_11);
110+
// StorageLive(_14);
111+
// _14 = &'33s (_2.0: std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>);
112+
// StorageLive(_15);
113+
// StorageLive(_16);
114+
// StorageLive(_17);
115+
// _17 = &'35_0rs _2;
116+
// _16 = &'35_0rs (*_17);
117+
// _15 = std::option::Option<&'35_0rs S<'35_0rs>>::Some(_16,);
118+
// StorageDead(_16);
119+
// _13 = const <std::cell::Cell<T>>::set(_14, _15) -> bb7;
120+
// }
121+
// bb7: {
122+
// EndRegion('33s);
123+
// StorageDead(_15);
124+
// StorageDead(_14);
125+
// StorageDead(_17);
126+
// _1 = ();
127+
// EndRegion('35_0rs);
128+
// StorageDead(_2);
129+
// goto -> bb1;
130+
// }
131+
// }
132+
// END rustc.node16.SimplifyCfg-qualify-consts.after.mir

0 commit comments

Comments
 (0)