From e10695f161fade16829f9fa96f48465b123c133e Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sun, 18 Dec 2016 16:05:40 -0700 Subject: [PATCH] Move param_substs onto MirContext --- src/librustc_trans/common.rs | 25 ------------------------- src/librustc_trans/mir/analyze.rs | 29 ++++++++++++++++------------- src/librustc_trans/mir/block.rs | 4 ++-- src/librustc_trans/mir/constant.rs | 7 +++---- src/librustc_trans/mir/lvalue.rs | 6 +++--- src/librustc_trans/mir/mod.rs | 25 ++++++++++++++++++++----- src/librustc_trans/mir/operand.rs | 2 +- src/librustc_trans/mir/rvalue.rs | 6 +++--- 8 files changed, 48 insertions(+), 56 deletions(-) diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 528ecf2a4266..9a6127746ff3 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(&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 38e21bdefb2c..71375f1160c3 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 2ccf92a743ea..577c304d0f7a 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::>(); 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 9628ed254066..56f88977c865 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 1582dc9a6aa1..673a786f1f8b 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 6fbbaa7bc766..6f376251d9b7 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, + + /// 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(&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 20364d6320c6..6e69608e51e6 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 d7a4adb1dd4d..5037bd9dae39 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);