]> git.lizzy.rs Git - rust.git/commitdiff
Properly look for uninhabitedness when handling discriminants
authorAnthony Ramine <n.oxyde@gmail.com>
Wed, 11 Apr 2018 15:25:18 +0000 (17:25 +0200)
committerAnthony Ramine <n.oxyde@gmail.com>
Thu, 26 Apr 2018 13:07:04 +0000 (15:07 +0200)
src/librustc_mir/interpret/eval_context.rs
src/librustc_trans/mir/place.rs
src/librustc_trans/mir/rvalue.rs

index b98ab218de5cb5cd7bc1a6b45cb492543d592ac7..478f45e841d1c720e0dc6b0e188a3063b9a0fac6 100644 (file)
@@ -850,6 +850,9 @@ pub fn read_discriminant_value(
     ) -> EvalResult<'tcx, u128> {
         let layout = self.layout_of(ty)?;
         trace!("read_discriminant_value {:#?}", layout);
+        if layout.abi == layout::Abi::Uninhabited {
+            return Ok(0);
+        }
 
         match layout.variants {
             layout::Variants::Single { index } => {
index b340d91b02708edf0eed3de96b9ff70c8cfb8cfd..3cadaef47bb660ac26242341bd90127662144f78 100644 (file)
@@ -16,7 +16,7 @@
 use rustc_data_structures::indexed_vec::Idx;
 use base;
 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 type_of::LayoutLlvmExt;
 use type_::Type;
@@ -264,6 +264,9 @@ pub fn project_field(self, bx: &Builder<'a, 'tcx>, ix: usize) -> PlaceRef<'tcx>
     /// Obtain the actual discriminant of a value.
     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);
+        if self.layout.abi == layout::Abi::Uninhabited {
+            return C_undef(cast_to);
+        }
         match self.layout.variants {
             layout::Variants::Single { index } => {
                 return C_uint(cast_to, index as u64);
index 93702bfbbf3b1a00bb292c8cf9c7c0bd96ea3b17..245f3ec11c96d6d2f2baf2989fcebbea0db8373f 100644 (file)
@@ -22,7 +22,7 @@
 use builder::Builder;
 use callee;
 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 monomorphize;
 use type_::Type;
@@ -267,11 +267,17 @@ pub fn trans_rvalue_operand(&mut self,
                     }
                     mir::CastKind::Misc => {
                         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)
                             .expect("bad input 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_out = cast.immediate_llvm_type(bx.cx);
                         let llval = operand.immediate();
 
                         let mut signed = false;