Skip to content

Commit d02299c

Browse files
committed
Get all variants to eliminate the default branching if we cannot get the layout of type
1 parent e8c09fd commit d02299c

8 files changed

+100
-111
lines changed

compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs

+6
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
9595

9696
let mut allowed_variants = if let Ok(layout) = layout {
9797
variant_discriminants(&layout, discriminant_ty, tcx)
98+
} else if let Some(variant_range) = discriminant_ty.variant_range(tcx) {
99+
variant_range
100+
.map(|variant| {
101+
discriminant_ty.discriminant_for_variant(tcx, variant).unwrap().val
102+
})
103+
.collect()
98104
} else {
99105
continue;
100106
};

tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir

+38-22
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
fn num_to_digit(_1: char) -> u32 {
44
debug num => _1;
55
let mut _0: u32;
6-
let mut _5: std::option::Option<u32>;
6+
let mut _5: bool;
7+
let mut _6: std::option::Option<u32>;
78
scope 1 (inlined char::methods::<impl char>::is_digit) {
89
debug self => _1;
910
debug radix => const 8_u32;
@@ -15,15 +16,16 @@ fn num_to_digit(_1: char) -> u32 {
1516
}
1617
}
1718
scope 3 (inlined #[track_caller] Option::<u32>::unwrap) {
18-
debug self => _5;
19-
let mut _6: isize;
20-
let mut _7: !;
19+
debug self => _6;
20+
let mut _7: isize;
21+
let mut _8: !;
2122
scope 4 {
2223
debug val => _0;
2324
}
2425
}
2526

2627
bb0: {
28+
StorageLive(_5);
2729
StorageLive(_3);
2830
StorageLive(_2);
2931
_2 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> [return: bb1, unwind unreachable];
@@ -33,45 +35,59 @@ fn num_to_digit(_1: char) -> u32 {
3335
_3 = &_2;
3436
StorageLive(_4);
3537
_4 = discriminant(_2);
36-
StorageDead(_3);
37-
StorageDead(_2);
38-
switchInt(move _4) -> [1: bb2, otherwise: bb7];
38+
switchInt(move _4) -> [1: bb2, 0: bb3, otherwise: bb11];
3939
}
4040

4141
bb2: {
42-
StorageDead(_4);
43-
StorageLive(_5);
44-
_5 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable];
42+
_5 = const true;
43+
goto -> bb4;
4544
}
4645

4746
bb3: {
48-
StorageLive(_6);
49-
_6 = discriminant(_5);
50-
switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb6];
47+
_5 = const false;
48+
goto -> bb4;
5149
}
5250

5351
bb4: {
54-
_7 = option::unwrap_failed() -> unwind unreachable;
52+
StorageDead(_4);
53+
StorageDead(_3);
54+
StorageDead(_2);
55+
switchInt(move _5) -> [0: bb5, otherwise: bb6];
5556
}
5657

5758
bb5: {
58-
_0 = move ((_5 as Some).0: u32);
59-
StorageDead(_6);
60-
StorageDead(_5);
61-
goto -> bb8;
59+
_0 = const 0_u32;
60+
goto -> bb10;
6261
}
6362

6463
bb6: {
65-
unreachable;
64+
StorageLive(_6);
65+
_6 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb7, unwind unreachable];
6666
}
6767

6868
bb7: {
69-
StorageDead(_4);
70-
_0 = const 0_u32;
71-
goto -> bb8;
69+
StorageLive(_7);
70+
_7 = discriminant(_6);
71+
switchInt(move _7) -> [0: bb8, 1: bb9, otherwise: bb11];
7272
}
7373

7474
bb8: {
75+
_8 = option::unwrap_failed() -> unwind unreachable;
76+
}
77+
78+
bb9: {
79+
_0 = move ((_6 as Some).0: u32);
80+
StorageDead(_7);
81+
StorageDead(_6);
82+
goto -> bb10;
83+
}
84+
85+
bb10: {
86+
StorageDead(_5);
7587
return;
7688
}
89+
90+
bb11: {
91+
unreachable;
92+
}
7793
}

tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir

