From 28abc0a6aad5e282dd69193b3fec64fd2fef1348 Mon Sep 17 00:00:00 2001
From: Scott A Carr <s.carr1024@gmail.com>
Date: Fri, 5 Aug 2016 15:59:51 -0700
Subject: [PATCH 1/4] refactor lvalue_ty to be method of lvalue

---
 src/librustc/mir/repr.rs                      | 23 ++++++++++++++++++
 src/librustc/mir/tcx.rs                       | 24 ++-----------------
 .../borrowck/mir/elaborate_drops.rs           |  8 +++----
 src/librustc_borrowck/borrowck/mir/mod.rs     |  4 ++--
 src/librustc_mir/transform/promote_consts.rs  |  2 +-
 src/librustc_mir/transform/qualify_consts.rs  | 10 ++++----
 src/librustc_mir/transform/type_check.rs      | 10 ++++----
 src/librustc_trans/collector.rs               |  4 ++--
 src/librustc_trans/mir/analyze.rs             |  5 ++--
 src/librustc_trans/mir/block.rs               |  4 ++--
 src/librustc_trans/mir/constant.rs            |  4 ++--
 src/librustc_trans/mir/lvalue.rs              | 12 +++++-----
 src/librustc_trans/mir/statement.rs           |  2 +-
 13 files changed, 57 insertions(+), 55 deletions(-)

diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs
index 93507246241..36ae4237b19 100644
--- a/src/librustc/mir/repr.rs
+++ b/src/librustc/mir/repr.rs
@@ -32,6 +32,8 @@ use syntax::ast::{self, Name};
 use syntax_pos::Span;
 
 use super::cache::Cache;
+use super::super::ty::TyCtxt;
+use super::tcx::LvalueTy;
 
 macro_rules! newtype_index {
     ($name:ident, $debug_name:expr) => (
@@ -809,8 +811,29 @@ impl<'tcx> Lvalue<'tcx> {
             elem: elem,
         }))
     }
+
+    pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> LvalueTy<'tcx>
+    {
+        match self {
+            &Lvalue::Var(index) =>
+                LvalueTy::Ty { ty: mir.var_decls[index].ty },
+            &Lvalue::Temp(index) =>
+                LvalueTy::Ty { ty: mir.temp_decls[index].ty },
+            &Lvalue::Arg(index) =>
+                LvalueTy::Ty { ty: mir.arg_decls[index].ty },
+            &Lvalue::Static(def_id) =>
+                LvalueTy::Ty { ty: tcx.lookup_item_type(def_id).ty },
+            &Lvalue::ReturnPointer =>
+                LvalueTy::Ty { ty: mir.return_ty.unwrap() },
+            &Lvalue::Projection(ref proj) =>
+                proj.base.ty(mir, tcx).projection_ty(tcx, &proj.elem),
+        }
+    }
 }
 
