]> git.lizzy.rs Git - rust.git/blob - src/test/mir-opt/end_region_cyclic.rs
Update the tools CI to use --no-fail-fast and --save-toolstates.
[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 //     bb0: {
66 //         goto -> bb1;
67 //     }
68 //     bb1: {
69 //         StorageLive(_2);
70 //         StorageLive(_3);
71 //         StorageLive(_4);
72 //         _4 = std::option::Option<&'35_0rs S<'35_0rs>>::None;
73 //         _3 = const <std::cell::Cell<T>>::new(move _4) -> bb2;
74 //     }
75 //     bb2: {
76 //         StorageDead(_4);
77 //         _2 = S<'35_0rs> { r: move _3 };
78 //         StorageDead(_3);
79 //         StorageLive(_6);
80 //         _6 = &'16s (_2.0: std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>);
81 //         StorageLive(_7);
82 //         StorageLive(_8);
83 //         StorageLive(_9);
84 //         _9 = &'35_0rs _2;
85 //         _8 = &'35_0rs (*_9);
86 //         _7 = std::option::Option<&'35_0rs S<'35_0rs>>::Some(move _8,);
87 //         StorageDead(_8);
88 //         _5 = const <std::cell::Cell<T>>::set(move _6, move _7) -> bb3;
89 //     }
90 //     bb3: {
91 //         EndRegion('16s);
92 //         StorageDead(_7);
93 //         StorageDead(_6);
94 //         StorageDead(_9);
95 //         StorageLive(_11);
96 //         _11 = const query() -> bb4;
97 //     }
98 //     bb4: {
99 //         switchInt(move _11) -> [0u8: bb6, otherwise: bb5];
100 //     }
101 //     bb5: {
102 //         _0 = ();
103 //         StorageDead(_11);
104 //         EndRegion('35_0rs);
105 //         StorageDead(_2);
106 //         return;
107 //     }
108 //     bb6: {
109 //         _10 = ();
110 //         StorageDead(_11);
111 //         StorageLive(_14);
112 //         _14 = &'33s (_2.0: std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>);
113 //         StorageLive(_15);
114 //         StorageLive(_16);
115 //         StorageLive(_17);
116 //         _17 = &'35_0rs _2;
117 //         _16 = &'35_0rs (*_17);
118 //         _15 = std::option::Option<&'35_0rs S<'35_0rs>>::Some(move _16,);
119 //         StorageDead(_16);
120 //         _13 = const <std::cell::Cell<T>>::set(move _14, move_15) -> bb7;
121 //     }
122 //     bb7: {
123 //         EndRegion('33s);
124 //         StorageDead(_15);
125 //         StorageDead(_14);
126 //         StorageDead(_17);
127 //         _1 = ();
128 //         EndRegion('35_0rs);
129 //         StorageDead(_2);
130 //         goto -> bb1;
131 //     }
132 // }
133 // END rustc.main.SimplifyCfg-qualify-consts.after.mir