about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_trans/mir/analyze.rs4
-rw-r--r--src/librustc_trans/mir/block.rs47
-rw-r--r--src/librustc_trans/mir/lvalue.rs1
-rw-r--r--src/librustc_trans/type_of.rs2
4 files changed, 36 insertions, 18 deletions
diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs
index 9b7b55842cc..f721e88a954 100644
--- a/src/librustc_trans/mir/analyze.rs
+++ b/src/librustc_trans/mir/analyze.rs
@@ -105,7 +105,9 @@ impl<'tcx> Visitor<'tcx> for TempAnalyzer {
         match *lvalue {
             mir::Lvalue::Temp(index) => {
                 match context {
-                    LvalueContext::Call |
+                    LvalueContext::Call => {
+                        self.mark_assigned(index as usize);
+                    }
                     LvalueContext::Consume => {
                     }
                     LvalueContext::Store |
diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs
index 7234bff4397..303cf61ad33 100644
--- a/src/librustc_trans/mir/block.rs
+++ b/src/librustc_trans/mir/block.rs
@@ -16,7 +16,7 @@ use adt;
 use base;
 use build;
 use callee::{Callee, CalleeData, Fn, Intrinsic, NamedTupleConstructor, Virtual};
-use common::{self, Block, BlockAndBuilder, C_undef};
+use common::{self, type_is_fat_ptr, Block, BlockAndBuilder, C_undef};
 use debuginfo::DebugLoc;
 use Disr;
 use machine::{llalign_of_min, llbitsize_of_real};
@@ -169,6 +169,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                     _ => bug!("{} is not callable", callee.ty)
                 };
 
+                let sig = bcx.tcx().erase_late_bound_regions(sig);
+
                 // Handle intrinsics old trans wants Expr's for, ourselves.
                 let intrinsic = match (&callee.ty.sty, &callee.data) {
                     (&ty::TyFnDef(def_id, _, _), &Intrinsic) => {
@@ -200,7 +202,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                     return;
                 }
 
-                let extra_args = &args[sig.0.inputs.len()..];
+                let extra_args = &args[sig.inputs.len()..];
                 let extra_args = extra_args.iter().map(|op_arg| {
                     self.mir.operand_ty(bcx.tcx(), op_arg)
                 }).collect::<Vec<_>>();
@@ -263,30 +265,30 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                         };
 
                         bcx.with_block(|bcx| {
-                            let res = trans_intrinsic_call(bcx, callee.ty, &fn_ty,
+                            trans_intrinsic_call(bcx, callee.ty, &fn_ty,
                                                            ArgVals(llargs), dest,
                                                            DebugLoc::None);
-                            let bcx = res.bcx.build();
-                            if let Some((_, target)) = *destination {
-                                for op in args {
-                                    self.set_operand_dropped(&bcx, op);
-                                }
-                                funclet_br(bcx, self.llblock(target));
-                            } else {
-                                // trans_intrinsic_call already used Unreachable.
-                                // bcx.unreachable();
-                            }
                         });
 
                         if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
                             // Make a fake operand for store_return
                             let op = OperandRef {
                                 val: OperandValue::Ref(dst),
-                                ty: sig.0.output.unwrap()
+                                ty: sig.output.unwrap()
                             };
                             self.store_return(&bcx, ret_dest, fn_ty.ret, op);
                         }
 
+                        if let Some((_, target)) = *destination {
+                            for op in args {
+                                self.set_operand_dropped(&bcx, op);
+                            }
+                            funclet_br(bcx, self.llblock(target));
+                        } else {
+                            // trans_intrinsic_call already used Unreachable.
+                            // bcx.unreachable();
+                        }
+
                         return;
                     }
                     Fn(f) => f,
@@ -318,7 +320,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                         ret_bcx.at_start(|ret_bcx| {
                             let op = OperandRef {
                                 val: OperandValue::Immediate(invokeret),
-                                ty: sig.0.output.unwrap()
+                                ty: sig.output.unwrap()
                             };
                             self.store_return(&ret_bcx, ret_dest, fn_ty.ret, op);
                             for op in args {
@@ -332,7 +334,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                     if let Some((_, target)) = *destination {
                         let op = OperandRef {
                             val: OperandValue::Immediate(llret),
-                            ty: sig.0.output.unwrap()
+                            ty: sig.output.unwrap()
                         };
                         self.store_return(&bcx, ret_dest, fn_ty.ret, op);
                         for op in args {
@@ -554,6 +556,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
         let dest = match *dest {
             mir::Lvalue::Temp(idx) => {
                 let lvalue_ty = self.mir.lvalue_ty(bcx.tcx(), dest);
+                let lvalue_ty = bcx.monomorphize(&lvalue_ty);
                 let ret_ty = lvalue_ty.to_ty(bcx.tcx());
                 match self.temps[idx as usize] {
                     TempRef::Lvalue(dest) => dest,
@@ -633,6 +636,18 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                 self.temps[idx as usize] = TempRef::Operand(Some(op));
             }
             DirectOperand(idx) => {
+                let op = if type_is_fat_ptr(bcx.tcx(), op.ty) {
+                    let llval = op.immediate();
+                    let ptr = bcx.extract_value(llval, 0);
+                    let meta = bcx.extract_value(llval, 1);
+
+                    OperandRef {
+                        val: OperandValue::FatPtr(ptr, meta),
+                        ty: op.ty
+                    }
+                } else {
+                    op
+                };
                 self.temps[idx as usize] = TempRef::Operand(Some(op));
             }
         }
diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs
index 13e1894df16..695806aa82c 100644
--- a/src/librustc_trans/mir/lvalue.rs
+++ b/src/librustc_trans/mir/lvalue.rs
@@ -220,6 +220,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                     TempRef::Lvalue(lvalue) => f(self, lvalue),
                     TempRef::Operand(None) => {
                         let lvalue_ty = self.mir.lvalue_ty(bcx.tcx(), lvalue);
+                        let lvalue_ty = bcx.monomorphize(&lvalue_ty);
                         let lvalue = LvalueRef::alloca(bcx,
                                                        lvalue_ty.to_ty(bcx.tcx()),
                                                        "lvalue_temp");
diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs
index 8b1aaafab58..ab3cdbee71f 100644
--- a/src/librustc_trans/type_of.rs
+++ b/src/librustc_trans/type_of.rs
@@ -182,7 +182,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
 
     debug!("type_of {:?}", t);
 
-    assert!(!t.has_escaping_regions());
+    assert!(!t.has_escaping_regions(), "{:?} has escaping regions", t);
 
     // Replace any typedef'd types with their equivalent non-typedef
     // type. This ensures that all LLVM nominal types that contain