+
+
+
 impl<'tcx> Debug for Lvalue<'tcx> {
     fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
         use self::Lvalue::*;
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index e3905c39daa..6c19db9a0f7 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -119,7 +119,7 @@ impl<'a, 'gcx, 'tcx> Mir<'tcx> {
                       -> Ty<'tcx>
     {
         match *operand {
-            Operand::Consume(ref l) => self.lvalue_ty(tcx, l).to_ty(tcx),
+            Operand::Consume(ref l) => l.ty(self, tcx).to_ty(tcx),
             Operand::Constant(ref c) => c.ty,
         }
     }
@@ -148,26 +148,6 @@ impl<'a, 'gcx, 'tcx> Mir<'tcx> {
         }
     }
 
-    pub fn lvalue_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                     lvalue: &Lvalue<'tcx>)
-                     -> LvalueTy<'tcx>
-    {
-        match *lvalue {
-            Lvalue::Var(index) =>
-                LvalueTy::Ty { ty: self.var_decls[index].ty },
-            Lvalue::Temp(index) =>
-                LvalueTy::Ty { ty: self.temp_decls[index].ty },
-            Lvalue::Arg(index) =>
-                LvalueTy::Ty { ty: self.arg_decls[index].ty },
-            Lvalue::Static(def_id) =>
-                LvalueTy::Ty { ty: tcx.lookup_item_type(def_id).ty },
-            Lvalue::ReturnPointer =>
-                LvalueTy::Ty { ty: self.return_ty.unwrap() },
-            Lvalue::Projection(ref proj) =>
-                self.lvalue_ty(tcx, &proj.base).projection_ty(tcx, &proj.elem)
-        }
-    }
-
     pub fn rvalue_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                      rvalue: &Rvalue<'tcx>)
                      -> Option<Ty<'tcx>>
@@ -181,7 +161,7 @@ impl<'a, 'gcx, 'tcx> Mir<'tcx> {
                 Some(tcx.mk_array(op_ty, count as usize))
             }
             Rvalue::Ref(reg, bk, ref lv) => {
-                let lv_ty = self.lvalue_ty(tcx, lv).to_ty(tcx);
+                let lv_ty = lv.ty(self, tcx).to_ty(tcx);
                 Some(tcx.mk_ref(
                     tcx.mk_region(reg),
                     ty::TypeAndMut {
diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
index 623ea60c5a6..f6e9484eda1 100644
--- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
+++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
@@ -185,7 +185,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
     {
         match self.move_data().move_paths[path].content {
             MovePathContent::Lvalue(ref lvalue) => {
-                let ty = self.mir.lvalue_ty(self.tcx, lvalue).to_ty(self.tcx);
+                let ty = lvalue.ty(self.mir, self.tcx).to_ty(self.tcx);
                 debug!("path_needs_drop({:?}, {:?} : {:?})", path, lvalue, ty);
 
                 self.tcx.type_needs_drop_given_env(ty, self.param_env())
@@ -555,7 +555,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
 
         let mut fields = fields;
         fields.retain(|&(ref lvalue, _)| {
-            let ty = self.mir.lvalue_ty(self.tcx, lvalue).to_ty(self.tcx);
+            let ty = lvalue.ty(self.mir, self.tcx).to_ty(self.tcx);
             self.tcx.type_needs_drop_given_env(ty, self.param_env())
         });
 
@@ -706,7 +706,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
     /// This creates a "drop ladder" that drops the needed fields of the
     /// ADT, both in the success case or if one of the destructors fail.
     fn open_drop<'a>(&mut self, c: &DropCtxt<'a, 'tcx>) -> BasicBlock {
-        let ty = self.mir.lvalue_ty(self.tcx, c.lvalue).to_ty(self.tcx);
+        let ty = c.lvalue.ty(self.mir, self.tcx).to_ty(self.tcx);
         match ty.sty {
             ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => {
                 self.open_drop_for_adt(c, def, substs)
@@ -892,7 +892,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
         // dataflow can create unneeded children in some cases
         // - be sure to ignore them.
 
-        let ty = self.mir.lvalue_ty(self.tcx, c.lvalue).to_ty(self.tcx);
+        let ty = c.lvalue.ty(self.mir, self.tcx).to_ty(self.tcx);
 
         match ty.sty {
             ty::TyStruct(def, _) | ty::TyEnum(def, _) => {
diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs
index 7481b15685e..7c912e8bac6 100644
--- a/src/librustc_borrowck/borrowck/mir/mod.rs
+++ b/src/librustc_borrowck/borrowck/mir/mod.rs
@@ -256,7 +256,7 @@ fn move_path_children_matching<'tcx, F>(move_paths: &MovePathData<'tcx>,
 fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                       mir: &Mir<'tcx>,
                                                       lv: &repr::Lvalue<'tcx>) -> bool {
-    let ty = mir.lvalue_ty(tcx, lv).to_ty(tcx);
+    let ty = lv.ty(mir, tcx).to_ty(tcx);
     match ty.sty {
         ty::TyArray(..) | ty::TySlice(..) | ty::TyRef(..) | ty::TyRawPtr(..) => {
             debug!("lvalue_contents_drop_state_cannot_differ lv: {:?} ty: {:?} refd => false",
@@ -355,7 +355,7 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
 
         // don't move out of non-Copy things
         if let MovePathContent::Lvalue(ref lvalue) = move_data.move_paths[path].content {
-            let ty = mir.lvalue_ty(tcx, lvalue).to_ty(tcx);
+            let ty = lvalue.ty(mir, tcx).to_ty(tcx);
             if !ty.moves_by_default(tcx, param_env, DUMMY_SP) {
                 continue;
             }
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 4b551d6bb08..f1e3f55ec8b 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -347,7 +347,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
                         continue;
                     }
                 }
-                (statement.source_info.span, mir.lvalue_ty(tcx, dest).to_ty(tcx))
+                (statement.source_info.span, dest.ty(mir, tcx).to_ty(tcx))
             }
             Candidate::ShuffleIndices(bb) => {
                 let terminator = mir[bb].terminator();
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 1d00938fb25..5148cd6735f 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -485,8 +485,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                                 this.add(Qualif::STATIC);
                             }
 
-                            let base_ty = this.mir.lvalue_ty(this.tcx, &proj.base)
-                                              .to_ty(this.tcx);
+                            let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx);
                             if let ty::TyRawPtr(_) = base_ty.sty {
                                 this.add(Qualif::NOT_CONST);
                                 if this.mode != Mode::Fn {
@@ -505,8 +504,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                                           "cannot refer to the interior of another \
                                            static, use a constant instead");
                             }
-                            let ty = this.mir.lvalue_ty(this.tcx, lvalue)
-                                         .to_ty(this.tcx);
+                            let ty = lvalue.ty(this.mir, this.tcx).to_ty(this.tcx);
                             this.qualif.restrict(ty, this.tcx, &this.param_env);
                         }
 
@@ -591,7 +589,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                     self.add(Qualif::STATIC_REF);
                 }
 
-                let ty = self.mir.lvalue_ty(self.tcx, lvalue).to_ty(self.tcx);
+                let ty = lvalue.ty(self.mir, self.tcx).to_ty(self.tcx);
                 if kind == BorrowKind::Mut {
                     // In theory, any zero-sized value could be borrowed
                     // mutably without consequences. However, only &mut []
@@ -801,7 +799,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                 } else {
                     // Be conservative about the returned value of a const fn.
                     let tcx = self.tcx;
-                    let ty = self.mir.lvalue_ty(tcx, dest).to_ty(tcx);
+                    let ty = dest.ty(self.mir, tcx).to_ty(tcx);
                     self.qualif = Qualif::empty();
                     self.add_type(ty);
 
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index db49e1e0407..7606c21ed7b 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -355,7 +355,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         let tcx = self.tcx();
         match stmt.kind {
             StatementKind::Assign(ref lv, ref rv) => {
-                let lv_ty = mir.lvalue_ty(tcx, lv).to_ty(tcx);
+                let lv_ty = lv.ty(mir, tcx).to_ty(tcx);
                 let rv_ty = mir.rvalue_ty(tcx, rv);
                 if let Some(rv_ty) = rv_ty {
                     if let Err(terr) = self.sub_types(self.last_span, rv_ty, lv_ty) {
@@ -390,7 +390,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 ref value,
                 ..
             } => {
-                let lv_ty = mir.lvalue_ty(tcx, location).to_ty(tcx);
+                let lv_ty = location.ty(mir, tcx).to_ty(tcx);
                 let rv_ty = mir.operand_ty(tcx, value);
                 if let Err(terr) = self.sub_types(self.last_span, rv_ty, lv_ty) {
                     span_mirbug!(self, term, "bad DropAndReplace ({:?} = {:?}): {:?}",
@@ -408,7 +408,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 }
             }
             TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => {
-                let discr_ty = mir.lvalue_ty(tcx, discr).to_ty(tcx);
+                let discr_ty = discr.ty(mir, tcx).to_ty(tcx);
                 if let Err(terr) = self.sub_types(self.last_span, discr_ty, switch_ty) {
                     span_mirbug!(self, term, "bad SwitchInt ({:?} on {:?}): {:?}",
                                  switch_ty, discr_ty, terr);
@@ -421,7 +421,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 // FIXME: check the values
             }
             TerminatorKind::Switch { ref discr, adt_def, ref targets } => {
-                let discr_ty = mir.lvalue_ty(tcx, discr).to_ty(tcx);
+                let discr_ty = discr.ty(mir, tcx).to_ty(tcx);
                 match discr_ty.sty {
                     ty::TyEnum(def, _)
                         if def == adt_def && adt_def.variants.len() == targets.len()
@@ -481,7 +481,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 span_mirbug!(self, term, "call to diverging function {:?} with dest", sig);
             }
             (&Some((ref dest, _)), ty::FnConverging(ty)) => {
-                let dest_ty = mir.lvalue_ty(tcx, dest).to_ty(tcx);
+                let dest_ty = dest.ty(mir, tcx).to_ty(tcx);
                 if let Err(terr) = self.sub_types(self.last_span, ty, dest_ty) {
                     span_mirbug!(self, term,
                                  "call dest mismatch ({:?} <- {:?}): {:?}",
diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs
index ba2cd2ba699..6246e4a9d35 100644
--- a/src/librustc_trans/collector.rs
+++ b/src/librustc_trans/collector.rs
@@ -525,8 +525,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
         debug!("visiting lvalue {:?}", *lvalue);
 
         if let mir_visit::LvalueContext::Drop = context {
-            let ty = self.mir.lvalue_ty(self.scx.tcx(), lvalue)
-                             .to_ty(self.scx.tcx());
+            let ty = lvalue.ty(self.mir, self.scx.tcx())
+                           .to_ty(self.scx.tcx());
 
             let ty = monomorphize::apply_param_substs(self.scx.tcx(),
                                                       self.param_substs,
diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs
index dac7afab6e3..d6dbefec034 100644
--- a/src/librustc_trans/mir/analyze.rs
+++ b/src/librustc_trans/mir/analyze.rs
@@ -143,7 +143,8 @@ impl<'mir, 'bcx, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'bcx, 'tcx> {
         // Allow uses of projections of immediate pair fields.
         if let mir::Lvalue::Projection(ref proj) = *lvalue {
             if self.mir.local_index(&proj.base).is_some() {
-                let ty = self.mir.lvalue_ty(self.bcx.tcx(), &proj.base);
+                let ty = proj.base.ty(self.mir, self.bcx.tcx());
+
                 let ty = self.bcx.monomorphize(&ty.to_ty(self.bcx.tcx()));
                 if common::type_is_imm_pair(self.bcx.ccx(), ty) {
                     if let mir::ProjectionElem::Field(..) = proj.elem {
@@ -170,7 +171,7 @@ impl<'mir, 'bcx, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'bcx, 'tcx> {
                     self.mark_as_lvalue(index);
                 }
                 LvalueContext::Drop => {
-                    let ty = self.mir.lvalue_ty(self.bcx.tcx(), lvalue);
+                    let ty = lvalue.ty(self.mir, self.bcx.tcx());
                     let ty = self.bcx.monomorphize(&ty.to_ty(self.bcx.tcx()));
 
                     // Only need the lvalue if we're actually dropping it.
diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs
index 9bfdb511c62..3290bbf59c5 100644
--- a/src/librustc_trans/mir/block.rs
+++ b/src/librustc_trans/mir/block.rs
@@ -230,7 +230,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
             }
 
             mir::TerminatorKind::Drop { ref location, target, unwind } => {
-                let ty = mir.lvalue_ty(bcx.tcx(), location).to_ty(bcx.tcx());
+                let ty = location.ty(&mir, bcx.tcx()).to_ty(bcx.tcx());
                 let ty = bcx.monomorphize(&ty);
 
                 // Double check for necessity to drop
@@ -828,7 +828,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
             return ReturnDest::Nothing;
         }
         let dest = if let Some(index) = self.mir.local_index(dest) {
-            let ret_ty = self.lvalue_ty(dest);
+            let ret_ty = self.monomorphized_lvalue_ty(dest);
             match self.locals[index] {
                 LocalRef::Lvalue(dest) => dest,
                 LocalRef::Operand(None) => {
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index 00db19d2739..fa40dfd64d6 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -278,7 +278,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
                 let span = statement.source_info.span;
                 match statement.kind {
                     mir::StatementKind::Assign(ref dest, ref rvalue) => {
-                        let ty = self.mir.lvalue_ty(tcx, dest);
+                        let ty = dest.ty(self.mir, tcx);
                         let ty = self.monomorphize(&ty).to_ty(tcx);
                         match self.const_rvalue(rvalue, ty, span) {
                             Ok(value) => self.store(dest, value, span),
@@ -386,7 +386,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
                 ConstLvalue {
                     base: Base::Static(consts::get_static(self.ccx, def_id).val),
                     llextra: ptr::null_mut(),
-                    ty: self.mir.lvalue_ty(tcx, lvalue).to_ty(tcx)
+                    ty: lvalue.ty(self.mir, tcx).to_ty(tcx)
                 }
             }
             mir::Lvalue::Projection(ref projection) => {
diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs
index ceaba2a40ca..94db2e3c23c 100644
--- a/src/librustc_trans/mir/lvalue.rs
+++ b/src/librustc_trans/mir/lvalue.rs
@@ -108,7 +108,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
             mir::Lvalue::Arg(_) |
             mir::Lvalue::ReturnPointer => bug!(), // handled above
             mir::Lvalue::Static(def_id) => {
-                let const_ty = self.lvalue_ty(lvalue);
+                let const_ty = self.monomorphized_lvalue_ty(lvalue);
                 LvalueRef::new_sized(consts::get_static(ccx, def_id).val,
                                      LvalueTy::from_ty(const_ty))
             },
@@ -200,7 +200,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                             ty::TyArray(..) => {
                                 // must cast the lvalue pointer type to the new
                                 // array type (*[%_; new_len]).
-                                let base_ty = self.lvalue_ty(lvalue);
+                                let base_ty = self.monomorphized_lvalue_ty(lvalue);
                                 let llbasety = type_of::type_of(bcx.ccx(), base_ty).ptr_to();
                                 let llbase = bcx.pointercast(llbase, llbasety);
                                 (llbase, ptr::null_mut())
@@ -240,7 +240,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
             match self.locals[index] {
                 LocalRef::Lvalue(lvalue) => f(self, lvalue),
                 LocalRef::Operand(None) => {
-                    let lvalue_ty = self.lvalue_ty(lvalue);
+                    let lvalue_ty = self.monomorphized_lvalue_ty(lvalue);
                     let lvalue = LvalueRef::alloca(bcx,
                                                    lvalue_ty,
                                                    "lvalue_temp");
@@ -252,7 +252,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                 LocalRef::Operand(Some(_)) => {
                     // See comments in LocalRef::new_operand as to why
                     // we always have Some in a ZST LocalRef::Operand.
-                    let ty = self.lvalue_ty(lvalue);
+                    let ty = self.monomorphized_lvalue_ty(lvalue);
                     if common::type_is_zero_size(bcx.ccx(), ty) {
                         // Pass an undef pointer as no stores can actually occur.
                         let llptr = C_undef(type_of(bcx.ccx(), ty).ptr_to());
@@ -289,9 +289,9 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
         }
     }
 
-    pub fn lvalue_ty(&self, lvalue: &mir::Lvalue<'tcx>) -> Ty<'tcx> {
+    pub fn monomorphized_lvalue_ty(&self, lvalue: &mir::Lvalue<'tcx>) -> Ty<'tcx> {
         let tcx = self.fcx.ccx.tcx();
-        let lvalue_ty = self.mir.lvalue_ty(tcx, lvalue);
+        let lvalue_ty = lvalue.ty(&self.mir, tcx);
         self.fcx.monomorphize(&lvalue_ty.to_ty(tcx))
     }
 }
diff --git a/src/librustc_trans/mir/statement.rs b/src/librustc_trans/mir/statement.rs
index 55efa75b173..44d264c7e98 100644
--- a/src/librustc_trans/mir/statement.rs
+++ b/src/librustc_trans/mir/statement.rs
@@ -39,7 +39,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                             bcx
                         }
                         LocalRef::Operand(Some(_)) => {
-                            let ty = self.lvalue_ty(lvalue);
+                            let ty = self.monomorphized_lvalue_ty(lvalue);
 
                             if !common::type_is_zero_size(bcx.ccx(), ty) {
                                 span_bug!(statement.source_info.span,

From 9f8093856dceb3e6bd740ab1238e132eddb203ca Mon Sep 17 00:00:00 2001
From: Scott A Carr <s.carr1024@gmail.com>
Date: Mon, 8 Aug 2016 13:35:10 -0700
Subject: [PATCH 2/4] refactor other type methods

---
 src/librustc/mir/repr.rs                     |  23 ----
 src/librustc/mir/tcx.rs                      | 133 +++++++++++--------
 src/librustc_mir/transform/promote_consts.rs |   2 +-
 src/librustc_mir/transform/qualify_consts.rs |   8 +-
 src/librustc_mir/transform/type_check.rs     |  22 +--
 src/librustc_trans/collector.rs              |   4 +-
 src/librustc_trans/mir/block.rs              |   2 +-
 src/librustc_trans/mir/constant.rs           |   6 +-
 src/librustc_trans/mir/rvalue.rs             |   4 +-
 9 files changed, 99 insertions(+), 105 deletions(-)

diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs
index 36ae4237b19..93507246241 100644
--- a/src/librustc/mir/repr.rs
+++ b/src/librustc/mir/repr.rs
@@ -32,8 +32,6 @@ use syntax::ast::{self, Name};
 use syntax_pos::Span;
 
 use super::cache::Cache;
-use super::super::ty::TyCtxt;
-use super::tcx::LvalueTy;
 
 macro_rules! newtype_index {
     ($name:ident, $debug_name:expr) => (
@@ -811,29 +809,8 @@ impl<'tcx> Lvalue<'tcx> {
             elem: elem,
         }))
     }
-
-    pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> LvalueTy<'tcx>
-    {
-        match self {
-            &Lvalue::Var(index) =>
-                LvalueTy::Ty { ty: mir.var_decls[index].ty },
-            &Lvalue::Temp(index) =>
-                LvalueTy::Ty { ty: mir.temp_decls[index].ty },
-            &Lvalue::Arg(index) =>
-                LvalueTy::Ty { ty: mir.arg_decls[index].ty },
-            &Lvalue::Static(def_id) =>
-                LvalueTy::Ty { ty: tcx.lookup_item_type(def_id).ty },
-            &Lvalue::ReturnPointer =>
-                LvalueTy::Ty { ty: mir.return_ty.unwrap() },
-            &Lvalue::Projection(ref proj) =>
-                proj.base.ty(mir, tcx).projection_ty(tcx, &proj.elem),
-        }
-    }
 }
 
-
-
-
 impl<'tcx> Debug for Lvalue<'tcx> {
     fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
         use self::Lvalue::*;
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index 6c19db9a0f7..2c60d82997f 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -113,55 +113,38 @@ impl<'tcx> TypeFoldable<'tcx> for LvalueTy<'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> Mir<'tcx> {
-    pub fn operand_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                      operand: &Operand<'tcx>)
-                      -> Ty<'tcx>
-    {
-        match *operand {
-            Operand::Consume(ref l) => l.ty(self, tcx).to_ty(tcx),
-            Operand::Constant(ref c) => c.ty,
+impl<'tcx> Lvalue<'tcx> {
+    pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> LvalueTy<'tcx> {
+        match self {
+            &Lvalue::Var(index) =>
+                LvalueTy::Ty { ty: mir.var_decls[index].ty },
+            &Lvalue::Temp(index) =>
+                LvalueTy::Ty { ty: mir.temp_decls[index].ty },
+            &Lvalue::Arg(index) =>
+                LvalueTy::Ty { ty: mir.arg_decls[index].ty },
+            &Lvalue::Static(def_id) =>
+                LvalueTy::Ty { ty: tcx.lookup_item_type(def_id).ty },
+            &Lvalue::ReturnPointer =>
+                LvalueTy::Ty { ty: mir.return_ty.unwrap() },
+            &Lvalue::Projection(ref proj) =>
+                proj.base.ty(mir, tcx).projection_ty(tcx, &proj.elem),
         }
     }
+}
 
-    pub fn binop_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                    op: BinOp,
-                    lhs_ty: Ty<'tcx>,
-                    rhs_ty: Ty<'tcx>)
-                    -> Ty<'tcx>
+impl<'tcx> Rvalue<'tcx> {
+    pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> 
     {
-        // FIXME: handle SIMD correctly
-        match op {
-            BinOp::Add | BinOp::Sub | BinOp::Mul | BinOp::Div | BinOp::Rem |
-            BinOp::BitXor | BinOp::BitAnd | BinOp::BitOr => {
-                // these should be integers or floats of the same size.
-                assert_eq!(lhs_ty, rhs_ty);
-                lhs_ty
-            }
-            BinOp::Shl | BinOp::Shr => {
-                lhs_ty // lhs_ty can be != rhs_ty
-            }
-            BinOp::Eq | BinOp::Lt | BinOp::Le |
-            BinOp::Ne | BinOp::Ge | BinOp::Gt => {
-                tcx.types.bool
-            }
-        }
-    }
-
-    pub fn rvalue_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                     rvalue: &Rvalue<'tcx>)
-                     -> Option<Ty<'tcx>>
-    {
-        match *rvalue {
-            Rvalue::Use(ref operand) => Some(self.operand_ty(tcx, operand)),
-            Rvalue::Repeat(ref operand, ref count) => {
-                let op_ty = self.operand_ty(tcx, operand);
+        match self {
+            &Rvalue::Use(ref operand) => Some(operand.ty(mir, tcx)),
+            &Rvalue::Repeat(ref operand, ref count) => {
+                let op_ty = operand.ty(mir, tcx);
                 let count = count.value.as_u64(tcx.sess.target.uint_type);
                 assert_eq!(count as usize as u64, count);
                 Some(tcx.mk_array(op_ty, count as usize))
             }
-            Rvalue::Ref(reg, bk, ref lv) => {
-                let lv_ty = lv.ty(self, tcx).to_ty(tcx);
+            &Rvalue::Ref(reg, bk, ref lv) => {
+                let lv_ty = lv.ty(mir, tcx).to_ty(tcx);
                 Some(tcx.mk_ref(
                     tcx.mk_region(reg),
                     ty::TypeAndMut {
@@ -170,31 +153,31 @@ impl<'a, 'gcx, 'tcx> Mir<'tcx> {
                     }
                 ))
             }
-            Rvalue::Len(..) => Some(tcx.types.usize),
-            Rvalue::Cast(_, _, ty) => Some(ty),
-            Rvalue::BinaryOp(op, ref lhs, ref rhs) => {
-                let lhs_ty = self.operand_ty(tcx, lhs);
-                let rhs_ty = self.operand_ty(tcx, rhs);
-                Some(self.binop_ty(tcx, op, lhs_ty, rhs_ty))
+            &Rvalue::Len(..) => Some(tcx.types.usize),
+            &Rvalue::Cast(_, _, ty) => Some(ty),
+            &Rvalue::BinaryOp(op, ref lhs, ref rhs) => {
+                let lhs_ty = lhs.ty(mir, tcx);
+                let rhs_ty = rhs.ty(mir, tcx);
+                Some(op.ty(tcx, lhs_ty, rhs_ty))
             }
-            Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) => {
-                let lhs_ty = self.operand_ty(tcx, lhs);
-                let rhs_ty = self.operand_ty(tcx, rhs);
-                let ty = self.binop_ty(tcx, op, 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 ty = op.ty(tcx, lhs_ty, rhs_ty);
                 let ty = tcx.mk_tup(vec![ty, tcx.types.bool]);
                 Some(ty)
             }
-            Rvalue::UnaryOp(_, ref operand) => {
-                Some(self.operand_ty(tcx, operand))
+            &Rvalue::UnaryOp(_, ref operand) => {
+                Some(operand.ty(mir, tcx))
             }
-            Rvalue::Box(t) => {
+            &Rvalue::Box(t) => {
                 Some(tcx.mk_box(t))
             }
-            Rvalue::Aggregate(ref ak, ref ops) => {
+            &Rvalue::Aggregate(ref ak, ref ops) => {
                 match *ak {
                     AggregateKind::Vec => {
                         if let Some(operand) = ops.get(0) {
-                            let ty = self.operand_ty(tcx, operand);
+                            let ty = operand.ty(mir, tcx);
                             Some(tcx.mk_array(ty, ops.len()))
                         } else {
                             None
@@ -202,7 +185,7 @@ impl<'a, 'gcx, 'tcx> Mir<'tcx> {
                     }
                     AggregateKind::Tuple => {
                         Some(tcx.mk_tup(
-                            ops.iter().map(|op| self.operand_ty(tcx, op)).collect()
+                            ops.iter().map(|op| op.ty(mir, tcx)).collect()
                         ))
                     }
                     AggregateKind::Adt(def, _, substs) => {
@@ -213,11 +196,45 @@ impl<'a, 'gcx, 'tcx> Mir<'tcx> {
                     }
                 }
             }
-            Rvalue::InlineAsm { .. } => None
+            &Rvalue::InlineAsm { .. } => None
         }
     }
 }
 
+impl<'tcx> Operand<'tcx> {
+    pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
+        match self {
+            &Operand::Consume(ref l) => l.ty(mir, tcx).to_ty(tcx),
+            &Operand::Constant(ref c) => c.ty,
+        }
+    }    
+}
+
+impl<'tcx> BinOp {
+      pub fn ty<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
+                    lhs_ty: Ty<'tcx>,
+                    rhs_ty: Ty<'tcx>)
+                    -> Ty<'tcx>
+    {
+        // FIXME: handle SIMD correctly
+        match self {
+            &BinOp::Add | &BinOp::Sub | &BinOp::Mul | &BinOp::Div | &BinOp::Rem |
+            &BinOp::BitXor | &BinOp::BitAnd | &BinOp::BitOr => {
+                // these should be integers or floats of the same size.
+                assert_eq!(lhs_ty, rhs_ty);
+                lhs_ty
+            }
+            &BinOp::Shl | &BinOp::Shr => {
+                lhs_ty // lhs_ty can be != rhs_ty
+            }
+            &BinOp::Eq | &BinOp::Lt | &BinOp::Le |
+            &BinOp::Ne | &BinOp::Ge | &BinOp::Gt => {
+                tcx.types.bool
+            }
+        }
+    }  
+}
+
 impl BorrowKind {
     pub fn to_mutbl_lossy(self) -> hir::Mutability {
         match self {
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index f1e3f55ec8b..fa3490cbcf3 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -353,7 +353,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
                 let terminator = mir[bb].terminator();
                 let ty = match terminator.kind {
                     TerminatorKind::Call { ref args, .. } => {
-                        mir.operand_ty(tcx, &args[2])
+                        args[2].ty(mir, tcx)
                     }
                     _ => {
                         span_bug!(terminator.source_info.span,
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 5148cd6735f..8afe7ef78ee 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -649,7 +649,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
             }
 
             Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) => {
-                let operand_ty = self.mir.operand_ty(self.tcx, operand);
+                let operand_ty = operand.ty(self.mir, self.tcx);
                 let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
                 let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
                 match (cast_in, cast_out) {
@@ -667,7 +667,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
             }
 
             Rvalue::BinaryOp(op, ref lhs, _) => {
-                if let ty::TyRawPtr(_) = self.mir.operand_ty(self.tcx, lhs).sty {
+                if let ty::TyRawPtr(_) = lhs.ty(self.mir, self.tcx).sty {
                     assert!(op == BinOp::Eq || op == BinOp::Ne ||
                             op == BinOp::Le || op == BinOp::Lt ||
                             op == BinOp::Ge || op == BinOp::Gt);
@@ -697,7 +697,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                     }
 
                     if Some(def.did) == self.tcx.lang_items.unsafe_cell_type() {
-                        let ty = self.mir.rvalue_ty(self.tcx, rvalue).unwrap();
+                        let ty = rvalue.ty(self.mir, self.tcx).unwrap();
                         self.add_type(ty);
                         assert!(self.qualif.intersects(Qualif::MUTABLE_INTERIOR));
                         // Even if the value inside may not need dropping,
@@ -719,7 +719,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
         if let TerminatorKind::Call { ref func, ref args, ref destination, .. } = *kind {
             self.visit_operand(func);
 
-            let fn_ty = self.mir.operand_ty(self.tcx, func);
+            let fn_ty = func.ty(self.mir, self.tcx);
             let (is_shuffle, is_const_fn) = match fn_ty.sty {
                 ty::TyFnDef(def_id, _, f) => {
                     (f.abi == Abi::PlatformIntrinsic &&
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index 7606c21ed7b..246096b5836 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -81,7 +81,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
 
     fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
         self.super_rvalue(rvalue);
-        if let Some(ty) = self.mir.rvalue_ty(self.tcx(), rvalue) {
+        if let Some(ty) = rvalue.ty(self.mir, self.tcx()) {
             self.sanitize_type(rvalue, ty);
         }
     }
@@ -180,7 +180,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
             }
             ProjectionElem::Index(ref i) => {
                 self.visit_operand(i);
-                let index_ty = self.mir.operand_ty(tcx, i);
+                let index_ty = i.ty(self.mir, tcx);
                 if index_ty != tcx.types.usize {
                     LvalueTy::Ty {
                         ty: span_mirbug_and_err!(self, i, "index by non-usize {:?}", i)
@@ -356,7 +356,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         match stmt.kind {
             StatementKind::Assign(ref lv, ref rv) => {
                 let lv_ty = lv.ty(mir, tcx).to_ty(tcx);
-                let rv_ty = mir.rvalue_ty(tcx, rv);
+                let rv_ty = rv.ty(mir, tcx);
                 if let Some(rv_ty) = rv_ty {
                     if let Err(terr) = self.sub_types(self.last_span, rv_ty, lv_ty) {
                         span_mirbug!(self, stmt, "bad assignment ({:?} = {:?}): {:?}",
@@ -391,7 +391,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 ..
             } => {
                 let lv_ty = location.ty(mir, tcx).to_ty(tcx);
-                let rv_ty = mir.operand_ty(tcx, value);
+                let rv_ty = value.ty(mir, tcx);
                 if let Err(terr) = self.sub_types(self.last_span, rv_ty, lv_ty) {
                     span_mirbug!(self, term, "bad DropAndReplace ({:?} = {:?}): {:?}",
                                  lv_ty, rv_ty, terr);
@@ -399,7 +399,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
             }
 
             TerminatorKind::If { ref cond, .. } => {
-                let cond_ty = mir.operand_ty(tcx, cond);
+                let cond_ty = cond.ty(mir, tcx);
                 match cond_ty.sty {
                     ty::TyBool => {}
                     _ => {
@@ -433,7 +433,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 }
             }
             TerminatorKind::Call { ref func, ref args, ref destination, .. } => {
-                let func_ty = mir.operand_ty(tcx, func);
+                let func_ty = func.ty(mir, tcx);
                 debug!("check_terminator: call, func_ty={:?}", func_ty);
                 let func_ty = match func_ty.sty {
                     ty::TyFnDef(_, _, func_ty) | ty::TyFnPtr(func_ty) => func_ty,
@@ -453,16 +453,16 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 }
             }
             TerminatorKind::Assert { ref cond, ref msg, .. } => {
-                let cond_ty = mir.operand_ty(tcx, cond);
+                let cond_ty = cond.ty(mir, tcx);
                 if cond_ty != tcx.types.bool {
                     span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
                 }
 
                 if let AssertMessage::BoundsCheck { ref len, ref index } = *msg {
-                    if mir.operand_ty(tcx, len) != tcx.types.usize {
+                    if len.ty(mir, tcx) != tcx.types.usize {
                         span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
                     }
-                    if mir.operand_ty(tcx, index) != tcx.types.usize {
+                    if index.ty(mir, tcx) != tcx.types.usize {
                         span_mirbug!(self, index, "bounds-check index non-usize {:?}", index)
                     }
                 }
@@ -507,7 +507,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
             span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
         }
         for (n, (fn_arg, op_arg)) in sig.inputs.iter().zip(args).enumerate() {
-            let op_arg_ty = mir.operand_ty(self.tcx(), op_arg);
+            let op_arg_ty = op_arg.ty(mir, self.tcx());
             if let Err(terr) = self.sub_types(self.last_span, op_arg_ty, fn_arg) {
                 span_mirbug!(self, term, "bad arg #{:?} ({:?} <- {:?}): {:?}",
                              n, fn_arg, op_arg_ty, terr);
@@ -554,7 +554,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
             return;
         }
 
-        let arg_ty = match mir.operand_ty(self.tcx(), &args[0]).sty {
+        let arg_ty = match args[0].ty(mir, self.tcx()).sty {
             ty::TyRawPtr(mt) => mt.ty,
             ty::TyBox(ty) => ty,
             _ => {
diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs
index 6246e4a9d35..58b49f6944f 100644
--- a/src/librustc_trans/collector.rs
+++ b/src/librustc_trans/collector.rs
@@ -478,7 +478,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
                 let target_ty = monomorphize::apply_param_substs(self.scx.tcx(),
                                                                  self.param_substs,
                                                                  &target_ty);
-                let source_ty = self.mir.operand_ty(self.scx.tcx(), operand);
+                let source_ty = operand.ty(self.mir, self.scx.tcx());
                 let source_ty = monomorphize::apply_param_substs(self.scx.tcx(),
                                                                  self.param_substs,
                                                                  &source_ty);
@@ -627,7 +627,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
                 match constant.ty.sty {
                     ty::TyFnDef(def_id, _, bare_fn_ty)
                         if is_drop_in_place_intrinsic(tcx, def_id, bare_fn_ty) => {
-                        let operand_ty = self.mir.operand_ty(tcx, &args[0]);
+                        let operand_ty = args[0].ty(self.mir, tcx);
                         if let ty::TyRawPtr(mt) = operand_ty.sty {
                             let operand_ty = monomorphize::apply_param_substs(tcx,
                                                                               self.param_substs,
diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs
index 3290bbf59c5..b1fd3e88d75 100644
--- a/src/librustc_trans/mir/block.rs
+++ b/src/librustc_trans/mir/block.rs
@@ -433,7 +433,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
 
                 let extra_args = &args[sig.inputs.len()..];
                 let extra_args = extra_args.iter().map(|op_arg| {
-                    let op_ty = self.mir.operand_ty(bcx.tcx(), op_arg);
+                    let op_ty = op_arg.ty(&self.mir, bcx.tcx());
                     bcx.monomorphize(&op_ty)
                 }).collect::<Vec<_>>();
                 let fn_ty = callee.direct_fn_type(bcx.ccx(), &extra_args);
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index fa40dfd64d6..35ded704296 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -327,7 +327,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
                 }
 
                 mir::TerminatorKind::Call { ref func, ref args, ref destination, .. } => {
-                    let fn_ty = self.mir.operand_ty(tcx, func);
+                    let fn_ty = func.ty(self.mir, tcx);
                     let fn_ty = self.monomorphize(&fn_ty);
                     let instance = match fn_ty.sty {
                         ty::TyFnDef(def_id, substs, _) => {
@@ -723,7 +723,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
                 let lhs = self.const_operand(lhs, span)?;
                 let rhs = self.const_operand(rhs, span)?;
                 let ty = lhs.ty;
-                let binop_ty = self.mir.binop_ty(tcx, op, lhs.ty, rhs.ty);
+                let binop_ty = op.ty(tcx, lhs.ty, rhs.ty);
                 let (lhs, rhs) = (lhs.llval, rhs.llval);
                 Const::new(const_scalar_binop(op, lhs, rhs, ty), binop_ty)
             }
@@ -732,7 +732,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
                 let lhs = self.const_operand(lhs, span)?;
                 let rhs = self.const_operand(rhs, span)?;
                 let ty = lhs.ty;
-                let val_ty = self.mir.binop_ty(tcx, op, lhs.ty, rhs.ty);
+                let val_ty = op.ty(tcx, lhs.ty, rhs.ty);
                 let binop_ty = tcx.mk_tup(vec![val_ty, tcx.types.bool]);
                 let (lhs, rhs) = (lhs.llval, rhs.llval);
                 assert!(!ty.is_fp());
diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs
index 97d65ce9c53..9f7c2ee219e 100644
--- a/src/librustc_trans/mir/rvalue.rs
+++ b/src/librustc_trans/mir/rvalue.rs
@@ -400,7 +400,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                 };
                 let operand = OperandRef {
                     val: OperandValue::Immediate(llresult),
-                    ty: self.mir.binop_ty(bcx.tcx(), op, lhs.ty, rhs.ty),
+                    ty: op.ty(bcx.tcx(), lhs.ty, rhs.ty),
                 };
                 (bcx, operand)
             }
@@ -410,7 +410,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                 let result = self.trans_scalar_checked_binop(&bcx, op,
                                                              lhs.immediate(), rhs.immediate(),
                                                              lhs.ty);
-                let val_ty = self.mir.binop_ty(bcx.tcx(), op, lhs.ty, rhs.ty);
+                let val_ty = op.ty(bcx.tcx(), lhs.ty, rhs.ty);
                 let operand_ty = bcx.tcx().mk_tup(vec![val_ty, bcx.tcx().types.bool]);
                 let operand = OperandRef {
                     val: result,

From 969b2b86ad1e77229dddb739d7b4c180dae07a4b Mon Sep 17 00:00:00 2001
From: Scott A Carr <s.carr1024@gmail.com>
Date: Tue, 9 Aug 2016 08:17:50 -0700
Subject: [PATCH 3/4] make tidy

---
 src/librustc/mir/tcx.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index 2c60d82997f..5ca60a70a7c 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -133,7 +133,7 @@ impl<'tcx> Lvalue<'tcx> {
 }
 
 impl<'tcx> Rvalue<'tcx> {
-    pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> 
+    pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>>
     {
         match self {
             &Rvalue::Use(ref operand) => Some(operand.ty(mir, tcx)),
@@ -207,7 +207,7 @@ impl<'tcx> Operand<'tcx> {
             &Operand::Consume(ref l) => l.ty(mir, tcx).to_ty(tcx),
             &Operand::Constant(ref c) => c.ty,
         }
-    }    
+    }
 }
 
 impl<'tcx> BinOp {
@@ -232,7 +232,7 @@ impl<'tcx> BinOp {
                 tcx.types.bool
             }
         }
-    }  
+    }
 }
 
 impl BorrowKind {

From f37bf6d367c8fb0a69f72ff49b24ad2da67ddbe5 Mon Sep 17 00:00:00 2001
From: Scott A Carr <s.carr1024@gmail.com>
Date: Wed, 10 Aug 2016 09:42:33 -0700
Subject: [PATCH 4/4] no op commit for travis

---
 src/librustc/mir/tcx.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index 5ca60a70a7c..534bb2c0b2b 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -214,8 +214,7 @@ impl<'tcx> BinOp {
       pub fn ty<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                     lhs_ty: Ty<'tcx>,
                     rhs_ty: Ty<'tcx>)
-                    -> Ty<'tcx>
-    {
+                    -> Ty<'tcx> {
         // FIXME: handle SIMD correctly
         match self {
             &BinOp::Add | &BinOp::Sub | &BinOp::Mul | &BinOp::Div | &BinOp::Rem |