diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 96ccc3ba500..d176ae761e1 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -66,6 +66,25 @@ macro_rules! newtype_index { ) } +/// Types for locals +type LocalDecls<'tcx> = IndexVec>; + +pub trait HasLocalDecls<'tcx> { + fn local_decls(&self) -> &LocalDecls<'tcx>; +} + +impl<'tcx> HasLocalDecls<'tcx> for LocalDecls<'tcx> { + fn local_decls(&self) -> &LocalDecls<'tcx> { + self + } +} + +impl<'tcx> HasLocalDecls<'tcx> for Mir<'tcx> { + fn local_decls(&self) -> &LocalDecls<'tcx> { + &self.local_decls + } +} + /// Lowered representation of a single function. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Mir<'tcx> { @@ -90,7 +109,7 @@ pub struct Mir<'tcx> { /// The first local is the return value pointer, followed by `arg_count` /// locals for the function arguments, followed by any user-declared /// variables and temporaries. - pub local_decls: IndexVec>, + pub local_decls: LocalDecls<'tcx>, /// Number of arguments this function takes. /// diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 71acb36ecf7..1af80771fb9 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -121,31 +121,34 @@ impl<'tcx> TypeFoldable<'tcx> for LvalueTy<'tcx> { } impl<'tcx> Lvalue<'tcx> { - pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> LvalueTy<'tcx> { + pub fn ty<'a, 'gcx, D>(&self, local_decls: &D, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> LvalueTy<'tcx> + where D: HasLocalDecls<'tcx> + { match *self { Lvalue::Local(index) => - LvalueTy::Ty { ty: mir.local_decls[index].ty }, + LvalueTy::Ty { ty: local_decls.local_decls()[index].ty }, Lvalue::Static(ref data) => LvalueTy::Ty { ty: data.ty }, Lvalue::Projection(ref proj) => - proj.base.ty(mir, tcx).projection_ty(tcx, &proj.elem), + proj.base.ty(local_decls, tcx).projection_ty(tcx, &proj.elem), } } } impl<'tcx> Rvalue<'tcx> { - pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> + pub fn ty<'a, 'gcx, D>(&self, local_decls: &D, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> + where D: HasLocalDecls<'tcx> { match *self { - Rvalue::Use(ref operand) => operand.ty(mir, tcx), + Rvalue::Use(ref operand) => operand.ty(local_decls, tcx), Rvalue::Repeat(ref operand, ref count) => { - let op_ty = operand.ty(mir, tcx); + let op_ty = operand.ty(local_decls, tcx); let count = count.as_u64(tcx.sess.target.uint_type); assert_eq!(count as usize as u64, count); tcx.mk_array(op_ty, count as usize) } Rvalue::Ref(reg, bk, ref lv) => { - let lv_ty = lv.ty(mir, tcx).to_ty(tcx); + let lv_ty = lv.ty(local_decls, tcx).to_ty(tcx); tcx.mk_ref(reg, ty::TypeAndMut { ty: lv_ty, @@ -156,22 +159,22 @@ impl<'tcx> Rvalue<'tcx> { Rvalue::Len(..) => tcx.types.usize, Rvalue::Cast(.., ty) => ty, Rvalue::BinaryOp(op, ref lhs, ref rhs) => { - let lhs_ty = lhs.ty(mir, tcx); - let rhs_ty = rhs.ty(mir, tcx); + let lhs_ty = lhs.ty(local_decls, tcx); + let rhs_ty = rhs.ty(local_decls, tcx); op.ty(tcx, lhs_ty, rhs_ty) } Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) => { - let lhs_ty = lhs.ty(mir, tcx); - let rhs_ty = rhs.ty(mir, tcx); + let lhs_ty = lhs.ty(local_decls, tcx); + let rhs_ty = rhs.ty(local_decls, tcx); let ty = op.ty(tcx, lhs_ty, rhs_ty); tcx.intern_tup(&[ty, tcx.types.bool], false) } Rvalue::UnaryOp(UnOp::Not, ref operand) | Rvalue::UnaryOp(UnOp::Neg, ref operand) => { - operand.ty(mir, tcx) + operand.ty(local_decls, tcx) } Rvalue::Discriminant(ref lval) => { - let ty = lval.ty(mir, tcx).to_ty(tcx); + let ty = lval.ty(local_decls, tcx).to_ty(tcx); if let ty::TyAdt(adt_def, _) = ty.sty { adt_def.repr.discr_type().to_ty(tcx) } else { @@ -189,7 +192,7 @@ impl<'tcx> Rvalue<'tcx> { } AggregateKind::Tuple => { tcx.mk_tup( - ops.iter().map(|op| op.ty(mir, tcx)), + ops.iter().map(|op| op.ty(local_decls, tcx)), false ) } @@ -206,9 +209,11 @@ impl<'tcx> Rvalue<'tcx> { } impl<'tcx> Operand<'tcx> { - pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> { + pub fn ty<'a, 'gcx, D>(&self, local_decls: &D, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> + where D: HasLocalDecls<'tcx> + { match self { - &Operand::Consume(ref l) => l.ty(mir, tcx).to_ty(tcx), + &Operand::Consume(ref l) => l.ty(local_decls, tcx).to_ty(tcx), &Operand::Constant(ref c) => c.ty, } } diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 5f80c7bee14..d3fee8045e6 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -250,7 +250,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { work_list.push(target); // If the location doesn't actually need dropping, treat it like // a regular goto. - let ty = location.ty(&callee_mir, tcx).subst(tcx, callsite.substs); + let ty = location.ty(callee_mir, tcx).subst(tcx, callsite.substs); let ty = ty.to_ty(tcx); if ty.needs_drop(tcx, param_env) { cost += CALL_PENALTY; diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 48b166c61de..9bb29c340d9 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -263,7 +263,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 = location.ty(self.mir, bcx.tcx()).to_ty(bcx.tcx()); let ty = self.monomorphize(&ty); let drop_fn = monomorphize::resolve_drop_in_place(bcx.ccx.shared(), ty); @@ -438,7 +438,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()); + let op_ty = op_arg.ty(self.mir, bcx.tcx()); self.monomorphize(&op_ty) }).collect::>(); diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs index 88e46b5c99a..af8976967a1 100644 --- a/src/librustc_trans/mir/lvalue.rs +++ b/src/librustc_trans/mir/lvalue.rs @@ -408,7 +408,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { pub fn monomorphized_lvalue_ty(&self, lvalue: &mir::Lvalue<'tcx>) -> Ty<'tcx> { let tcx = self.ccx.tcx(); - let lvalue_ty = lvalue.ty(&self.mir, tcx); + let lvalue_ty = lvalue.ty(self.mir, tcx); self.monomorphize(&lvalue_ty.to_ty(tcx)) } }