+38-22
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
fn num_to_digit(_1: char) -> u32 {
44
debug num => _1;
55
let mut _0: u32;
6-
let mut _5: std::option::Option<u32>;
6+
let mut _5: bool;
7+
let mut _6: std::option::Option<u32>;
78
scope 1 (inlined char::methods::<impl char>::is_digit) {
89
debug self => _1;
910
debug radix => const 8_u32;
@@ -15,15 +16,16 @@ fn num_to_digit(_1: char) -> u32 {
1516
}
1617
}
1718
scope 3 (inlined #[track_caller] Option::<u32>::unwrap) {
18-
debug self => _5;
19-
let mut _6: isize;
20-
let mut _7: !;
19+
debug self => _6;
20+
let mut _7: isize;
21+
let mut _8: !;
2122
scope 4 {
2223
debug val => _0;
2324
}
2425
}
2526

2627
bb0: {
28+
StorageLive(_5);
2729
StorageLive(_3);
2830
StorageLive(_2);
2931
_2 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> [return: bb1, unwind continue];
@@ -33,45 +35,59 @@ fn num_to_digit(_1: char) -> u32 {
3335
_3 = &_2;
3436
StorageLive(_4);
3537
_4 = discriminant(_2);
36-
StorageDead(_3);
37-
StorageDead(_2);
38-
switchInt(move _4) -> [1: bb2, otherwise: bb7];
38+
switchInt(move _4) -> [1: bb2, 0: bb3, otherwise: bb11];
3939
}
4040

4141
bb2: {
42-
StorageDead(_4);
43-
StorageLive(_5);
44-
_5 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind continue];
42+
_5 = const true;
43+
goto -> bb4;
4544
}
4645

4746
bb3: {
48-
StorageLive(_6);
49-
_6 = discriminant(_5);
50-
switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb6];
47+
_5 = const false;
48+
goto -> bb4;
5149
}
5250

5351
bb4: {
54-
_7 = option::unwrap_failed() -> unwind continue;
52+
StorageDead(_4);
53+
StorageDead(_3);
54+
StorageDead(_2);
55+
switchInt(move _5) -> [0: bb5, otherwise: bb6];
5556
}
5657

5758
bb5: {
58-
_0 = move ((_5 as Some).0: u32);
59-
StorageDead(_6);
60-
StorageDead(_5);
61-
goto -> bb8;
59+
_0 = const 0_u32;
60+
goto -> bb10;
6261
}
6362

6463
bb6: {
65-
unreachable;
64+
StorageLive(_6);
65+
_6 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb7, unwind continue];
6666
}
6767

6868
bb7: {
69-
StorageDead(_4);
70-
_0 = const 0_u32;
71-
goto -> bb8;
69+
StorageLive(_7);
70+
_7 = discriminant(_6);
71+
switchInt(move _7) -> [0: bb8, 1: bb9, otherwise: bb11];
7272
}
7373

7474
bb8: {
75+
_8 = option::unwrap_failed() -> unwind continue;
76+
}
77+
78+
bb9: {
79+
_0 = move ((_6 as Some).0: u32);
80+
StorageDead(_7);
81+
StorageDead(_6);
82+
goto -> bb10;
83+
}
84+
85+
bb10: {
86+
StorageDead(_5);
7587
return;
7688
}
89+
90+
bb11: {
91+
unreachable;
92+
}
7793
}

tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir

