Skip to content

Commit 3e76b58

Browse files
committed
add place mention for #[loop_match] scrutinee
1 parent 9916ce3 commit 3e76b58

File tree

6 files changed

+374
-3
lines changed

6 files changed

+374
-3
lines changed

compiler/rustc_mir_build/src/builder/expr/into.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
295295
this.diverge_from(loop_block);
296296

297297
// Logic for `match`.
298-
let scrutinee_place_builder =
299-
unpack!(body_block = this.as_place_builder(body_block, scrutinee));
300298
let scrutinee_span = this.thir.exprs[scrutinee].span;
299+
let scrutinee_place_builder = unpack!(
300+
body_block = this.lower_scrutinee(body_block, scrutinee, scrutinee_span)
301+
);
302+
301303
let match_start_span = match_span.shrink_to_lo().to(scrutinee_span);
302304

303305
let mut patterns = Vec::with_capacity(arms.len());

compiler/rustc_mir_build/src/builder/matches/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
407407
}
408408

409409
/// Evaluate the scrutinee and add the PlaceMention for it.
410-
fn lower_scrutinee(
410+
pub(crate) fn lower_scrutinee(
411411
&mut self,
412412
mut block: BasicBlock,
413413
scrutinee_id: ExprId,
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// MIR for `break_to_block_unit` after built
2+
3+
fn break_to_block_unit() -> u8 {
4+
let mut _0: u8;
5+
let mut _1: i32;
6+
let mut _2: !;
7+
scope 1 {
8+
debug state => _1;
9+
}
10+
11+
bb0: {
12+
StorageLive(_1);
13+
_1 = const 0_i32;
14+
FakeRead(ForLet(None), _1);
15+
StorageLive(_2);
16+
goto -> bb1;
17+
}
18+
19+
bb1: {
20+
falseUnwind -> [real: bb2, unwind: bb10];
21+
}
22+
23+
bb2: {
24+
PlaceMention(_1);
25+
_1 = const 2_i32;
26+
goto -> bb5;
27+
}
28+
29+
bb3: {
30+
FakeRead(ForMatchedPlace(None), _1);
31+
unreachable;
32+
}
33+
34+
bb4: {
35+
goto -> bb6;
36+
}
37+
38+
bb5: {
39+
goto -> bb6;
40+
}
41+
42+
bb6: {
43+
goto -> bb7;
44+
}
45+
46+
bb7: {
47+
goto -> bb1;
48+
}
49+
50+
bb8: {
51+
unreachable;
52+
}
53+
54+
bb9: {
55+
StorageDead(_2);
56+
StorageDead(_1);
57+
return;
58+
}
59+
60+
bb10 (cleanup): {
61+
resume;
62+
}
63+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// MIR for `infinite_a` after built
2+
3+
fn infinite_a(_1: u8) -> () {
4+
debug state => _1;
5+
let mut _0: ();
6+
let mut _2: !;
7+
let _3: u8;
8+
scope 1 {
9+
debug a => _3;
10+
}
11+
12+
bb0: {
13+
StorageLive(_2);
14+
goto -> bb1;
15+
}
16+
17+
bb1: {
18+
falseUnwind -> [real: bb2, unwind: bb7];
19+
}
20+
21+
bb2: {
22+
PlaceMention(_1);
23+
StorageLive(_3);
24+
_3 = copy _1;
25+
_1 = copy _3;
26+
StorageDead(_3);
27+
goto -> bb4;
28+
}
29+
30+
bb3: {
31+
FakeRead(ForMatchedPlace(None), _1);
32+
unreachable;
33+
}
34+
35+
bb4: {
36+
goto -> bb1;
37+
}
38+
39+
bb5: {
40+
unreachable;
41+
}
42+
43+
bb6: {
44+
StorageDead(_2);
45+
return;
46+
}
47+
48+
bb7 (cleanup): {
49+
resume;
50+
}
51+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// skip-filecheck
2+
#![allow(incomplete_features)]
3+
#![feature(loop_match)]
4+
#![crate_type = "lib"]
5+
6+
// Test that a #[loop_match] without an explicit break from the loop generates valid MIR.
7+
8+
enum State {
9+
A,
10+
B,
11+
C,
12+
}
13+
14+
// EMIT_MIR loop_match_diverges.simple.built.after.mir
15+
fn simple(mut state: State) -> State {
16+
#[loop_match]
17+
'a: loop {
18+
state = 'blk: {
19+
match state {
20+
State::A => {
21+
#[const_continue]
22+
break 'blk State::B;
23+
}
24+
State::B => {
25+
if true {
26+
#[const_continue]
27+
break 'blk State::C;
28+
} else {
29+
#[const_continue]
30+
break 'blk State::A;
31+
}
32+
}
33+
State::C => break 'a,
34+
}
35+
};
36+
}
37+
38+
state
39+
}
40+
41+
// EMIT_MIR loop_match_diverges.break_to_block_unit.built.after.mir
42+
#[unsafe(no_mangle)]
43+
fn break_to_block_unit() -> u8 {
44+
let mut state = 0;
45+
#[loop_match]
46+
loop {
47+
state = 'blk: {
48+
match state {
49+
_ => 'b: {
50+
break 'b 2;
51+
}
52+
}
53+
}
54+
}
55+
}
56+
57+
// EMIT_MIR loop_match_diverges.infinite_a.built.after.mir
58+
#[unsafe(no_mangle)]
59+
fn infinite_a(mut state: u8) {
60+
#[loop_match]
61+
loop {
62+
state = 'blk: {
63+
match state {
64+
a => a,
65+
}
66+
}
67+
}
68+
}
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
// MIR for `simple` after built
2+
3+
fn simple(_1: State) -> State {
4+
debug state => _1;
5+
let mut _0: State;
6+
let _2: ();
7+
let mut _3: isize;
8+
let mut _4: !;
9+
let mut _5: isize;
10+
let mut _6: bool;
11+
let mut _7: !;
12+
let mut _8: isize;
13+
let mut _9: !;
14+
let mut _10: isize;
15+
let mut _11: !;
16+
17+
bb0: {
18+
StorageLive(_2);
19+
goto -> bb1;
20+
}
21+
22+
bb1: {
23+
falseUnwind -> [real: bb2, unwind: bb37];
24+
}
25+
26+
bb2: {
27+
PlaceMention(_1);
28+
_3 = discriminant(_1);
29+
switchInt(move _3) -> [0: bb4, 1: bb6, 2: bb8, otherwise: bb3];
30+
}
31+
32+
bb3: {
33+
FakeRead(ForMatchedPlace(None), _1);
34+
unreachable;
35+
}
36+
37+
bb4: {
38+
falseEdge -> [real: bb11, imaginary: bb6];
39+
}
40+
41+
bb5: {
42+
goto -> bb3;
43+
}
44+
45+
bb6: {
46+
falseEdge -> [real: bb10, imaginary: bb8];
47+
}
48+
49+
bb7: {
50+
goto -> bb3;
51+
}
52+
53+
bb8: {
54+
_2 = const ();
55+
goto -> bb36;
56+
}
57+
58+
bb9: {
59+
goto -> bb3;
60+
}
61+
62+
bb10: {
63+
StorageLive(_6);
64+
_6 = const true;
65+
switchInt(move _6) -> [0: bb17, otherwise: bb16];
66+
}
67+
68+
bb11: {
69+
_1 = State::B;
70+
_5 = discriminant(_1);
71+
falseEdge -> [real: bb12, imaginary: bb13];
72+
}
73+
74+
bb12: {
75+
goto -> bb10;
76+
}
77+
78+
bb13: {
79+
goto -> bb34;
80+
}
81+
82+
bb14: {
83+
unreachable;
84+
}
85+
86+
bb15: {
87+
goto -> bb32;
88+
}
89+
90+
bb16: {
91+
_1 = State::C;
92+
_8 = discriminant(_1);
93+
falseEdge -> [real: bb18, imaginary: bb19];
94+
}
95+
96+
bb17: {
97+
goto -> bb23;
98+
}
99+
100+
bb18: {
101+
goto -> bb20;
102+
}
103+
104+
bb19: {
105+
goto -> bb33;
106+
}
107+
108+
bb20: {
109+
StorageDead(_6);
110+
goto -> bb8;
111+
}
112+
113+
bb21: {
114+
unreachable;
115+
}
116+
117+
bb22: {
118+
goto -> bb29;
119+
}
120+
121+
bb23: {
122+
_1 = State::A;
123+
_10 = discriminant(_1);
124+
falseEdge -> [real: bb24, imaginary: bb25];
125+
}
126+
127+
bb24: {
128+
goto -> bb26;
129+
}
130+
131+
bb25: {
132+
goto -> bb33;
133+
}
134+
135+
bb26: {
136+
StorageDead(_6);
137+
goto -> bb11;
138+
}
139+
140+
bb27: {
141+
unreachable;
142+
}
143+
144+
bb28: {
145+
goto -> bb29;
146+
}
147+
148+
bb29: {
149+
StorageDead(_6);
150+
goto -> bb32;
151+
}
152+
153+
bb30: {
154+
unreachable;
155+
}
156+
157+
bb31: {
158+
goto -> bb32;
159+
}
160+
161+
bb32: {
162+
goto -> bb35;
163+
}
164+
165+
bb33: {
166+
StorageDead(_6);
167+
goto -> bb34;
168+
}
169+
170+
bb34: {
171+
goto -> bb35;
172+
}
173+
174+
bb35: {
175+
goto -> bb1;
176+
}
177+
178+
bb36: {
179+
StorageDead(_2);
180+
_0 = move _1;
181+
return;
182+
}
183+
184+
bb37 (cleanup): {
185+
resume;
186+
}
187+
}

0 commit comments

Comments
 (0)