Skip to content

Commit 2890b37

Browse files
committed
Auto merge of #69753 - pnkfelix:issue-69191-ice-on-uninhabited-enum-field, r=oli
Do not ICE when matching an uninhabited enum's field Fix #69191
2 parents 865b44a + b4422fb commit 2890b37

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

src/librustc_mir/interpret/place.rs

+8
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,14 @@ where
410410
stride * field
411411
}
412412
layout::FieldPlacement::Union(count) => {
413+
// This is a narrow bug-fix for rust-lang/rust#69191: if we are
414+
// trying to access absent field of uninhabited variant, then
415+
// signal UB (but don't ICE the compiler).
416+
// FIXME temporary hack to work around incoherence between
417+
// layout computation and MIR building
418+
if field >= count as u64 && base.layout.abi == layout::Abi::Uninhabited {
419+
throw_ub!(Unreachable);
420+
}
413421
assert!(
414422
field < count as u64,
415423
"Tried to access field {} of union {:#?} with {} fields",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// build-pass
2+
//
3+
// (this is deliberately *not* check-pass; I have confirmed that the bug in
4+
// question does not replicate when one uses `cargo check` alone.)
5+
6+
pub enum Void {}
7+
8+
enum UninhabitedUnivariant {
9+
_Variant(Void),
10+
}
11+
12+
enum UninhabitedMultivariant2 {
13+
_Variant(Void),
14+
_Warriont(Void),
15+
}
16+
17+
enum UninhabitedMultivariant3 {
18+
_Variant(Void),
19+
_Warriont(Void),
20+
_Worrynot(Void),
21+
}
22+
23+
#[repr(C)]
24+
enum UninhabitedUnivariantC {
25+
_Variant(Void),
26+
}
27+
28+
#[repr(i32)]
29+
enum UninhabitedUnivariant32 {
30+
_Variant(Void),
31+
}
32+
33+
fn main() {
34+
let _seed: UninhabitedUnivariant = None.unwrap();
35+
match _seed {
36+
UninhabitedUnivariant::_Variant(_x) => {}
37+
}
38+
39+
let _seed: UninhabitedMultivariant2 = None.unwrap();
40+
match _seed {
41+
UninhabitedMultivariant2::_Variant(_x) => {}
42+
UninhabitedMultivariant2::_Warriont(_x) => {}
43+
}
44+
45+
let _seed: UninhabitedMultivariant2 = None.unwrap();
46+
match _seed {
47+
UninhabitedMultivariant2::_Variant(_x) => {}
48+
_ => {}
49+
}
50+
51+
let _seed: UninhabitedMultivariant2 = None.unwrap();
52+
match _seed {
53+
UninhabitedMultivariant2::_Warriont(_x) => {}
54+
_ => {}
55+
}
56+
57+
let _seed: UninhabitedMultivariant3 = None.unwrap();
58+
match _seed {
59+
UninhabitedMultivariant3::_Variant(_x) => {}
60+
UninhabitedMultivariant3::_Warriont(_x) => {}
61+
UninhabitedMultivariant3::_Worrynot(_x) => {}
62+
}
63+
64+
let _seed: UninhabitedMultivariant3 = None.unwrap();
65+
match _seed {
66+
UninhabitedMultivariant3::_Variant(_x) => {}
67+
_ => {}
68+
}
69+
70+
let _seed: UninhabitedMultivariant3 = None.unwrap();
71+
match _seed {
72+
UninhabitedMultivariant3::_Warriont(_x) => {}
73+
_ => {}
74+
}
75+
76+
let _seed: UninhabitedMultivariant3 = None.unwrap();
77+
match _seed {
78+
UninhabitedMultivariant3::_Worrynot(_x) => {}
79+
_ => {}
80+
}
81+
82+
let _seed: UninhabitedUnivariantC = None.unwrap();
83+
match _seed {
84+
UninhabitedUnivariantC::_Variant(_x) => {}
85+
}
86+
87+
let _seed: UninhabitedUnivariant32 = None.unwrap();
88+
match _seed {
89+
UninhabitedUnivariant32::_Variant(_x) => {}
90+
}
91+
}

0 commit comments

Comments
 (0)