Skip to content

Commit

Permalink
Auto merge of rust-lang#43174 - RalfJung:refactor-ty, r=nikomatsakis
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jul 14, 2017
2 parents 6d9d82d + 0bbc315 commit 23ecebd
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 21 deletions.
21 changes: 20 additions & 1 deletion src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand All @@ -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.
///
Expand Down
37 changes: 21 additions & 16 deletions src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 {
Expand All @@ -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
)
}
Expand All @@ -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,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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<_>>();

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/mir/lvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
}

0 comments on commit 23ecebd

Please sign in to comment.