add place mention for #[loop_match] scrutinee
This commit is contained in:
parent
9916ce362f
commit
3e76b58453
6 changed files with 374 additions and 3 deletions
|
|
@ -295,9 +295,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
this.diverge_from(loop_block);
|
||||
|
||||
// Logic for `match`.
|
||||
let scrutinee_place_builder =
|
||||
unpack!(body_block = this.as_place_builder(body_block, scrutinee));
|
||||
let scrutinee_span = this.thir.exprs[scrutinee].span;
|
||||
let scrutinee_place_builder = unpack!(
|
||||
body_block = this.lower_scrutinee(body_block, scrutinee, scrutinee_span)
|
||||
);
|
||||
|
||||
let match_start_span = match_span.shrink_to_lo().to(scrutinee_span);
|
||||
|
||||
let mut patterns = Vec::with_capacity(arms.len());
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
/// Evaluate the scrutinee and add the PlaceMention for it.
|
||||
fn lower_scrutinee(
|
||||
pub(crate) fn lower_scrutinee(
|
||||
&mut self,
|
||||
mut block: BasicBlock,
|
||||
scrutinee_id: ExprId,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
// MIR for `break_to_block_unit` after built
|
||||
|
||||
fn break_to_block_unit() -> u8 {
|
||||
let mut _0: u8;
|
||||
let mut _1: i32;
|
||||
let mut _2: !;
|
||||
scope 1 {
|
||||
debug state => _1;
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = const 0_i32;
|
||||
FakeRead(ForLet(None), _1);
|
||||
StorageLive(_2);
|
||||
goto -> bb1;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
falseUnwind -> [real: bb2, unwind: bb10];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
PlaceMention(_1);
|
||||
_1 = const 2_i32;
|
||||
goto -> bb5;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
FakeRead(ForMatchedPlace(None), _1);
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
goto -> bb6;
|
||||
}
|
||||
|
||||
bb5: {
|
||||
goto -> bb6;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
goto -> bb7;
|
||||
}
|
||||
|
||||
bb7: {
|
||||
goto -> bb1;
|
||||
}
|
||||
|
||||
bb8: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
|
||||
bb10 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// MIR for `infinite_a` after built
|
||||
|
||||
fn infinite_a(_1: u8) -> () {
|
||||
debug state => _1;
|
||||
let mut _0: ();
|
||||
let mut _2: !;
|
||||
let _3: u8;
|
||||
scope 1 {
|
||||
debug a => _3;
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
goto -> bb1;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
falseUnwind -> [real: bb2, unwind: bb7];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
PlaceMention(_1);
|
||||
StorageLive(_3);
|
||||
_3 = copy _1;
|
||||
_1 = copy _3;
|
||||
StorageDead(_3);
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
FakeRead(ForMatchedPlace(None), _1);
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
goto -> bb1;
|
||||
}
|
||||
|
||||
bb5: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_2);
|
||||
return;
|
||||
}
|
||||
|
||||
bb7 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
68
tests/mir-opt/building/loop_match_diverges.rs
Normal file
68
tests/mir-opt/building/loop_match_diverges.rs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
// skip-filecheck
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(loop_match)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// Test that a #[loop_match] without an explicit break from the loop generates valid MIR.
|
||||
|
||||
enum State {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
}
|
||||
|
||||
// EMIT_MIR loop_match_diverges.simple.built.after.mir
|
||||
fn simple(mut state: State) -> State {
|
||||
#[loop_match]
|
||||
'a: loop {
|
||||
state = 'blk: {
|
||||
match state {
|
||||
State::A => {
|
||||
#[const_continue]
|
||||
break 'blk State::B;
|
||||
}
|
||||
State::B => {
|
||||
if true {
|
||||
#[const_continue]
|
||||
break 'blk State::C;
|
||||
} else {
|
||||
#[const_continue]
|
||||
break 'blk State::A;
|
||||
}
|
||||
}
|
||||
State::C => break 'a,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
// EMIT_MIR loop_match_diverges.break_to_block_unit.built.after.mir
|
||||
#[unsafe(no_mangle)]
|
||||
fn break_to_block_unit() -> u8 {
|
||||
let mut state = 0;
|
||||
#[loop_match]
|
||||
loop {
|
||||
state = 'blk: {
|
||||
match state {
|
||||
_ => 'b: {
|
||||
break 'b 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// EMIT_MIR loop_match_diverges.infinite_a.built.after.mir
|
||||
#[unsafe(no_mangle)]
|
||||
fn infinite_a(mut state: u8) {
|
||||
#[loop_match]
|
||||
loop {
|
||||
state = 'blk: {
|
||||
match state {
|
||||
a => a,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
// MIR for `simple` after built
|
||||
|
||||
fn simple(_1: State) -> State {
|
||||
debug state => _1;
|
||||
let mut _0: State;
|
||||
let _2: ();
|
||||
let mut _3: isize;
|
||||
let mut _4: !;
|
||||
let mut _5: isize;
|
||||
let mut _6: bool;
|
||||
let mut _7: !;
|
||||
let mut _8: isize;
|
||||
let mut _9: !;
|
||||
let mut _10: isize;
|
||||
let mut _11: !;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
goto -> bb1;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
falseUnwind -> [real: bb2, unwind: bb37];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
PlaceMention(_1);
|
||||
_3 = discriminant(_1);
|
||||
switchInt(move _3) -> [0: bb4, 1: bb6, 2: bb8, otherwise: bb3];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
FakeRead(ForMatchedPlace(None), _1);
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
falseEdge -> [real: bb11, imaginary: bb6];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
falseEdge -> [real: bb10, imaginary: bb8];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb8: {
|
||||
_2 = const ();
|
||||
goto -> bb36;
|
||||
}
|
||||
|
||||
bb9: {
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb10: {
|
||||
StorageLive(_6);
|
||||
_6 = const true;
|
||||
switchInt(move _6) -> [0: bb17, otherwise: bb16];
|
||||
}
|
||||
|
||||
bb11: {
|
||||
_1 = State::B;
|
||||
_5 = discriminant(_1);
|
||||
falseEdge -> [real: bb12, imaginary: bb13];
|
||||
}
|
||||
|
||||
bb12: {
|
||||
goto -> bb10;
|
||||
}
|
||||
|
||||
bb13: {
|
||||
goto -> bb34;
|
||||
}
|
||||
|
||||
bb14: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb15: {
|
||||
goto -> bb32;
|
||||
}
|
||||
|
||||
bb16: {
|
||||
_1 = State::C;
|
||||
_8 = discriminant(_1);
|
||||
falseEdge -> [real: bb18, imaginary: bb19];
|
||||
}
|
||||
|
||||
bb17: {
|
||||
goto -> bb23;
|
||||
}
|
||||
|
||||
bb18: {
|
||||
goto -> bb20;
|
||||
}
|
||||
|
||||
bb19: {
|
||||
goto -> bb33;
|
||||
}
|
||||
|
||||
bb20: {
|
||||
StorageDead(_6);
|
||||
goto -> bb8;
|
||||
}
|
||||
|
||||
bb21: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb22: {
|
||||
goto -> bb29;
|
||||
}
|
||||
|
||||
bb23: {
|
||||
_1 = State::A;
|
||||
_10 = discriminant(_1);
|
||||
falseEdge -> [real: bb24, imaginary: bb25];
|
||||
}
|
||||
|
||||
bb24: {
|
||||
goto -> bb26;
|
||||
}
|
||||
|
||||
bb25: {
|
||||
goto -> bb33;
|
||||
}
|
||||
|
||||
bb26: {
|
||||
StorageDead(_6);
|
||||
goto -> bb11;
|
||||
}
|
||||
|
||||
bb27: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb28: {
|
||||
goto -> bb29;
|
||||
}
|
||||
|
||||
bb29: {
|
||||
StorageDead(_6);
|
||||
goto -> bb32;
|
||||
}
|
||||
|
||||
bb30: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb31: {
|
||||
goto -> bb32;
|
||||
}
|
||||
|
||||
bb32: {
|
||||
goto -> bb35;
|
||||
}
|
||||
|
||||
bb33: {
|
||||
StorageDead(_6);
|
||||
goto -> bb34;
|
||||
}
|
||||
|
||||
bb34: {
|
||||
goto -> bb35;
|
||||
}
|
||||
|
||||
bb35: {
|
||||
goto -> bb1;
|
||||
}
|
||||
|
||||
bb36: {
|
||||
StorageDead(_2);
|
||||
_0 = move _1;
|
||||
return;
|
||||
}
|
||||
|
||||
bb37 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue