diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index e3905c39daa9c..534bb2c0b2b2a 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -113,75 +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) => self.lvalue_ty(tcx, l).to_ty(tcx), - Operand::Constant(ref c) => c.ty, - } - } - - pub fn binop_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - op: BinOp, - lhs_ty: Ty<'tcx>, - rhs_ty: Ty<'tcx>) - -> 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 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) => +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: self.return_ty.unwrap() }, - Lvalue::Projection(ref proj) => - self.lvalue_ty(tcx, &proj.base).projection_ty(tcx, &proj.elem) + &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 rvalue_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - rvalue: &Rvalue<'tcx>) - -> Option> +impl<'tcx> Rvalue<'tcx> { + pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option> { - 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 = self.lvalue_ty(tcx, lv).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 { @@ -190,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 @@ -222,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) => { @@ -233,7 +196,40 @@ 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 + } } } } diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index 623ea60c5a6d8..f6e9484eda1a4 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 7481b15685e69..7c912e8bac6bb 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 4b551d6bb083c..fa3490cbcf338 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -347,13 +347,13 @@ 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(); 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 b16ee9577463b..539ec81889f01 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -486,8 +486,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 { @@ -506,8 +505,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); } @@ -592,7 +590,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 [] @@ -652,7 +650,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) { @@ -670,7 +668,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); @@ -702,7 +700,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, @@ -724,7 +722,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 && @@ -804,7 +802,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 26a907920e8db..c8556d5e0d83f 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -79,7 +79,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); } } @@ -178,7 +178,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) @@ -353,8 +353,8 @@ 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 rv_ty = mir.rvalue_ty(tcx, rv); + let lv_ty = lv.ty(mir, tcx).to_ty(tcx); + 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 ({:?} = {:?}): {:?}", @@ -388,8 +388,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { ref value, .. } => { - let lv_ty = mir.lvalue_ty(tcx, location).to_ty(tcx); - let rv_ty = mir.operand_ty(tcx, value); + let lv_ty = location.ty(mir, tcx).to_ty(tcx); + 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); @@ -397,7 +397,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 => {} _ => { @@ -406,7 +406,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); @@ -419,7 +419,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() @@ -431,7 +431,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, @@ -451,16 +451,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) } } @@ -479,7 +479,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 ({:?} <- {:?}): {:?}", @@ -505,7 +505,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); @@ -552,7 +552,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 ba2cd2ba69992..58b49f6944fa7 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); @@ -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, @@ -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/analyze.rs b/src/librustc_trans/mir/analyze.rs index dac7afab6e38b..d6dbefec03467 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 9bfdb511c623c..b1fd3e88d75f0 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 @@ -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::>(); let fn_ty = callee.direct_fn_type(bcx.ccx(), &extra_args); @@ -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 00db19d2739c3..35ded7042969f 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), @@ -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, _) => { @@ -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) => { @@ -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/lvalue.rs b/src/librustc_trans/mir/lvalue.rs index ceaba2a40ca55..94db2e3c23cef 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/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 97d65ce9c5361..9f7c2ee219eb5 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, diff --git a/src/librustc_trans/mir/statement.rs b/src/librustc_trans/mir/statement.rs index 55efa75b17336..44d264c7e98f2 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,