1
Fork 0

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
This commit is contained in:
bors 2020-03-06 17:52:52 +00:00
commit 2890b37b86
2 changed files with 99 additions and 0 deletions

View file

@ -410,6 +410,14 @@ where
stride * field
}
layout::FieldPlacement::Union(count) => {
// This is a narrow bug-fix for rust-lang/rust#69191: if we are
// trying to access absent field of uninhabited variant, then
// signal UB (but don't ICE the compiler).
// FIXME temporary hack to work around incoherence between
// layout computation and MIR building
if field >= count as u64 && base.layout.abi == layout::Abi::Uninhabited {
throw_ub!(Unreachable);
}
assert!(
field < count as u64,
"Tried to access field {} of union {:#?} with {} fields",

View file

@ -0,0 +1,91 @@
// build-pass
//
// (this is deliberately *not* check-pass; I have confirmed that the bug in
// question does not replicate when one uses `cargo check` alone.)
pub enum Void {}
enum UninhabitedUnivariant {
_Variant(Void),
}
enum UninhabitedMultivariant2 {
_Variant(Void),
_Warriont(Void),
}
enum UninhabitedMultivariant3 {
_Variant(Void),
_Warriont(Void),
_Worrynot(Void),
}
#[repr(C)]
enum UninhabitedUnivariantC {
_Variant(Void),
}
#[repr(i32)]
enum UninhabitedUnivariant32 {
_Variant(Void),
}
fn main() {
let _seed: UninhabitedUnivariant = None.unwrap();
match _seed {
UninhabitedUnivariant::_Variant(_x) => {}
}
let _seed: UninhabitedMultivariant2 = None.unwrap();
match _seed {
UninhabitedMultivariant2::_Variant(_x) => {}
UninhabitedMultivariant2::_Warriont(_x) => {}
}
let _seed: UninhabitedMultivariant2 = None.unwrap();
match _seed {
UninhabitedMultivariant2::_Variant(_x) => {}
_ => {}
}
let _seed: UninhabitedMultivariant2 = None.unwrap();
match _seed {
UninhabitedMultivariant2::_Warriont(_x) => {}
_ => {}
}
let _seed: UninhabitedMultivariant3 = None.unwrap();
match _seed {
UninhabitedMultivariant3::_Variant(_x) => {}
UninhabitedMultivariant3::_Warriont(_x) => {}
UninhabitedMultivariant3::_Worrynot(_x) => {}
}
let _seed: UninhabitedMultivariant3 = None.unwrap();
match _seed {
UninhabitedMultivariant3::_Variant(_x) => {}
_ => {}
}
let _seed: UninhabitedMultivariant3 = None.unwrap();
match _seed {
UninhabitedMultivariant3::_Warriont(_x) => {}
_ => {}
}
let _seed: UninhabitedMultivariant3 = None.unwrap();
match _seed {
UninhabitedMultivariant3::_Worrynot(_x) => {}
_ => {}
}
let _seed: UninhabitedUnivariantC = None.unwrap();
match _seed {
UninhabitedUnivariantC::_Variant(_x) => {}
}
let _seed: UninhabitedUnivariant32 = None.unwrap();
match _seed {
UninhabitedUnivariant32::_Variant(_x) => {}
}
}