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:
@@ -410,6 +410,14 @@ where
|
|||||||
stride * field
|
stride * field
|
||||||
}
|
}
|
||||||
layout::FieldPlacement::Union(count) => {
|
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!(
|
assert!(
|
||||||
field < count as u64,
|
field < count as u64,
|
||||||
"Tried to access field {} of union {:#?} with {} fields",
|
"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) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user