diff options
| author | bors <bors@rust-lang.org> | 2017-07-14 23:29:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-07-14 23:29:51 +0000 |
| commit | 23ecebd6bd4362142ac586014aec44070a177a3d (patch) | |
| tree | e5ce2c9b5b3f58ba19b194879973b63cb314df6f /src | |
| parent | 6d9d82d3dff580d2ec31e4db5cdef73c9625a864 (diff) | |
| parent | 0bbc3158300452dbb45931ab8d6740faa840d486 (diff) | |
| download | rust-23ecebd6bd4362142ac586014aec44070a177a3d.tar.gz rust-23ecebd6bd4362142ac586014aec44070a177a3d.zip | |
Auto merge of #43174 - RalfJung:refactor-ty, r=nikomatsakis
Refactor: {Lvalue,Rvalue,Operand}::ty only need the locals' types, not the full &Mir
I am writing code that needs to call these `ty` methods while mutating MIR -- which is impossible with the current API.
Even with the refactoring the situation is not great: I am cloning the `local_decls` and then passing the clone to the `ty` methods. I have to clone because `Mir::basic_blocks_mut` borrows the entire `Mir` including the `local_decls`. But even that is better than not being able to get these types at all...
Cc @nikomatsakis
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/mir/mod.rs | 21 | ||||
| -rw-r--r-- | src/librustc/mir/tcx.rs | 37 | ||||
| -rw-r--r-- | src/librustc_mir/transform/inline.rs | 2 | ||||
| -rw-r--r-- | src/librustc_trans/mir/block.rs | 4 | ||||
| -rw-r--r-- | src/librustc_trans/mir/lvalue.rs | 2 |
5 files changed, 45 insertions, 21 deletions
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<Local, LocalDecl<'tcx>>; + +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<Local, LocalDecl<'tcx>>, + 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::<Vec<_>>(); 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)) } } |
