Skip to content

Commit

Permalink
Auto merge of #69753 - pnkfelix:issue-69191-ice-on-uninhabited-enum-f…
Browse files Browse the repository at this point in the history
…ield, r=oli

Do not ICE when matching an uninhabited enum's field

Fix #69191
  • Loading branch information
bors committed Mar 6, 2020
2 parents 865b44a + b4422fb commit 2890b37
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/librustc_mir/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
91 changes: 91 additions & 0 deletions src/test/ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs
Original file line number Diff line number Diff line change
@@ -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) => {}
}
}

0 comments on commit 2890b37

Please sign in to comment.