Skip to content

Commit

Permalink
rustc_mir: use Local in ProjectionElem::Index.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Sep 3, 2017
1 parent c911925 commit 2f42cd8
Show file tree
Hide file tree
Showing 14 changed files with 65 additions and 74 deletions.
10 changes: 5 additions & 5 deletions src/librustc/mir/mod.rs
Expand Up @@ -1077,12 +1077,12 @@ pub enum ProjectionElem<'tcx, V, T> {
}

/// Alias for projections as they appear in lvalues, where the base is an lvalue
/// and the index is an operand.
pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>, Ty<'tcx>>;
/// and the index is a local.
pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Local, Ty<'tcx>>;

/// Alias for projections as they appear in lvalues, where the base is an lvalue
/// and the index is an operand.
pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Operand<'tcx>, Ty<'tcx>>;
/// and the index is a local.
pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;

newtype_index!(Field, "field");

Expand All @@ -1099,7 +1099,7 @@ impl<'tcx> Lvalue<'tcx> {
self.elem(ProjectionElem::Downcast(adt_def, variant_index))
}

pub fn index(self, index: Operand<'tcx>) -> Lvalue<'tcx> {
pub fn index(self, index: Local) -> Lvalue<'tcx> {
self.elem(ProjectionElem::Index(index))
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/mir/visit.rs
Expand Up @@ -664,8 +664,8 @@ macro_rules! make_mir_visitor {
ProjectionElem::Field(_field, ref $($mutability)* ty) => {
self.visit_ty(ty, Lookup::Loc(location));
}
ProjectionElem::Index(ref $($mutability)* operand) => {
self.visit_operand(operand, location);
ProjectionElem::Index(ref $($mutability)* local) => {
self.visit_local(local, LvalueContext::Consume, location);
}
ProjectionElem::ConstantIndex { offset: _,
min_length: _,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/structural_impls.rs
Expand Up @@ -421,7 +421,7 @@ macro_rules! CopyImpls {
}
}

CopyImpls! { (), hir::Unsafety, abi::Abi, hir::def_id::DefId }
CopyImpls! { (), hir::Unsafety, abi::Abi, hir::def_id::DefId, ::mir::Local }

impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
Expand Down
25 changes: 4 additions & 21 deletions src/librustc_mir/borrow_check.rs
Expand Up @@ -710,7 +710,7 @@ mod restrictions {

use rustc::hir;
use rustc::ty::{self, TyCtxt};
use rustc::mir::{Lvalue, Mir, Operand, ProjectionElem};
use rustc::mir::{Lvalue, Mir, ProjectionElem};

pub(super) struct Restrictions<'c, 'tcx: 'c> {
mir: &'c Mir<'tcx>,
Expand Down Expand Up @@ -809,12 +809,7 @@ mod restrictions {
ProjectionElem::Downcast(..) |
ProjectionElem::Subslice { .. } |
ProjectionElem::ConstantIndex { .. } |
ProjectionElem::Index(Operand::Constant(..)) => {
cursor = &proj.base;
continue 'cursor;
}
ProjectionElem::Index(Operand::Consume(ref index)) => {
self.lvalue_stack.push(index); // FIXME: did old borrowck do this?
ProjectionElem::Index(_) => {
cursor = &proj.base;
continue 'cursor;
}
Expand Down Expand Up @@ -1004,7 +999,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
("", format!(""), None), // (dont emit downcast info)
ProjectionElem::Field(field, _ty) =>
("", format!(".{}", field.index()), None),
ProjectionElem::Index(ref index) =>
ProjectionElem::Index(index) =>
("", format!(""), Some(index)),
ProjectionElem::ConstantIndex { offset, min_length, from_end: true } =>
("", format!("[{} of {}]", offset, min_length), None),
Expand All @@ -1021,23 +1016,11 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
self.append_lvalue_to_string(&proj.base, buf);
if let Some(index) = index_operand {
buf.push_str("[");
self.append_operand_to_string(index, buf);
self.append_lvalue_to_string(&Lvalue::Local(index), buf);
buf.push_str("]");
} else {
buf.push_str(&suffix);
}

}
}
}

fn append_operand_to_string(&self, operand: &Operand, buf: &mut String) {
match *operand {
Operand::Consume(ref lvalue) => {
self.append_lvalue_to_string(lvalue, buf);
}
Operand::Constant(ref constant) => {
buf.push_str(&format!("{:?}", constant));
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/librustc_mir/build/expr/as_lvalue.rs
Expand Up @@ -61,7 +61,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// region_scope=None so lvalue indexes live forever. They are scalars so they
// do not need storage annotations, and they are often copied between
// places.
let idx = unpack!(block = this.as_operand(block, None, index));
let idx = unpack!(block = this.as_temp(block, None, index));

// bounds check:
let (len, lt) = (this.temp(usize_ty.clone(), expr_span),
Expand All @@ -70,12 +70,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
&len, Rvalue::Len(slice.clone()));
this.cfg.push_assign(block, source_info, // lt = idx < len
&lt, Rvalue::BinaryOp(BinOp::Lt,
idx.clone(),
Operand::Consume(Lvalue::Local(idx)),
Operand::Consume(len.clone())));

let msg = AssertMessage::BoundsCheck {
len: Operand::Consume(len),
index: idx.clone()
index: Operand::Consume(Lvalue::Local(idx))
};
let success = this.assert(block, Operand::Consume(lt), true,
msg, expr_span);
Expand Down Expand Up @@ -127,7 +127,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
Some(Category::Lvalue) => false,
_ => true,
});
this.as_temp(block, expr.temp_lifetime, expr)
let temp = unpack!(block = this.as_temp(block, expr.temp_lifetime, expr));
block.and(Lvalue::Local(temp))
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/build/expr/as_operand.rs
Expand Up @@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
Category::Rvalue(..) => {
let operand =
unpack!(block = this.as_temp(block, scope, expr));
block.and(Operand::Consume(operand))
block.and(Operand::Consume(Lvalue::Local(operand)))
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions src/librustc_mir/build/expr/as_temp.rs
Expand Up @@ -23,7 +23,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
block: BasicBlock,
temp_lifetime: Option<region::Scope>,
expr: M)
-> BlockAnd<Lvalue<'tcx>>
-> BlockAnd<Local>
where M: Mirror<'tcx, Output = Expr<'tcx>>
{
let expr = self.hir.mirror(expr);
Expand All @@ -34,7 +34,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
mut block: BasicBlock,
temp_lifetime: Option<region::Scope>,
expr: Expr<'tcx>)
-> BlockAnd<Lvalue<'tcx>> {
-> BlockAnd<Local> {
debug!("expr_as_temp(block={:?}, temp_lifetime={:?}, expr={:?})",
block, temp_lifetime, expr);
let this = self;
Expand All @@ -47,13 +47,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
});
}

let expr_ty = expr.ty.clone();
let temp = this.temp(expr_ty.clone(), expr_span);
let expr_ty = expr.ty;
let temp = this.local_decls.push(LocalDecl::new_temp(expr_ty, expr_span));

if !expr_ty.is_never() {
this.cfg.push(block, Statement {
source_info,
kind: StatementKind::StorageLive(temp.clone())
kind: StatementKind::StorageLive(Lvalue::Local(temp))
});
}

Expand All @@ -68,18 +68,18 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
Category::Lvalue => {
let lvalue = unpack!(block = this.as_lvalue(block, expr));
let rvalue = Rvalue::Use(Operand::Consume(lvalue));
this.cfg.push_assign(block, source_info, &temp, rvalue);
this.cfg.push_assign(block, source_info, &Lvalue::Local(temp), rvalue);
}
_ => {
unpack!(block = this.into(&temp, block, expr));
unpack!(block = this.into(&Lvalue::Local(temp), block, expr));
}
}

// In constants, temp_lifetime is None. We should not need to drop
// anything because no values with a destructor can be created in
// a constant at this time, even if the type may need dropping.
if let Some(temp_lifetime) = temp_lifetime {
this.schedule_drop(expr_span, temp_lifetime, &temp, expr_ty);
this.schedule_drop(expr_span, temp_lifetime, &Lvalue::Local(temp), expr_ty);
}

block.and(temp)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/build/expr/into.rs
Expand Up @@ -229,7 +229,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {

let topmost_scope = this.topmost_scope();
let ptr = unpack!(block = this.as_temp(block, Some(topmost_scope), ptr));
this.into(&ptr.deref(), block, val)
this.into(&Lvalue::Local(ptr).deref(), block, val)
} else {
let args: Vec<_> =
args.into_iter()
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_mir/dataflow/move_paths/abs_domain.rs
Expand Up @@ -21,8 +21,7 @@
//! `a[x]` would still overlap them both. But that is not this
//! representation does today.)

use rustc::mir::LvalueElem;
use rustc::mir::{Operand, ProjectionElem};
use rustc::mir::{Local, LvalueElem, Operand, ProjectionElem};
use rustc::ty::Ty;

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
Expand All @@ -40,6 +39,10 @@ impl<'tcx> Lift for Operand<'tcx> {
type Abstract = AbstractOperand;
fn lift(&self) -> Self::Abstract { AbstractOperand }
}
impl Lift for Local {
type Abstract = AbstractOperand;
fn lift(&self) -> Self::Abstract { AbstractOperand }
}
impl<'tcx> Lift for Ty<'tcx> {
type Abstract = AbstractType;
fn lift(&self) -> Self::Abstract { AbstractType }
Expand Down
28 changes: 15 additions & 13 deletions src/librustc_mir/shim.rs
Expand Up @@ -479,9 +479,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {

fn array_shim(&mut self, ty: ty::Ty<'tcx>, len: usize) {
let tcx = self.tcx;
let span = self.span;
let rcvr = Lvalue::Local(Local::new(1+0)).deref();

let beg = self.make_lvalue(Mutability::Mut, tcx.types.usize);
let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
let end = self.make_lvalue(Mutability::Not, tcx.types.usize);
let ret = self.make_lvalue(Mutability::Mut, tcx.mk_array(ty, len));

Expand All @@ -492,7 +493,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
let inits = vec![
self.make_statement(
StatementKind::Assign(
beg.clone(),
Lvalue::Local(beg),
Rvalue::Use(Operand::Constant(self.make_usize(0)))
)
),
Expand All @@ -510,19 +511,19 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
// BB #3;
// }
// BB #4;
self.loop_header(beg.clone(), end, BasicBlock::new(2), BasicBlock::new(4), false);
self.loop_header(Lvalue::Local(beg), end, BasicBlock::new(2), BasicBlock::new(4), false);

// BB #2
// `let cloned = Clone::clone(rcvr[beg])`;
// Goto #3 if ok, #5 if unwinding happens.
let rcvr_field = rcvr.clone().index(Operand::Consume(beg.clone()));
let rcvr_field = rcvr.clone().index(beg);
let cloned = self.make_clone_call(ty, rcvr_field, BasicBlock::new(3), BasicBlock::new(5));

// BB #3
// `ret[beg] = cloned;`
// `beg = beg + 1;`
// `goto #1`;
let ret_field = ret.clone().index(Operand::Consume(beg.clone()));
let ret_field = ret.clone().index(beg);
let statements = vec![
self.make_statement(
StatementKind::Assign(
Expand All @@ -532,10 +533,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
),
self.make_statement(
StatementKind::Assign(
beg.clone(),
Lvalue::Local(beg),
Rvalue::BinaryOp(
BinOp::Add,
Operand::Consume(beg.clone()),
Operand::Consume(Lvalue::Local(beg)),
Operand::Constant(self.make_usize(1))
)
)
Expand All @@ -558,10 +559,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
// `let mut beg = 0;`
// goto #6;
let end = beg;
let beg = self.make_lvalue(Mutability::Mut, tcx.types.usize);
let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
let init = self.make_statement(
StatementKind::Assign(
beg.clone(),
Lvalue::Local(beg),
Rvalue::Use(Operand::Constant(self.make_usize(0)))
)
);
Expand All @@ -572,12 +573,13 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
// BB #8;
// }
// BB #9;
self.loop_header(beg.clone(), end, BasicBlock::new(7), BasicBlock::new(9), true);
self.loop_header(Lvalue::Local(beg), Lvalue::Local(end),
BasicBlock::new(7), BasicBlock::new(9), true);

// BB #7 (cleanup)
// `drop(ret[beg])`;
self.block(vec![], TerminatorKind::Drop {
location: ret.index(Operand::Consume(beg.clone())),
location: ret.index(beg),
target: BasicBlock::new(8),
unwind: None,
}, true);
Expand All @@ -587,10 +589,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
// `goto #6;`
let statement = self.make_statement(
StatementKind::Assign(
beg.clone(),
Lvalue::Local(beg),
Rvalue::BinaryOp(
BinOp::Add,
Operand::Consume(beg.clone()),
Operand::Consume(Lvalue::Local(beg)),
Operand::Constant(self.make_usize(1))
)
)
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_mir/transform/type_check.rs
Expand Up @@ -165,7 +165,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
base: LvalueTy<'tcx>,
pi: &LvalueElem<'tcx>,
lvalue: &Lvalue<'tcx>,
location: Location)
_: Location)
-> LvalueTy<'tcx> {
debug!("sanitize_projection: {:?} {:?} {:?}", base, pi, lvalue);
let tcx = self.tcx();
Expand All @@ -181,9 +181,8 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
})
}
}
ProjectionElem::Index(ref i) => {
self.visit_operand(i, location);
let index_ty = i.ty(self.mir, tcx);
ProjectionElem::Index(i) => {
let index_ty = Lvalue::Local(i).ty(self.mir, tcx).to_ty(tcx);
if index_ty != tcx.types.usize {
LvalueTy::Ty {
ty: span_mirbug_and_err!(self, i, "index by non-usize {:?}", i)
Expand Down

0 comments on commit 2f42cd8

Please sign in to comment.