about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_trans/common.rs25
-rw-r--r--src/librustc_trans/mir/analyze.rs29
-rw-r--r--src/librustc_trans/mir/block.rs4
-rw-r--r--src/librustc_trans/mir/constant.rs7
-rw-r--r--src/librustc_trans/mir/lvalue.rs6
-rw-r--r--src/librustc_trans/mir/mod.rs25
-rw-r--r--src/librustc_trans/mir/operand.rs2
-rw-r--r--src/librustc_trans/mir/rvalue.rs6
8 files changed, 48 insertions, 56 deletions
diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs
index 528ecf2a426..9a6127746ff 100644
--- a/src/librustc_trans/common.rs
+++ b/src/librustc_trans/common.rs
@@ -20,10 +20,8 @@ use monomorphize::Instance;
 use rustc::hir::def::Def;
 use rustc::hir::def_id::DefId;
 use rustc::hir::map::DefPathData;
-use rustc::infer::TransNormalize;
 use rustc::util::common::MemoizationMap;
 use middle::lang_items::LangItem;
-use rustc::ty::subst::Substs;
 use abi::{Abi, FnType};
 use base;
 use builder::Builder;
@@ -37,7 +35,6 @@ use value::Value;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::layout::Layout;
 use rustc::traits::{self, SelectionContext, Reveal};
-use rustc::ty::fold::TypeFoldable;
 use rustc::hir;
 
 use libc::{c_uint, c_char};
@@ -249,10 +246,6 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
     // Describes the return/argument LLVM types and their ABI handling.
     pub fn_ty: FnType,
 
-    // If this function is being monomorphized, this contains the type
-    // substitutions used.
-    pub param_substs: &'tcx Substs<'tcx>,
-
     // This function's enclosing crate context.
     pub ccx: &'a CrateContext<'a, 'tcx>,
 
@@ -266,23 +259,13 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
         ccx: &'a CrateContext<'a, 'tcx>,
         llfndecl: ValueRef,
         fn_ty: FnType,
-        definition: Option<(Instance<'tcx>, &ty::FnSig<'tcx>, Abi)>,
         skip_retptr: bool,
     ) -> FunctionContext<'a, 'tcx> {
-        let param_substs = match definition {
-            Some((instance, ..)) => {
-                assert!(!instance.substs.needs_infer());
-                instance.substs
-            }
-            None => ccx.tcx().intern_substs(&[])
-        };
-
         let mut fcx = FunctionContext {
             llfn: llfndecl,
             llretslotptr: None,
             alloca_insert_pt: None,
             fn_ty: fn_ty,
-            param_substs: param_substs,
             ccx: ccx,
             alloca_builder: Builder::with_ccx(ccx),
         };
@@ -340,14 +323,6 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
         BlockAndBuilder::new(self.new_block(name), self)
     }
 
