Skip to content

Replace switch to unreachable by assume statements #113970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
FileCheck uninhabited_enum_branching.
  • Loading branch information
cjgillot committed Oct 31, 2023
commit ae2e21114becdd27b426baaa385a90aca0cfa412
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
- // MIR for `main` before UninhabitedEnumBranching
+ // MIR for `main` after UninhabitedEnumBranching
- // MIR for `byref` before UninhabitedEnumBranching
+ // MIR for `byref` after UninhabitedEnumBranching

fn main() -> () {
fn byref() -> () {
let mut _0: ();
let _1: Plop;
let mut _2: Test1;
let mut _2: Test3;
let _3: &str;
let mut _4: &Test1;
let mut _4: &Test3;
let mut _5: isize;
let _6: &str;
let _7: &str;
Expand All @@ -23,12 +23,12 @@
bb0: {
StorageLive(_1);
StorageLive(_2);
_2 = Test1::C;
_1 = Plop { xx: const 51_u32, test1: move _2 };
_2 = Test3::C;
_1 = Plop { xx: const 51_u32, test3: move _2 };
StorageDead(_2);
StorageLive(_3);
StorageLive(_4);
_4 = &(_1.1: Test1);
_4 = &(_1.1: Test3);
_5 = discriminant((*_4));
- 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];
Expand Down Expand Up @@ -71,7 +71,7 @@
StorageDead(_4);
StorageDead(_3);
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: bb12, 1: bb12, 2: bb10, 3: bb7, otherwise: bb12];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}

This file was deleted.

70 changes: 64 additions & 6 deletions tests/mir-opt/uninhabited_enum_branching.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// skip-filecheck
enum Empty { }
// unit-test: UninhabitedEnumBranching
enum Empty {}

// test matching an enum with uninhabited variants
enum Test1 {
A(Empty),
B(Empty),
C
C,
}

// test an enum where the discriminants don't match the variant indexes
Expand All @@ -15,17 +15,75 @@ enum Test2 {
E = 5,
}

// EMIT_MIR uninhabited_enum_branching.main.UninhabitedEnumBranching.diff
// EMIT_MIR uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
fn main() {
// test matching an enum with uninhabited variants and multiple inhabited
enum Test3 {
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 {
Test1::A(_) => "A(Empty)",
Test1::B(_) => "B(Empty)",
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 {
Test2::D => "D",
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();
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
- // MIR for `main` before UninhabitedEnumBranching
+ // MIR for `main` after UninhabitedEnumBranching
- // MIR for `simple` before UninhabitedEnumBranching
+ // MIR for `simple` after UninhabitedEnumBranching

fn main() -> () {
fn simple() -> () {
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;

bb0: {
StorageLive(_1);
StorageLive(_2);
_2 = Test1::C;
_3 = discriminant(_2);
- 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: {
Expand Down Expand Up @@ -50,35 +46,11 @@
bb5: {
StorageDead(_2);
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 ();
return;
+ }
+
+ bb9: {
+ bb6: {
+ unreachable;
}
}
Expand Down
Loading