Skip to content

Commit 0a41061

Browse files
noxXandkeeper
authored andcommitted
Properly look for uninhabitedness when handling discriminants
1 parent d4ebf73 commit 0a41061

File tree

3 files changed

+15
-3
lines changed

3 files changed

+15
-3
lines changed

src/librustc_mir/interpret/eval_context.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
852852
) -> EvalResult<'tcx, u128> {
853853
let layout = self.layout_of(ty)?;
854854
trace!("read_discriminant_value {:#?}", layout);
855+
if layout.abi == layout::Abi::Uninhabited {
856+
return Ok(0);
857+
}
855858

856859
match layout.variants {
857860
layout::Variants::Single { index } => {

src/librustc_trans/mir/place.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc::mir::tcx::PlaceTy;
1616
use rustc_data_structures::indexed_vec::Idx;
1717
use base;
1818
use builder::Builder;
19-
use common::{CodegenCx, C_usize, C_u8, C_u32, C_uint, C_int, C_null, C_uint_big};
19+
use common::{CodegenCx, C_undef, C_usize, C_u8, C_u32, C_uint, C_int, C_null, C_uint_big};
2020
use consts;
2121
use type_of::LayoutLlvmExt;
2222
use type_::Type;
@@ -264,6 +264,9 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
264264
/// Obtain the actual discriminant of a value.
265265
pub fn trans_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef {
266266
let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx);
267+
if self.layout.abi == layout::Abi::Uninhabited {
268+
return C_undef(cast_to);
269+
}
267270
match self.layout.variants {
268271
layout::Variants::Single { index } => {
269272
return C_uint(cast_to, index as u64);

src/librustc_trans/mir/rvalue.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use base;
2222
use builder::Builder;
2323
use callee;
2424
use common::{self, val_ty};
25-
use common::{C_bool, C_u8, C_i32, C_u32, C_u64, C_null, C_usize, C_uint, C_uint_big};
25+
use common::{C_bool, C_u8, C_i32, C_u32, C_u64, C_undef, C_null, C_usize, C_uint, C_uint_big};
2626
use consts;
2727
use monomorphize;
2828
use type_::Type;
@@ -267,11 +267,17 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
267267
}
268268
mir::CastKind::Misc => {
269269
assert!(cast.is_llvm_immediate());
270+
let ll_t_out = cast.immediate_llvm_type(bx.cx);
271+
if operand.layout.abi == layout::Abi::Uninhabited {
272+
return (bx, OperandRef {
273+
val: OperandValue::Immediate(C_undef(ll_t_out)),
274+
layout: cast,
275+
});
276+
}
270277
let r_t_in = CastTy::from_ty(operand.layout.ty)
271278
.expect("bad input type for cast");
272279
let r_t_out = CastTy::from_ty(cast.ty).expect("bad output type for cast");
273280
let ll_t_in = operand.layout.immediate_llvm_type(bx.cx);
274-
let ll_t_out = cast.immediate_llvm_type(bx.cx);
275281
let llval = operand.immediate();
276282

277283
let mut signed = false;

0 commit comments

Comments
 (0)