-    pub fn monomorphize<T>(&self, value: &T) -> T
-        where T: TransNormalize<'tcx>
-    {
-        monomorphize::apply_param_substs(self.ccx.shared(),
-                                         self.param_substs,
-                                         value)
-    }
-
     pub fn eh_personality(&self) -> ValueRef {
         // The exception handling personality function.
         //
diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs
index 38e21bdefb2..71375f1160c 100644
--- a/src/librustc_trans/mir/analyze.rs
+++ b/src/librustc_trans/mir/analyze.rs
@@ -17,15 +17,18 @@ use rustc::mir::{self, Location, TerminatorKind};
 use rustc::mir::visit::{Visitor, LvalueContext};
 use rustc::mir::traversal;
 use common::{self, BlockAndBuilder};
+use super::MirContext;
 use super::rvalue;
 
-pub fn lvalue_locals<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>, mir: &mir::Mir<'tcx>) -> BitVector {
-    let mut analyzer = LocalAnalyzer::new(mir, &bcx);
+pub fn lvalue_locals<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>, mircx: &MirContext<'a, 'tcx>)
+    -> BitVector {
+    let mir = mircx.mir;
+    let mut analyzer = LocalAnalyzer::new(mircx, &bcx);
 
     analyzer.visit_mir(mir);
 
     for (index, ty) in mir.local_decls.iter().map(|l| l.ty).enumerate() {
-        let ty = bcx.fcx().monomorphize(&ty);
+        let ty = mircx.monomorphize(&ty);
         debug!("local {} has type {:?}", index, ty);
         if ty.is_scalar() ||
             ty.is_unique() ||
@@ -54,20 +57,20 @@ pub fn lvalue_locals<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>, mir: &mir::Mir<'
 }
 
 struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> {
-    mir: &'mir mir::Mir<'tcx>,
+    mir: &'mir MirContext<'a, 'tcx>,
     bcx: &'mir BlockAndBuilder<'a, 'tcx>,
     lvalue_locals: BitVector,
     seen_assigned: BitVector
 }
 
 impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> {
-    fn new(mir: &'mir mir::Mir<'tcx>, bcx: &'mir BlockAndBuilder<'a, 'tcx>)
+    fn new(mircx: &'mir MirContext<'a, 'tcx>, bcx: &'mir BlockAndBuilder<'a, 'tcx>)
            -> LocalAnalyzer<'mir, 'a, 'tcx> {
         LocalAnalyzer {
-            mir: mir,
+            mir: mircx,
             bcx: bcx,
-            lvalue_locals: BitVector::new(mir.local_decls.len()),
-            seen_assigned: BitVector::new(mir.local_decls.len())
+            lvalue_locals: BitVector::new(mircx.mir.local_decls.len()),
+            seen_assigned: BitVector::new(mircx.mir.local_decls.len())
         }
     }
 
@@ -93,7 +96,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
 
         if let mir::Lvalue::Local(index) = *lvalue {
             self.mark_assigned(index);
-            if !rvalue::rvalue_creates_operand(self.mir, self.bcx, rvalue) {
+            if !rvalue::rvalue_creates_operand(self.mir.mir, self.bcx, rvalue) {
                 self.mark_as_lvalue(index);
             }
         } else {
@@ -136,9 +139,9 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
         // Allow uses of projections of immediate pair fields.
         if let mir::Lvalue::Projection(ref proj) = *lvalue {
             if let mir::Lvalue::Local(_) = proj.base {
-                let ty = proj.base.ty(self.mir, self.bcx.tcx());
+                let ty = proj.base.ty(self.mir.mir, self.bcx.tcx());
 
-                let ty = self.bcx.fcx().monomorphize(&ty.to_ty(self.bcx.tcx()));
+                let ty = self.mir.monomorphize(&ty.to_ty(self.bcx.tcx()));
                 if common::type_is_imm_pair(self.bcx.ccx(), ty) {
                     if let mir::ProjectionElem::Field(..) = proj.elem {
                         if let LvalueContext::Consume = context {
@@ -167,8 +170,8 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
                 }
 
                 LvalueContext::Drop => {
-                    let ty = lvalue.ty(self.mir, self.bcx.tcx());
-                    let ty = self.bcx.fcx().monomorphize(&ty.to_ty(self.bcx.tcx()));
+                    let ty = lvalue.ty(self.mir.mir, self.bcx.tcx());
+                    let ty = self.mir.monomorphize(&ty.to_ty(self.bcx.tcx()));
 
                     // Only need the lvalue if we're actually dropping it.
                     if self.bcx.ccx().shared().type_needs_drop(ty) {
diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs
index 2ccf92a743e..577c304d0f7 100644
--- a/src/librustc_trans/mir/block.rs
+++ b/src/librustc_trans/mir/block.rs
@@ -242,7 +242,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
 
             mir::TerminatorKind::Drop { ref location, target, unwind } => {
                 let ty = location.ty(&self.mir, bcx.tcx()).to_ty(bcx.tcx());
-                let ty = bcx.fcx().monomorphize(&ty);
+                let ty = self.monomorphize(&ty);
 
                 // Double check for necessity to drop
                 if !bcx.ccx().shared().type_needs_drop(ty) {
@@ -522,7 +522,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
                 let extra_args = &args[sig.inputs().len()..];
                 let extra_args = extra_args.iter().map(|op_arg| {
                     let op_ty = op_arg.ty(&self.mir, bcx.tcx());
-                    bcx.fcx().monomorphize(&op_ty)
+                    self.monomorphize(&op_ty)
                 }).collect::<Vec<_>>();
                 let fn_ty = callee.direct_fn_type(bcx.ccx(), &extra_args);
 
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index 9628ed25406..56f88977c86 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -952,7 +952,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
                           -> Const<'tcx>
     {
         debug!("trans_constant({:?})", constant);
-        let ty = bcx.fcx().monomorphize(&constant.ty);
+        let ty = self.monomorphize(&constant.ty);
         let result = match constant.literal.clone() {
             mir::Literal::Item { def_id, substs } => {
                 // Shortcut for zero-sized types, including function item
@@ -962,14 +962,13 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
                     return Const::new(C_null(llty), ty);
                 }
 
-                let substs = bcx.fcx().monomorphize(&substs);
+                let substs = self.monomorphize(&substs);
                 let instance = Instance::new(def_id, substs);
                 MirConstContext::trans_def(bcx.ccx(), instance, IndexVec::new())
             }
             mir::Literal::Promoted { index } => {
                 let mir = &self.mir.promoted[index];
-                MirConstContext::new(bcx.ccx(), mir, bcx.fcx().param_substs,
-                                     IndexVec::new()).trans()
+                MirConstContext::new(bcx.ccx(), mir, self.param_substs, IndexVec::new()).trans()
             }
             mir::Literal::Value { value } => {
                 Ok(Const::from_constval(bcx.ccx(), value, ty))
diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs
index 1582dc9a6aa..673a786f1f8 100644
--- a/src/librustc_trans/mir/lvalue.rs
+++ b/src/librustc_trans/mir/lvalue.rs
@@ -103,7 +103,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
                 let ptr = self.trans_consume(bcx, base);
                 let projected_ty = LvalueTy::from_ty(ptr.ty)
                     .projection_ty(tcx, &mir::ProjectionElem::Deref);
-                let projected_ty = bcx.fcx().monomorphize(&projected_ty);
+                let projected_ty = self.monomorphize(&projected_ty);
                 let (llptr, llextra) = match ptr.val {
                     OperandValue::Immediate(llptr) => (llptr, ptr::null_mut()),
                     OperandValue::Pair(llptr, llextra) => (llptr, llextra),
@@ -118,7 +118,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
             mir::Lvalue::Projection(ref projection) => {
                 let tr_base = self.trans_lvalue(bcx, &projection.base);
                 let projected_ty = tr_base.ty.projection_ty(tcx, &projection.elem);
-                let projected_ty = bcx.fcx().monomorphize(&projected_ty);
+                let projected_ty = self.monomorphize(&projected_ty);
 
                 let project_index = |llindex| {
                     let element = if let ty::TySlice(_) = tr_base.ty.to_ty(tcx).sty {
@@ -274,6 +274,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
     pub fn monomorphized_lvalue_ty(&self, lvalue: &mir::Lvalue<'tcx>) -> Ty<'tcx> {
         let tcx = self.fcx.ccx.tcx();
         let lvalue_ty = lvalue.ty(&self.mir, tcx);
-        self.fcx.monomorphize(&lvalue_ty.to_ty(tcx))
+        self.monomorphize(&lvalue_ty.to_ty(tcx))
     }
 }
diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs
index 6fbbaa7bc76..6f376251d9b 100644
--- a/src/librustc_trans/mir/mod.rs
+++ b/src/librustc_trans/mir/mod.rs
@@ -14,11 +14,14 @@ use llvm::debuginfo::DIScope;
 use rustc::ty;
 use rustc::mir::{self, Mir};
 use rustc::mir::tcx::LvalueTy;
+use rustc::ty::subst::Substs;
+use rustc::infer::TransNormalize;
+use rustc::ty::TypeFoldable;
 use session::config::FullDebugInfo;
 use base;
 use common::{self, BlockAndBuilder, CrateContext, FunctionContext, C_null, Funclet};
 use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext};
-use monomorphize::Instance;
+use monomorphize::{self, Instance};
 use machine;
 use type_of;
 
@@ -88,9 +91,17 @@ pub struct MirContext<'a, 'tcx:'a> {
 
     /// Debug information for MIR scopes.
     scopes: IndexVec<mir::VisibilityScope, debuginfo::MirDebugScope>,
+
+    /// If this function is being monomorphized, this contains the type substitutions used.
+    param_substs: &'tcx Substs<'tcx>,
 }
 
 impl<'a, 'tcx> MirContext<'a, 'tcx> {
+    pub fn monomorphize<T>(&self, value: &T) -> T
+        where T: TransNormalize<'tcx> {
+        monomorphize::apply_param_substs(self.fcx.ccx.shared(), self.param_substs, value)
+    }
+
     pub fn debug_loc(&mut self, source_info: mir::SourceInfo) -> (DIScope, Span) {
         // Bail out if debug info emission is not enabled.
         match self.debug_context {
@@ -207,8 +218,6 @@ pub fn trans_mir<'a, 'tcx: 'a>(
     let bcx = fcx.get_entry_block();
 
     // Analyze the temps to determine which must be lvalues
-    // FIXME
-    let lvalue_locals = analyze::lvalue_locals(&bcx, &mir);
     let cleanup_kinds = analyze::cleanup_kinds(&mir);
 
     // Allocate a `Block` for every basic block
@@ -235,15 +244,21 @@ pub fn trans_mir<'a, 'tcx: 'a>(
         scopes: scopes,
         locals: IndexVec::new(),
         debug_context: debug_context,
+        param_substs: {
+            assert!(!instance.substs.needs_infer());
+            instance.substs
+        },
     };
 
+    let lvalue_locals = analyze::lvalue_locals(&bcx, &mircx);
+
     // Allocate variable and temp allocas
     mircx.locals = {
         let args = arg_local_refs(&bcx, &mircx, &mircx.scopes, &lvalue_locals);
 
         let mut allocate_local = |local| {
             let decl = &mir.local_decls[local];
-            let ty = bcx.fcx().monomorphize(&decl.ty);
+            let ty = mircx.monomorphize(&decl.ty);
 
             if let Some(name) = decl.name {
                 // User variable
@@ -356,7 +371,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
 
     mir.args_iter().enumerate().map(|(arg_index, local)| {
         let arg_decl = &mir.local_decls[local];
-        let arg_ty = bcx.fcx().monomorphize(&arg_decl.ty);
+        let arg_ty = mircx.monomorphize(&arg_decl.ty);
 
         if Some(local) == mir.spread_arg {
             // This argument (e.g. the last argument in the "rust-call" ABI)
diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs
index 20364d6320c..6e69608e51e 100644
--- a/src/librustc_trans/mir/operand.rs
+++ b/src/librustc_trans/mir/operand.rs
@@ -197,7 +197,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
                             let llval = [a, b][f.index()];
                             let op = OperandRef {
                                 val: OperandValue::Immediate(llval),
-                                ty: bcx.fcx().monomorphize(&ty)
+                                ty: self.monomorphize(&ty)
                             };
 
                             // Handle nested pairs.
diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs
index d7a4adb1dd4..5037bd9dae3 100644
--- a/src/librustc_trans/mir/rvalue.rs
+++ b/src/librustc_trans/mir/rvalue.rs
@@ -53,7 +53,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
            }
 
             mir::Rvalue::Cast(mir::CastKind::Unsize, ref source, cast_ty) => {
-                let cast_ty = bcx.fcx().monomorphize(&cast_ty);
+                let cast_ty = self.monomorphize(&cast_ty);
 
                 if common::type_is_fat_ptr(bcx.ccx(), cast_ty) {
                     // into-coerce of a thin pointer to a fat pointer - just
@@ -186,7 +186,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
             mir::Rvalue::Cast(ref kind, ref source, cast_ty) => {
                 let operand = self.trans_operand(&bcx, source);
                 debug!("cast operand is {:?}", operand);
-                let cast_ty = bcx.fcx().monomorphize(&cast_ty);
+                let cast_ty = self.monomorphize(&cast_ty);
 
                 let val = match *kind {
                     mir::CastKind::ReifyFnPointer => {
@@ -443,7 +443,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
             }
 
             mir::Rvalue::Box(content_ty) => {
-                let content_ty: Ty<'tcx> = bcx.fcx().monomorphize(&content_ty);
+                let content_ty: Ty<'tcx> = self.monomorphize(&content_ty);
                 let llty = type_of::type_of(bcx.ccx(), content_ty);
                 let llsize = machine::llsize_of(bcx.ccx(), llty);
                 let align = type_of::align_of(bcx.ccx(), content_ty);