]>
Commit | Line | Data |
---|---|---|
dc9dc135 XL |
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 | ||
dc9dc135 XL |
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 { | |
60c5eb7d XL |
56 | // debug a => _5; |
57 | // debug a => _6; | |
58 | // debug s => _7; | |
59 | // debug s => _8; | |
dc9dc135 XL |
60 | // } |
61 | // scope 2 { | |
60c5eb7d XL |
62 | // debug b => _15; |
63 | // debug t => _16; | |
dc9dc135 XL |
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 |