]> git.lizzy.rs Git - rust.git/blob - src/test/mir-opt/end_region_cyclic.rs
Rollup merge of #44513 - redox-os:master, r=alexcrichton
[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.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