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
This commit is contained in:
commit
23ecebd6bd
@ -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.
|
||||
///
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<_>>();
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user