+1-55
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,12 @@ fn step_forward(_1: u32, _2: usize) -> u32 {
44
debug x => _1;
55
debug n => _2;
66
let mut _0: u32;
7-
scope 1 (inlined <u32 as Step>::forward) {
8-
debug start => _1;
9-
debug n => _2;
10-
let _3: std::option::Option<u32>;
11-
let mut _4: &std::option::Option<u32>;
12-
let mut _7: bool;
13-
let mut _8: u32;
14-
scope 2 {
15-
}
16-
scope 3 (inlined Option::<u32>::is_none) {
17-
debug self => _4;
18-
let mut _6: bool;
19-
scope 4 (inlined Option::<u32>::is_some) {
20-
debug self => _4;
21-
let mut _5: isize;
22-
}
23-
}
24-
scope 5 (inlined core::num::<impl u32>::wrapping_add) {
25-
debug self => _1;
26-
debug rhs => _8;
27-
}
28-
}
297

308
bb0: {
31-
StorageLive(_7);
32-
StorageLive(_4);
33-
StorageLive(_3);
34-
_3 = <u32 as Step>::forward_checked(_1, _2) -> [return: bb1, unwind continue];
9+
_0 = <u32 as Step>::forward(move _1, move _2) -> [return: bb1, unwind continue];
3510
}
3611

3712
bb1: {
38-
_4 = &_3;
39-
StorageLive(_6);
40-
StorageLive(_5);
41-
_5 = discriminant(_3);
42-
_6 = Eq(_5, const 1_isize);
43-
StorageDead(_5);
44-
_7 = Not(move _6);
45-
StorageDead(_6);
46-
switchInt(move _7) -> [0: bb2, otherwise: bb3];
47-
}
48-
49-
bb2: {
50-
StorageDead(_3);
51-
StorageDead(_4);
52-
goto -> bb4;
53-
}
54-
55-
bb3: {
56-
StorageDead(_3);
57-
StorageDead(_4);
58-
assert(!const true, "attempt to compute `{} + {}`, which would overflow", const _, const 1_u32) -> [success: bb4, unwind continue];
59-
}
60-
61-
bb4: {
62-
StorageDead(_7);
63-
StorageLive(_8);
64-
_8 = _2 as u32 (IntToInt);
65-
_0 = Add(_1, _8);
66-
StorageDead(_8);
6713
return;
6814
}
6915
}

tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
bb1: {
3030
_4 = discriminant((_1.1: std::option::Option<T>));
31-
switchInt(move _4) -> [0: bb2, otherwise: bb3];
31+
switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb5];
3232
}
3333

3434
bb2: {

tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
bb1: {
3030
_4 = discriminant((_1.1: std::option::Option<T>));
31-
switchInt(move _4) -> [0: bb2, otherwise: bb3];
31+
switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb5];
3232
}
3333

3434
bb2: {

tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.diff

+7-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
let mut _0: ();
66
let _1: &str;
77
let mut _2: Test5<T>;
8-
let mut _3: isize;
8+
let mut _3: i8;
99
let _4: &str;
1010
let _5: &str;
1111
let _6: &str;
@@ -15,7 +15,8 @@
1515
StorageLive(_2);
1616
_2 = Test5::<T>::C;
1717
_3 = discriminant(_2);
18-
switchInt(move _3) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb1];
18+
- switchInt(move _3) -> [255: bb2, 0: bb3, 5: bb4, otherwise: bb1];
19+
+ switchInt(move _3) -> [255: bb2, 0: bb3, 5: bb4, 3: bb1, otherwise: bb8];
1920
}
2021

2122
bb1: {
@@ -60,6 +61,10 @@
6061

6162
bb7 (cleanup): {
6263
resume;
64+
+ }
65+
+
66+
+ bb8: {
67+
+ unreachable;
6368
}
6469
}
6570

tests/mir-opt/uninhabited_enum_branching.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ enum Test4 {
3030
D,
3131
}
3232

33+
#[repr(i8)]
3334
enum Test5<T> {
34-
A(T),
35-
B(T),
36-
C,
37-
D,
35+
A(T) = -1,
36+
B(T) = 0,
37+
C = 5,
38+
D = 3,
3839
}
3940

4041
struct Plop {
@@ -163,10 +164,9 @@ fn otherwise_t4() {
163164
fn otherwise_t5_uninhabited_default<T>() {
164165
// CHECK-LABEL: fn otherwise_t5_uninhabited_default(
165166
// CHECK: [[discr:_.*]] = discriminant(
166-
// CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb1];
167-
// CHECK: bb1: {
168-
// CHECK-NOT: unreachable;
169-
// CHECK: }
167+
// CHECK: switchInt(move [[discr]]) -> [255: bb2, 0: bb3, 5: bb4, 3: bb1, otherwise: [[unreachable:bb.*]]];
168+
// CHECK: [[unreachable]]: {
169+
// CHECK-NEXT: unreachable;
170170
match Test5::<T>::C {
171171
Test5::A(_) => "A(T)",
172172
Test5::B(_) => "B(T)",

0 commit comments

Comments
 (0)