about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-07-14 23:29:51 +0000
committerbors <bors@rust-lang.org>2017-07-14 23:29:51 +0000
commit23ecebd6bd4362142ac586014aec44070a177a3d (patch)
treee5ce2c9b5b3f58ba19b194879973b63cb314df6f /src
parent6d9d82d3dff580d2ec31e4db5cdef73c9625a864 (diff)
parent0bbc3158300452dbb45931ab8d6740faa840d486 (diff)
downloadrust-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.rs21
-rw-r--r--src/librustc/mir/tcx.rs37
-rw-r--r--src/librustc_mir/transform/inline.rs2
-rw-r--r--src/librustc_trans/mir/block.rs4
-rw-r--r--src/librustc_trans/mir/lvalue.rs2
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))
     }
 }