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