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:
commit
2890b37b86
2 changed files with 99 additions and 0 deletions
|
@ -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",
|
||||
|
|
|
@ -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) => {}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue