]> git.proxmox.com Git - rustc.git/blame - 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
CommitLineData
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
11fn 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
18const 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
29fn 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