]> git.lizzy.rs Git - rust.git/blob - src/test/mir-opt/end_region_cyclic.rs
Rollup merge of #53545 - FelixMcFelix:fix-50865-beta, r=petrochenkov
[rust.git] / src / test / mir-opt / end_region_cyclic.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 // 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.main.SimplifyCfg-qualify-consts.after.mir
43 // fn main() -> (){
44 //     let mut _0: ();
45 //     scope 1 {
46 //     }
47 //     scope 2 {
48 //         let _2: S<'36_0rs>;
49 //     }
50 //     let mut _1: ();
51 //     let mut _3: std::cell::Cell<std::option::Option<&'36_0rs S<'36_0rs>>>;
52 //     let mut _4: std::option::Option<&'36_0rs S<'36_0rs>>;
53 //     let mut _5: ();
54 //     let mut _6: &'17s std::cell::Cell<std::option::Option<&'36_0rs S<'36_0rs>>>;
55 //     let mut _7: std::option::Option<&'36_0rs S<'36_0rs>>;
56 //     let mut _8: &'36_0rs S<'36_0rs>;
57 //     let mut _9: &'36_0rs S<'36_0rs>;
58 //     let mut _10: ();
59 //     let mut _11: bool;
60 //     let mut _12: !;
61 //     let mut _13: ();
62 //     let mut _14: &'34s std::cell::Cell<std::option::Option<&'36_0rs S<'36_0rs>>>;
63 //     let mut _15: std::option::Option<&'36_0rs S<'36_0rs>>;
64 //     let mut _16: &'36_0rs S<'36_0rs>;
65 //     let mut _17: &'36_0rs S<'36_0rs>;
66 //     bb0: {
67 //         goto -> bb1;
68 //     }
69 //     bb1: {
70 //         falseUnwind -> [real: bb2, cleanup: bb3];
71 //     }
72 //     bb2: {
73 //         StorageLive(_2);
74 //         StorageLive(_3);
75 //         StorageLive(_4);
76 //         _4 = std::option::Option<&'36_0rs S<'36_0rs>>::None;
77 //         _3 = const <std::cell::Cell<T>>::new(move _4) -> [return: bb4, unwind: bb3];
78 //     }
79 //     bb3: {
80 //         resume;
81 //     }
82 //     bb4: {
83 //         StorageDead(_4);
84 //         _2 = S<'36_0rs> { r: move _3 };
85 //         StorageDead(_3);
86 //         StorageLive(_6);
87 //         _6 = &'17s (_2.0: std::cell::Cell<std::option::Option<&'36_0rs S<'36_0rs>>>);
88 //         StorageLive(_7);
89 //         StorageLive(_8);
90 //         StorageLive(_9);
91 //         _9 = &'36_0rs _2;
92 //         _8 = &'36_0rs (*_9);
93 //         _7 = std::option::Option<&'36_0rs S<'36_0rs>>::Some(move _8,);
94 //         StorageDead(_8);
95 //         _5 = const <std::cell::Cell<T>>::set(move _6, move _7) -> [return: bb5, unwind: bb3];
96 //     }
97 //     bb5: {
98 //         EndRegion('17s);
99 //         StorageDead(_7);
100 //         StorageDead(_6);
101 //         StorageDead(_9);
102 //         StorageLive(_11);
103 //         _11 = const query() -> [return: bb6, unwind: bb3];
104 //     }
105 //     bb6: {
106 //         switchInt(move _11) -> [false: bb8, otherwise: bb7];
107 //     }
108 //     bb7: {
109 //         _0 = ();
110 //         StorageDead(_11);
111 //         EndRegion('36_0rs);
112 //         StorageDead(_2);
113 //         return;
114 //     }
115 //     bb8: {
116 //         _10 = ();
117 //         StorageDead(_11);
118 //         StorageLive(_14);
119 //         _14 = &'34s (_2.0: std::cell::Cell<std::option::Option<&'36_0rs S<'36_0rs>>>);
120 //         StorageLive(_15);
121 //         StorageLive(_16);
122 //         StorageLive(_17);
123 //         _17 = &'36_0rs _2;
124 //         _16 = &'36_0rs (*_17);
125 //         _15 = std::option::Option<&'36_0rs S<'36_0rs>>::Some(move _16,);
126 //         StorageDead(_16);
127 //         _13 = const <std::cell::Cell<T>>::set(move _14, move _15) -> [return: bb9, unwind: bb3];
128 //     }
129 //     bb9: {
130 //         EndRegion('34s);
131 //         StorageDead(_15);
132 //         StorageDead(_14);
133 //         StorageDead(_17);
134 //         _1 = ();
135 //         EndRegion('36_0rs);
136 //         StorageDead(_2);
137 //         goto -> bb1;
138 //     }
139 // }
140 // END rustc.main.SimplifyCfg-qualify-consts.after.mir