]> git.lizzy.rs Git - rust.git/blob - src/test/mir-opt/match-arm-scopes.rs
Rollup merge of #65389 - ecstatic-morse:zero-sized-array-no-drop, r=eddyb
[rust.git] / src / test / mir-opt / match-arm-scopes.rs
1 // Test that StorageDead and Drops are generated properly for bindings in
2 // matches:
3 // * The MIR should only contain a single drop of `s` and `t`: at the end
4 //   of their respective arms.
5 // * StorageDead and StorageLive statements are correctly matched up on
6 //   non-unwind paths.
7 // * The visibility scopes of the match arms should be disjoint, and contain.
8 //   all of the bindings for that scope.
9 // * No drop flags are used.
10
11 fn complicated_match(cond: bool, items: (bool, bool, String)) -> i32 {
12     match items {
13         (false, a, s) | (a, false, s) if if cond { return 3 } else { a } => 1,
14         (true, b, t) | (false, b, t) => 2,
15     }
16 }
17
18 const CASES: &[(bool, bool, bool, i32)] = &[
19     (false, false, false, 2),
20     (false, false, true, 1),
21     (false, true, false, 1),
22     (false, true, true, 2),
23     (true, false, false, 3),
24     (true, false, true, 3),
25     (true, true, false, 3),
26     (true, true, true, 2),
27 ];
28
29 fn main() {
30     for &(cond, items_1, items_2, result) in CASES {
31         assert_eq!(
32             complicated_match(cond, (items_1, items_2, String::new())),
33             result,
34         );
35     }
36 }
37
38 // END RUST SOURCE
39 // START rustc.complicated_match.SimplifyCfg-initial.after.mir
40 // let mut _0: i32;
41 // let mut _3: &bool;                   // Temp for fake borrow of `items.0`
42 // let mut _4: &bool;                   // Temp for fake borrow of `items.1`
43 // let _5: bool;                        // `a` in arm
44 // let _6: &bool;                       // `a` in guard
45 // let _7: std::string::String;         // `s` in arm
46 // let _8: &std::string::String;        // `s` in guard
47 // let mut _9: bool;                    // `if cond { return 3 } else { a }`
48 // let mut _10: bool;                   // `cond`
49 // let mut _11: !;                      // `return 3`
50 // let mut _12: bool;                   // `if cond { return 3 } else { a }`
51 // let mut _13: bool;                   // `cond`
52 // let mut _14: !;                      // `return 3`
53 // let _15: bool;                       // `b`
54 // let _16: std::string::String;        // `t`
55 // scope 1 {
56 // }
57 // scope 2 {
58 // }
59 // bb0: {
60 //     FakeRead(ForMatchedPlace, _2);
61 //     switchInt((_2.0: bool)) -> [false: bb2, otherwise: bb5];
62 // }
63 // bb1 (cleanup): {
64 //     resume;
65 // }
66 // bb2: {
67 //     falseEdges -> [real: bb8, imaginary: bb3];
68 // }
69 // bb3: {
70 //     falseEdges -> [real: bb17, imaginary: bb4];
71 // }
72 // bb4: {
73 //     falseEdges -> [real: bb25, imaginary: bb26];
74 // }
75 // bb5: {
76 //     switchInt((_2.1: bool)) -> [false: bb3, otherwise: bb6];
77 // }
78 // bb6: {
79 //     switchInt((_2.0: bool)) -> [false: bb26, otherwise: bb4];
80 // }
81 // bb7: {                               // arm 1
82 //     _0 = const 1i32;
83 //     drop(_7) -> [return: bb23, unwind: bb13];
84 // }
85 // bb8: {                               // guard - first time
86 //     StorageLive(_6);
87 //     _6 = &(_2.1: bool);
88 //     StorageLive(_8);
89 //     _8 = &(_2.2: std::string::String);
90 //     _3 = &shallow (_2.0: bool);
91 //     _4 = &shallow (_2.1: bool);
92 //     StorageLive(_9);
93 //     StorageLive(_10);
94 //     _10 = _1;
95 //     FakeRead(ForMatchedPlace, _10);
96 //     switchInt(_10) -> [false: bb10, otherwise: bb9];
97 // }
98 // bb9: {
99 //     falseEdges -> [real: bb11, imaginary: bb10];
100 // }
101 // bb10: {                              // `else` block - first time
102 //     _9 = (*_6);
103 //     StorageDead(_10);
104 //     switchInt(move _9) -> [false: bb16, otherwise: bb15];
105 // }
106 // bb11: {                              // `return 3` - first time
107 //     _0 = const 3i32;
108 //     StorageDead(_10);
109 //     StorageDead(_9);
110 //     StorageDead(_8);
111 //     StorageDead(_6);
112 //     goto -> bb14;
113 // }
114 // bb12: {
115 //     return;
116 // }
117 // bb13 (cleanup): {
118 //     drop(_2) -> bb1;
119 // }
120 // bb14: {
121 //     drop(_2) -> [return: bb12, unwind: bb1];
122 // }
123 // bb15: {
124 //     StorageDead(_9);
125 //     FakeRead(ForMatchGuard, _3);
126 //     FakeRead(ForMatchGuard, _4);
127 //     FakeRead(ForGuardBinding, _6);
128 //     FakeRead(ForGuardBinding, _8);
129 //     StorageLive(_5);
130 //     _5 = (_2.1: bool);
131 //     StorageLive(_7);
132 //     _7 = move (_2.2: std::string::String);
133 //     goto -> bb7;
134 // }
135 // bb16: {                              // guard otherwise case - first time
136 //     StorageDead(_9);
137 //     StorageDead(_8);
138 //     StorageDead(_6);
139 //     falseEdges -> [real: bb5, imaginary: bb3];
140 // }
141 // bb17: {                              // guard - second time
142 //     StorageLive(_6);
143 //     _6 = &(_2.0: bool);
144 //     StorageLive(_8);
145 //     _8 = &(_2.2: std::string::String);
146 //     _3 = &shallow (_2.0: bool);
147 //     _4 = &shallow (_2.1: bool);
148 //     StorageLive(_12);
149 //     StorageLive(_13);
150 //     _13 = _1;
151 //     FakeRead(ForMatchedPlace, _13);
152 //     switchInt(_13) -> [false: bb19, otherwise: bb18];
153 // }
154 // bb18: {
155 //     falseEdges -> [real: bb20, imaginary: bb19];
156 // }
157 // bb19: {                              // `else` block - second time
158 //     _12 = (*_6);
159 //     StorageDead(_13);
160 //     switchInt(move _12) -> [false: bb22, otherwise: bb21];
161 // }
162 // bb20: {
163 //     _0 = const 3i32;
164 //     StorageDead(_13);
165 //     StorageDead(_12);
166 //     StorageDead(_8);
167 //     StorageDead(_6);
168 //     goto -> bb14;
169 // }
170 // bb21: {                              // bindings for arm 1
171 //     StorageDead(_12);
172 //     FakeRead(ForMatchGuard, _3);
173 //     FakeRead(ForMatchGuard, _4);
174 //     FakeRead(ForGuardBinding, _6);
175 //     FakeRead(ForGuardBinding, _8);
176 //     StorageLive(_5);
177 //     _5 = (_2.0: bool);
178 //     StorageLive(_7);
179 //     _7 = move (_2.2: std::string::String);
180 //     goto -> bb7;
181 // }
182 // bb22: {                              // Guard otherwise case - second time
183 //     StorageDead(_12);
184 //     StorageDead(_8);
185 //     StorageDead(_6);
186 //     falseEdges -> [real: bb6, imaginary: bb4];
187 // }
188 // bb23: {                              // rest of arm 1
189 //     StorageDead(_7);
190 //     StorageDead(_5);
191 //     StorageDead(_8);
192 //     StorageDead(_6);
193 //     goto -> bb28;
194 // }
195 // bb24: {                              // arm 2
196 //     _0 = const 2i32;
197 //     drop(_16) -> [return: bb27, unwind: bb13];
198 // }
199 // bb25: {                              // bindings for arm 2 - first pattern
200 //     StorageLive(_15);
201 //     _15 = (_2.1: bool);
202 //     StorageLive(_16);
203 //     _16 = move (_2.2: std::string::String);
204 //     goto -> bb24;
205 // }
206 // bb26: {                              // bindings for arm 2 - second pattern
207 //     StorageLive(_15);
208 //     _15 = (_2.1: bool);
209 //     StorageLive(_16);
210 //     _16 = move (_2.2: std::string::String);
211 //     goto -> bb24;
212 // }
213 // bb27: {                              // rest of arm 2
214 //     StorageDead(_16);
215 //     StorageDead(_15);
216 //     goto -> bb28;
217 // }
218 // bb28: {
219 //     drop(_2) -> [return: bb12, unwind: bb1];
220 // }
221 // END rustc.complicated_match.SimplifyCfg-initial.after.mir
222 // START rustc.complicated_match.ElaborateDrops.after.mir
223 // let _16: std::string::String;      // No drop flags, which would come after this.
224 // scope 1 {
225 // END rustc.complicated_match.ElaborateDrops.after.mir