diff options
| author | bors <bors@rust-lang.org> | 2020-03-06 17:52:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-03-06 17:52:52 +0000 |
| commit | 2890b37b861247de3b8c6ba2ecbcd00048c728a1 (patch) | |
| tree | 55557297edb5bff5cbc09c94b42ff9cb236415b7 | |
| parent | 865b44a3e330f3ef8be0f6edf69896c9ed957ac0 (diff) | |
| parent | b4422fb14b9e0c030e9da6fa943f0e4850b25a85 (diff) | |
| download | rust-2890b37b861247de3b8c6ba2ecbcd00048c728a1.tar.gz rust-2890b37b861247de3b8c6ba2ecbcd00048c728a1.zip | |
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
| -rw-r--r-- | src/librustc_mir/interpret/place.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs | 91 |
2 files changed, 99 insertions, 0 deletions
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 4f96cb69891..721766cc932 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -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", diff --git a/src/test/ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs b/src/test/ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs new file mode 100644 index 00000000000..5b7c7be42cf --- /dev/null +++ b/src/test/ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs @@ -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) => {} + } +} |
