]> git.proxmox.com Git - rustc.git/blob - src/test/mir-opt/match-arm-scopes.rs
New upstream version 1.41.1+dfsg1
[rustc.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 // debug a => _5;
57 // debug a => _6;
58 // debug s => _7;
59 // debug s => _8;
60 // }
61 // scope 2 {
62 // debug b => _15;
63 // debug t => _16;
64 // }
65 // bb0: {
66 // FakeRead(ForMatchedPlace, _2);
67 // switchInt((_2.0: bool)) -> [false: bb2, otherwise: bb5];
68 // }
69 // bb1 (cleanup): {
70 // resume;
71 // }
72 // bb2: {
73 // falseEdges -> [real: bb8, imaginary: bb3];
74 // }
75 // bb3: {
76 // falseEdges -> [real: bb17, imaginary: bb4];
77 // }
78 // bb4: {
79 // falseEdges -> [real: bb25, imaginary: bb26];
80 // }
81 // bb5: {
82 // switchInt((_2.1: bool)) -> [false: bb3, otherwise: bb6];
83 // }
84 // bb6: {
85 // switchInt((_2.0: bool)) -> [false: bb26, otherwise: bb4];
86 // }
87 // bb7: { // arm 1
88 // _0 = const 1i32;
89 // drop(_7) -> [return: bb23, unwind: bb13];
90 // }
91 // bb8: { // guard - first time
92 // StorageLive(_6);
93 // _6 = &(_2.1: bool);
94 // StorageLive(_8);
95 // _8 = &(_2.2: std::string::String);
96 // _3 = &shallow (_2.0: bool);
97 // _4 = &shallow (_2.1: bool);
98 // StorageLive(_9);
99 // StorageLive(_10);
100 // _10 = _1;
101 // FakeRead(ForMatchedPlace, _10);
102 // switchInt(_10) -> [false: bb10, otherwise: bb9];
103 // }
104 // bb9: {
105 // falseEdges -> [real: bb11, imaginary: bb10];
106 // }
107 // bb10: { // `else` block - first time
108 // _9 = (*_6);
109 // StorageDead(_10);
110 // switchInt(move _9) -> [false: bb16, otherwise: bb15];
111 // }
112 // bb11: { // `return 3` - first time
113 // _0 = const 3i32;
114 // StorageDead(_10);
115 // StorageDead(_9);
116 // StorageDead(_8);
117 // StorageDead(_6);
118 // goto -> bb14;
119 // }
120 // bb12: {
121 // return;
122 // }
123 // bb13 (cleanup): {
124 // drop(_2) -> bb1;
125 // }
126 // bb14: {
127 // drop(_2) -> [return: bb12, unwind: bb1];
128 // }
129 // bb15: {
130 // StorageDead(_9);
131 // FakeRead(ForMatchGuard, _3);
132 // FakeRead(ForMatchGuard, _4);
133 // FakeRead(ForGuardBinding, _6);
134 // FakeRead(ForGuardBinding, _8);
135 // StorageLive(_5);
136 // _5 = (_2.1: bool);
137 // StorageLive(_7);
138 // _7 = move (_2.2: std::string::String);
139 // goto -> bb7;
140 // }
141 // bb16: { // guard otherwise case - first time
142 // StorageDead(_9);
143 // StorageDead(_8);
144 // StorageDead(_6);
145 // falseEdges -> [real: bb5, imaginary: bb3];
146 // }
147 // bb17: { // guard - second time
148 // StorageLive(_6);
149 // _6 = &(_2.0: bool);
150 // StorageLive(_8);
151 // _8 = &(_2.2: std::string::String);
152 // _3 = &shallow (_2.0: bool);
153 // _4 = &shallow (_2.1: bool);
154 // StorageLive(_12);
155 // StorageLive(_13);
156 // _13 = _1;
157 // FakeRead(ForMatchedPlace, _13);
158 // switchInt(_13) -> [false: bb19, otherwise: bb18];
159 // }
160 // bb18: {
161 // falseEdges -> [real: bb20, imaginary: bb19];
162 // }
163 // bb19: { // `else` block - second time
164 // _12 = (*_6);
165 // StorageDead(_13);
166 // switchInt(move _12) -> [false: bb22, otherwise: bb21];
167 // }
168 // bb20: {
169 // _0 = const 3i32;
170 // StorageDead(_13);
171 // StorageDead(_12);
172 // StorageDead(_8);
173 // StorageDead(_6);
174 // goto -> bb14;
175 // }
176 // bb21: { // bindings for arm 1
177 // StorageDead(_12);
178 // FakeRead(ForMatchGuard, _3);
179 // FakeRead(ForMatchGuard, _4);
180 // FakeRead(ForGuardBinding, _6);
181 // FakeRead(ForGuardBinding, _8);
182 // StorageLive(_5);
183 // _5 = (_2.0: bool);
184 // StorageLive(_7);
185 // _7 = move (_2.2: std::string::String);
186 // goto -> bb7;
187 // }
188 // bb22: { // Guard otherwise case - second time
189 // StorageDead(_12);
190 // StorageDead(_8);
191 // StorageDead(_6);
192 // falseEdges -> [real: bb6, imaginary: bb4];
193 // }
194 // bb23: { // rest of arm 1
195 // StorageDead(_7);
196 // StorageDead(_5);
197 // StorageDead(_8);
198 // StorageDead(_6);
199 // goto -> bb28;
200 // }
201 // bb24: { // arm 2
202 // _0 = const 2i32;
203 // drop(_16) -> [return: bb27, unwind: bb13];
204 // }
205 // bb25: { // bindings for arm 2 - first pattern
206 // StorageLive(_15);
207 // _15 = (_2.1: bool);
208 // StorageLive(_16);
209 // _16 = move (_2.2: std::string::String);
210 // goto -> bb24;
211 // }
212 // bb26: { // bindings for arm 2 - second pattern
213 // StorageLive(_15);
214 // _15 = (_2.1: bool);
215 // StorageLive(_16);
216 // _16 = move (_2.2: std::string::String);
217 // goto -> bb24;
218 // }
219 // bb27: { // rest of arm 2
220 // StorageDead(_16);
221 // StorageDead(_15);
222 // goto -> bb28;
223 // }
224 // bb28: {
225 // drop(_2) -> [return: bb12, unwind: bb1];
226 // }
227 // END rustc.complicated_match.SimplifyCfg-initial.after.mir
228 // START rustc.complicated_match.ElaborateDrops.after.mir
229 // let _16: std::string::String; // No drop flags, which would come after this.
230 // scope 1 {
231 // END rustc.complicated_match.ElaborateDrops.after.mir