Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 154037f

Browse files
committed
Auto merge of #144783 - folkertdev:loop-match-diverging-loop, r=SparrowLii
fix `#[loop_match]` on diverging loop tracking issue: #132306 fixes #144492 fixes #144493 fixes #144781 this generated invalid MIR before. issue #143806 still has an issue where we assign `state = state` which is invalid in MIR. Fixing that problem is tricky, so I'd like to do that separately. r? `@bjorn3`
2 parents c0bb3b9 + 3e76b58 commit 154037f

File tree

7 files changed

+419
-4
lines changed

7 files changed

+419
-4
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
293293
this.diverge_from(loop_block);
294294

295295
// Logic for `match`.
296-
let scrutinee_place_builder =
297-
unpack!(body_block = this.as_place_builder(body_block, scrutinee));
298296
let scrutinee_span = this.thir.exprs[scrutinee].span;
297+
let scrutinee_place_builder = unpack!(
298+
body_block = this.lower_scrutinee(body_block, scrutinee, scrutinee_span)
299+
);
300+
299301
let match_start_span = match_span.shrink_to_lo().to(scrutinee_span);
300302

301303
let mut patterns = Vec::with_capacity(arms.len());
@@ -343,7 +345,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
343345
expr_span,
344346
|this| {
345347
this.lower_match_arms(
346-
destination,
348+
state_place,
347349
scrutinee_place_builder,
348350
scrutinee_span,
349351
arms,

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

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

390390
/// Evaluate the scrutinee and add the PlaceMention for it.
391-
fn lower_scrutinee(
391+
pub(crate)fn lower_scrutinee(
392392
&mut self,
393393
mut block: BasicBlock,
394394
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+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /