Properly look for uninhabitedness when handling discriminants
This commit is contained in:
parent
3eca70a0c5
commit
b7c8cc4b77
3 changed files with 15 additions and 3 deletions
|
@ -850,6 +850,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||||
) -> EvalResult<'tcx, u128> {
|
) -> EvalResult<'tcx, u128> {
|
||||||
let layout = self.layout_of(ty)?;
|
let layout = self.layout_of(ty)?;
|
||||||
trace!("read_discriminant_value {:#?}", layout);
|
trace!("read_discriminant_value {:#?}", layout);
|
||||||
|
if layout.abi == layout::Abi::Uninhabited {
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
match layout.variants {
|
match layout.variants {
|
||||||
layout::Variants::Single { index } => {
|
layout::Variants::Single { index } => {
|
||||||
|
|
|
@ -16,7 +16,7 @@ use rustc::mir::tcx::PlaceTy;
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
use base;
|
use base;
|
||||||
use builder::Builder;
|
use builder::Builder;
|
||||||
use common::{CodegenCx, C_usize, C_u8, C_u32, C_uint, C_int, C_null, C_uint_big};
|
use common::{CodegenCx, C_undef, C_usize, C_u8, C_u32, C_uint, C_int, C_null, C_uint_big};
|
||||||
use consts;
|
use consts;
|
||||||
use type_of::LayoutLlvmExt;
|
use type_of::LayoutLlvmExt;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
|
@ -264,6 +264,9 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||||
/// Obtain the actual discriminant of a value.
|
/// Obtain the actual discriminant of a value.
|
||||||
pub fn trans_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef {
|
pub fn trans_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef {
|
||||||
let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx);
|
let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx);
|
||||||
|
if self.layout.abi == layout::Abi::Uninhabited {
|
||||||
|
return C_undef(cast_to);
|
||||||
|
}
|
||||||
match self.layout.variants {
|
match self.layout.variants {
|
||||||
layout::Variants::Single { index } => {
|
layout::Variants::Single { index } => {
|
||||||
return C_uint(cast_to, index as u64);
|
return C_uint(cast_to, index as u64);
|
||||||
|
|
|
@ -22,7 +22,7 @@ use base;
|
||||||
use builder::Builder;
|
use builder::Builder;
|
||||||
use callee;
|
use callee;
|
||||||
use common::{self, val_ty};
|
use common::{self, val_ty};
|
||||||
use common::{C_bool, C_u8, C_i32, C_u32, C_u64, C_null, C_usize, C_uint, C_uint_big};
|
use common::{C_bool, C_u8, C_i32, C_u32, C_u64, C_undef, C_null, C_usize, C_uint, C_uint_big};
|
||||||
use consts;
|
use consts;
|
||||||
use monomorphize;
|
use monomorphize;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
|
@ -267,11 +267,17 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
mir::CastKind::Misc => {
|
mir::CastKind::Misc => {
|
||||||
assert!(cast.is_llvm_immediate());
|
assert!(cast.is_llvm_immediate());
|
||||||
|
let ll_t_out = cast.immediate_llvm_type(bx.cx);
|
||||||
|
if operand.layout.abi == layout::Abi::Uninhabited {
|
||||||
|
return (bx, OperandRef {
|
||||||
|
val: OperandValue::Immediate(C_undef(ll_t_out)),
|
||||||
|
layout: cast,
|
||||||
|
});
|
||||||
|
}
|
||||||
let r_t_in = CastTy::from_ty(operand.layout.ty)
|
let r_t_in = CastTy::from_ty(operand.layout.ty)
|
||||||
.expect("bad input type for cast");
|
.expect("bad input type for cast");
|
||||||
let r_t_out = CastTy::from_ty(cast.ty).expect("bad output type for cast");
|
let r_t_out = CastTy::from_ty(cast.ty).expect("bad output type for cast");
|
||||||
let ll_t_in = operand.layout.immediate_llvm_type(bx.cx);
|
let ll_t_in = operand.layout.immediate_llvm_type(bx.cx);
|
||||||
let ll_t_out = cast.immediate_llvm_type(bx.cx);
|
|
||||||
let llval = operand.immediate();
|
let llval = operand.immediate();
|
||||||
|
|
||||||
let mut signed = false;
|
let mut signed = false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue