FileCheck uninhabited_enum_branching.
This commit is contained in:
parent
cb918904fe
commit
ae2e21114b
@ -1,12 +1,12 @@
|
|||||||
- // MIR for `main` before UninhabitedEnumBranching
|
- // MIR for `byref` before UninhabitedEnumBranching
|
||||||
+ // MIR for `main` after UninhabitedEnumBranching
|
+ // MIR for `byref` after UninhabitedEnumBranching
|
||||||
|
|
||||||
fn main() -> () {
|
fn byref() -> () {
|
||||||
let mut _0: ();
|
let mut _0: ();
|
||||||
let _1: Plop;
|
let _1: Plop;
|
||||||
let mut _2: Test1;
|
let mut _2: Test3;
|
||||||
let _3: &str;
|
let _3: &str;
|
||||||
let mut _4: &Test1;
|
let mut _4: &Test3;
|
||||||
let mut _5: isize;
|
let mut _5: isize;
|
||||||
let _6: &str;
|
let _6: &str;
|
||||||
let _7: &str;
|
let _7: &str;
|
||||||
@ -23,12 +23,12 @@
|
|||||||
bb0: {
|
bb0: {
|
||||||
StorageLive(_1);
|
StorageLive(_1);
|
||||||
StorageLive(_2);
|
StorageLive(_2);
|
||||||
_2 = Test1::C;
|
_2 = Test3::C;
|
||||||
_1 = Plop { xx: const 51_u32, test1: move _2 };
|
_1 = Plop { xx: const 51_u32, test3: move _2 };
|
||||||
StorageDead(_2);
|
StorageDead(_2);
|
||||||
StorageLive(_3);
|
StorageLive(_3);
|
||||||
StorageLive(_4);
|
StorageLive(_4);
|
||||||
_4 = &(_1.1: Test1);
|
_4 = &(_1.1: Test3);
|
||||||
_5 = discriminant((*_4));
|
_5 = discriminant((*_4));
|
||||||
- switchInt(move _5) -> [0: bb3, 1: bb4, 2: bb5, 3: bb1, otherwise: bb2];
|
- switchInt(move _5) -> [0: bb3, 1: bb4, 2: bb5, 3: bb1, otherwise: bb2];
|
||||||
+ switchInt(move _5) -> [0: bb12, 1: bb12, 2: bb5, 3: bb1, otherwise: bb12];
|
+ switchInt(move _5) -> [0: bb12, 1: bb12, 2: bb5, 3: bb1, otherwise: bb12];
|
||||||
@ -71,7 +71,7 @@
|
|||||||
StorageDead(_4);
|
StorageDead(_4);
|
||||||
StorageDead(_3);
|
StorageDead(_3);
|
||||||
StorageLive(_9);
|
StorageLive(_9);
|
||||||
_10 = discriminant((_1.1: Test1));
|
_10 = discriminant((_1.1: Test3));
|
||||||
- switchInt(move _10) -> [0: bb8, 1: bb9, 2: bb10, 3: bb7, otherwise: bb2];
|
- switchInt(move _10) -> [0: bb8, 1: bb9, 2: bb10, 3: bb7, otherwise: bb2];
|
||||||
+ switchInt(move _10) -> [0: bb12, 1: bb12, 2: bb10, 3: bb7, otherwise: bb12];
|
+ switchInt(move _10) -> [0: bb12, 1: bb12, 2: bb10, 3: bb7, otherwise: bb12];
|
||||||
}
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
- // MIR for `custom_discriminant` before UninhabitedEnumBranching
|
||||||
|
+ // MIR for `custom_discriminant` after UninhabitedEnumBranching
|
||||||
|
|
||||||
|
fn custom_discriminant() -> () {
|
||||||
|
let mut _0: ();
|
||||||
|
let _1: &str;
|
||||||
|
let mut _2: Test2;
|
||||||
|
let mut _3: isize;
|
||||||
|
let _4: &str;
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
StorageLive(_1);
|
||||||
|
StorageLive(_2);
|
||||||
|
_2 = Test2::D;
|
||||||
|
_3 = discriminant(_2);
|
||||||
|
- switchInt(move _3) -> [4: bb3, 5: bb1, otherwise: bb2];
|
||||||
|
+ switchInt(move _3) -> [4: bb3, 5: bb1, otherwise: bb5];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb1: {
|
||||||
|
StorageLive(_4);
|
||||||
|
_4 = const "E";
|
||||||
|
_1 = &(*_4);
|
||||||
|
StorageDead(_4);
|
||||||
|
goto -> bb4;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb2: {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb3: {
|
||||||
|
_1 = const "D";
|
||||||
|
goto -> bb4;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb4: {
|
||||||
|
StorageDead(_2);
|
||||||
|
StorageDead(_1);
|
||||||
|
_0 = const ();
|
||||||
|
return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bb5: {
|
||||||
|
+ unreachable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,65 +0,0 @@
|
|||||||
// MIR for `main` after SimplifyCfg-after-uninhabited-enum-branching
|
|
||||||
|
|
||||||
fn main() -> () {
|
|
||||||
let mut _0: ();
|
|
||||||
let _1: &str;
|
|
||||||
let mut _2: Test1;
|
|
||||||
let mut _3: isize;
|
|
||||||
let _4: &str;
|
|
||||||
let _5: &str;
|
|
||||||
let _6: &str;
|
|
||||||
let mut _7: Test2;
|
|
||||||
let mut _8: isize;
|
|
||||||
let _9: &str;
|
|
||||||
let mut _10: bool;
|
|
||||||
let mut _11: bool;
|
|
||||||
let mut _12: bool;
|
|
||||||
|
|
||||||
bb0: {
|
|
||||||
StorageLive(_1);
|
|
||||||
StorageLive(_2);
|
|
||||||
_2 = Test1::C;
|
|
||||||
_3 = discriminant(_2);
|
|
||||||
_10 = Ne(_3, const 0_isize);
|
|
||||||
assume(move _10);
|
|
||||||
_11 = Ne(_3, const 1_isize);
|
|
||||||
assume(move _11);
|
|
||||||
_12 = Eq(_3, const 2_isize);
|
|
||||||
assume(move _12);
|
|
||||||
StorageLive(_5);
|
|
||||||
_5 = const "C";
|
|
||||||
_1 = &(*_5);
|
|
||||||
StorageDead(_5);
|
|
||||||
StorageDead(_2);
|
|
||||||
StorageDead(_1);
|
|
||||||
StorageLive(_6);
|
|
||||||
StorageLive(_7);
|
|
||||||
_7 = Test2::D;
|
|
||||||
_8 = discriminant(_7);
|
|
||||||
switchInt(move _8) -> [4: bb3, 5: bb2, otherwise: bb1];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb1: {
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb2: {
|
|
||||||
StorageLive(_9);
|
|
||||||
_9 = const "E";
|
|
||||||
_6 = &(*_9);
|
|
||||||
StorageDead(_9);
|
|
||||||
goto -> bb4;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb3: {
|
|
||||||
_6 = const "D";
|
|
||||||
goto -> bb4;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb4: {
|
|
||||||
StorageDead(_7);
|
|
||||||
StorageDead(_6);
|
|
||||||
_0 = const ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1,11 @@
|
|||||||
// skip-filecheck
|
// unit-test: UninhabitedEnumBranching
|
||||||
enum Empty { }
|
enum Empty {}
|
||||||
|
|
||||||
// test matching an enum with uninhabited variants
|
// test matching an enum with uninhabited variants
|
||||||
enum Test1 {
|
enum Test1 {
|
||||||
A(Empty),
|
A(Empty),
|
||||||
B(Empty),
|
B(Empty),
|
||||||
C
|
C,
|
||||||
}
|
}
|
||||||
|
|
||||||
// test an enum where the discriminants don't match the variant indexes
|
// test an enum where the discriminants don't match the variant indexes
|
||||||
@ -15,17 +15,75 @@ enum Test2 {
|
|||||||
E = 5,
|
E = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_MIR uninhabited_enum_branching.main.UninhabitedEnumBranching.diff
|
// test matching an enum with uninhabited variants and multiple inhabited
|
||||||
// EMIT_MIR uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
|
enum Test3 {
|
||||||
fn main() {
|
A(Empty),
|
||||||
|
B(Empty),
|
||||||
|
C,
|
||||||
|
D,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Plop {
|
||||||
|
xx: u32,
|
||||||
|
test3: Test3,
|
||||||
|
}
|
||||||
|
|
||||||
|
// EMIT_MIR uninhabited_enum_branching.simple.UninhabitedEnumBranching.diff
|
||||||
|
fn simple() {
|
||||||
|
// CHECK-LABEL: fn simple(
|
||||||
|
// CHECK: [[discr:_.*]] = discriminant(
|
||||||
|
// CHECK: switchInt(move [[discr]]) -> [0: [[unreachable:bb.*]], 1: [[unreachable]], 2: bb1, otherwise: [[unreachable]]];
|
||||||
|
// CHECK: [[unreachable]]: {
|
||||||
|
// CHECK-NEXT: unreachable;
|
||||||
match Test1::C {
|
match Test1::C {
|
||||||
Test1::A(_) => "A(Empty)",
|
Test1::A(_) => "A(Empty)",
|
||||||
Test1::B(_) => "B(Empty)",
|
Test1::B(_) => "B(Empty)",
|
||||||
Test1::C => "C",
|
Test1::C => "C",
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// EMIT_MIR uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.diff
|
||||||
|
fn custom_discriminant() {
|
||||||
|
// CHECK-LABEL: fn custom_discriminant(
|
||||||
|
// CHECK: [[discr:_.*]] = discriminant(
|
||||||
|
// CHECK: switchInt(move [[discr]]) -> [4: bb3, 5: bb1, otherwise: bb5];
|
||||||
|
// CHECK: bb5: {
|
||||||
|
// CHECK-NEXT: unreachable;
|
||||||
match Test2::D {
|
match Test2::D {
|
||||||
Test2::D => "D",
|
Test2::D => "D",
|
||||||
Test2::E => "E",
|
Test2::E => "E",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EMIT_MIR uninhabited_enum_branching.byref.UninhabitedEnumBranching.diff
|
||||||
|
fn byref() {
|
||||||
|
// CHECK-LABEL: fn byref(
|
||||||
|
let plop = Plop { xx: 51, test3: Test3::C };
|
||||||
|
|
||||||
|
// CHECK: [[ref_discr:_.*]] = discriminant((*
|
||||||
|
// CHECK: switchInt(move [[ref_discr]]) -> [0: [[unreachable:bb.*]], 1: [[unreachable]], 2: bb5, 3: bb1, otherwise: [[unreachable]]];
|
||||||
|
match &plop.test3 {
|
||||||
|
Test3::A(_) => "A(Empty)",
|
||||||
|
Test3::B(_) => "B(Empty)",
|
||||||
|
Test3::C => "C",
|
||||||
|
Test3::D => "D",
|
||||||
|
};
|
||||||
|
|
||||||
|
// CHECK: [[discr:_.*]] = discriminant(
|
||||||
|
// CHECK: switchInt(move [[discr]]) -> [0: [[unreachable]], 1: [[unreachable]], 2: bb10, 3: bb7, otherwise: [[unreachable]]];
|
||||||
|
match plop.test3 {
|
||||||
|
Test3::A(_) => "A(Empty)",
|
||||||
|
Test3::B(_) => "B(Empty)",
|
||||||
|
Test3::C => "C",
|
||||||
|
Test3::D => "D",
|
||||||
|
};
|
||||||
|
|
||||||
|
// CHECK: [[unreachable]]: {
|
||||||
|
// CHECK-NEXT: unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
simple();
|
||||||
|
custom_discriminant();
|
||||||
|
byref();
|
||||||
|
}
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
- // MIR for `main` before UninhabitedEnumBranching
|
- // MIR for `simple` before UninhabitedEnumBranching
|
||||||
+ // MIR for `main` after UninhabitedEnumBranching
|
+ // MIR for `simple` after UninhabitedEnumBranching
|
||||||
|
|
||||||
fn main() -> () {
|
fn simple() -> () {
|
||||||
let mut _0: ();
|
let mut _0: ();
|
||||||
let _1: &str;
|
let _1: &str;
|
||||||
let mut _2: Test1;
|
let mut _2: Test1;
|
||||||
let mut _3: isize;
|
let mut _3: isize;
|
||||||
let _4: &str;
|
let _4: &str;
|
||||||
let _5: &str;
|
let _5: &str;
|
||||||
let _6: &str;
|
|
||||||
let mut _7: Test2;
|
|
||||||
let mut _8: isize;
|
|
||||||
let _9: &str;
|
|
||||||
|
|
||||||
bb0: {
|
bb0: {
|
||||||
StorageLive(_1);
|
StorageLive(_1);
|
||||||
@ -19,7 +15,7 @@
|
|||||||
_2 = Test1::C;
|
_2 = Test1::C;
|
||||||
_3 = discriminant(_2);
|
_3 = discriminant(_2);
|
||||||
- switchInt(move _3) -> [0: bb3, 1: bb4, 2: bb1, otherwise: bb2];
|
- switchInt(move _3) -> [0: bb3, 1: bb4, 2: bb1, otherwise: bb2];
|
||||||
+ switchInt(move _3) -> [0: bb9, 1: bb9, 2: bb1, otherwise: bb9];
|
+ switchInt(move _3) -> [0: bb6, 1: bb6, 2: bb1, otherwise: bb6];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
@ -50,35 +46,11 @@
|
|||||||
bb5: {
|
bb5: {
|
||||||
StorageDead(_2);
|
StorageDead(_2);
|
||||||
StorageDead(_1);
|
StorageDead(_1);
|
||||||
StorageLive(_6);
|
|
||||||
StorageLive(_7);
|
|
||||||
_7 = Test2::D;
|
|
||||||
_8 = discriminant(_7);
|
|
||||||
- switchInt(move _8) -> [4: bb7, 5: bb6, otherwise: bb2];
|
|
||||||
+ switchInt(move _8) -> [4: bb7, 5: bb6, otherwise: bb9];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb6: {
|
|
||||||
StorageLive(_9);
|
|
||||||
_9 = const "E";
|
|
||||||
_6 = &(*_9);
|
|
||||||
StorageDead(_9);
|
|
||||||
goto -> bb8;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb7: {
|
|
||||||
_6 = const "D";
|
|
||||||
goto -> bb8;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb8: {
|
|
||||||
StorageDead(_7);
|
|
||||||
StorageDead(_6);
|
|
||||||
_0 = const ();
|
_0 = const ();
|
||||||
return;
|
return;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ bb9: {
|
+ bb6: {
|
||||||
+ unreachable;
|
+ unreachable;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,97 +0,0 @@
|
|||||||
// MIR for `main` after SimplifyCfg-after-uninhabited-enum-branching
|
|
||||||
|
|
||||||
fn main() -> () {
|
|
||||||
let mut _0: ();
|
|
||||||
let _1: Plop;
|
|
||||||
let mut _2: Test1;
|
|
||||||
let _3: &str;
|
|
||||||
let mut _4: &Test1;
|
|
||||||
let mut _5: isize;
|
|
||||||
let _6: &str;
|
|
||||||
let _7: &str;
|
|
||||||
let _8: &str;
|
|
||||||
let _9: &str;
|
|
||||||
let mut _10: isize;
|
|
||||||
let _11: &str;
|
|
||||||
let _12: &str;
|
|
||||||
let _13: &str;
|
|
||||||
let mut _14: bool;
|
|
||||||
let mut _15: bool;
|
|
||||||
let mut _16: bool;
|
|
||||||
let mut _17: bool;
|
|
||||||
scope 1 {
|
|
||||||
debug plop => _1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb0: {
|
|
||||||
StorageLive(_1);
|
|
||||||
StorageLive(_2);
|
|
||||||
_2 = Test1::C;
|
|
||||||
_1 = Plop { xx: const 51_u32, test1: move _2 };
|
|
||||||
StorageDead(_2);
|
|
||||||
StorageLive(_3);
|
|
||||||
StorageLive(_4);
|
|
||||||
_4 = &(_1.1: Test1);
|
|
||||||
_5 = discriminant((*_4));
|
|
||||||
_16 = Ne(_5, const 0_isize);
|
|
||||||
assume(move _16);
|
|
||||||
_17 = Ne(_5, const 1_isize);
|
|
||||||
assume(move _17);
|
|
||||||
switchInt(move _5) -> [2: bb3, 3: bb1, otherwise: bb2];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb1: {
|
|
||||||
StorageLive(_8);
|
|
||||||
_8 = const "D";
|
|
||||||
_3 = &(*_8);
|
|
||||||
StorageDead(_8);
|
|
||||||
goto -> bb4;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb2: {
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb3: {
|
|
||||||
StorageLive(_7);
|
|
||||||
_7 = const "C";
|
|
||||||
_3 = &(*_7);
|
|
||||||
StorageDead(_7);
|
|
||||||
goto -> bb4;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb4: {
|
|
||||||
StorageDead(_4);
|
|
||||||
StorageDead(_3);
|
|
||||||
StorageLive(_9);
|
|
||||||
_10 = discriminant((_1.1: Test1));
|
|
||||||
_14 = Ne(_10, const 0_isize);
|
|
||||||
assume(move _14);
|
|
||||||
_15 = Ne(_10, const 1_isize);
|
|
||||||
assume(move _15);
|
|
||||||
switchInt(move _10) -> [2: bb6, 3: bb5, otherwise: bb2];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb5: {
|
|
||||||
StorageLive(_13);
|
|
||||||
_13 = const "D";
|
|
||||||
_9 = &(*_13);
|
|
||||||
StorageDead(_13);
|
|
||||||
goto -> bb7;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb6: {
|
|
||||||
StorageLive(_12);
|
|
||||||
_12 = const "C";
|
|
||||||
_9 = &(*_12);
|
|
||||||
StorageDead(_12);
|
|
||||||
goto -> bb7;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb7: {
|
|
||||||
StorageDead(_9);
|
|
||||||
_0 = const ();
|
|
||||||
StorageDead(_1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
// skip-filecheck
|
|
||||||
enum Empty { }
|
|
||||||
|
|
||||||
// test matching an enum with uninhabited variants
|
|
||||||
enum Test1 {
|
|
||||||
A(Empty),
|
|
||||||
B(Empty),
|
|
||||||
C,
|
|
||||||
D,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Plop {
|
|
||||||
xx: u32,
|
|
||||||
test1: Test1,
|
|
||||||
}
|
|
||||||
|
|
||||||
// EMIT_MIR uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
|
|
||||||
// EMIT_MIR uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
|
|
||||||
fn main() {
|
|
||||||
let plop = Plop { xx: 51, test1: Test1::C };
|
|
||||||
|
|
||||||
match &plop.test1 {
|
|
||||||
Test1::A(_) => "A(Empty)",
|
|
||||||
Test1::B(_) => "B(Empty)",
|
|
||||||
Test1::C => "C",
|
|
||||||
Test1::D => "D",
|
|
||||||
};
|
|
||||||
|
|
||||||
match plop.test1 {
|
|
||||||
Test1::A(_) => "A(Empty)",
|
|
||||||
Test1::B(_) => "B(Empty)",
|
|
||||||
Test1::C => "C",
|
|
||||||
Test1::D => "D",
|
|
||||||
};
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user