mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-16 22:16:53 +00:00
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:
commit
42001edc99
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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, _) => {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
_ => {
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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) => {
|
||||
|
@ -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());
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user