Auto merge of #35403 - scottcarr:lvalue_refactor, r=nikomatsakis

refactor lvalue_ty to be method of lvalue

Currently `Mir` (and `MirContext`) implement a method `lvalue_ty` (and actually many more `foo_ty`).  But this should be a method of `Lvalue`.

If you have an `lvalue` and you want to get its type, the natural thing to write is:

```
lvalue.ty()
```

Of course it needs context, but still:

```
lvalue.ty(mir, tcx)
```

Makes more sense than

```
mir.lvalue_ty(lvalue, tcx)
```

I actually think we should go a step farther and have traits so we could get the type of some value generically, but that's up for debate.  The thing I'm running into a lot in the compiler is I have a value of type `Foo` and I know that there is some related type `Bar` which I can get through some combination of method calls, but it's often not as direct as I would imagine.  Unless you already know the code, its not clear why you would look in `Mir` for a method to get the type of an `Lvalue`.
This commit is contained in:
bors 2016-08-11 05:04:41 -07:00 committed by GitHub
commit 42001edc99
13 changed files with 129 additions and 134 deletions

View File

@ -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<Ty<'tcx>>
impl<'tcx> Rvalue<'tcx> {
pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, '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 = 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
}
}
}
}

View File

@ -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, _) => {

View File

@ -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;
}

View File

@ -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,

View File

@ -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);

View File

@ -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,
_ => {

View File

@ -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,

View File

@ -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.

View File

@ -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::<Vec<_>>();
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) => {

View File

@ -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());

View File

@ -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))
}
}

View File

@ -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,

View File

@ -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,