mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
MIR: s/Lvalue/Place in type names.
This commit is contained in:
parent
e3ed21272d
commit
511743c438
@ -318,19 +318,19 @@ impl<'gcx, T> HashStable<StableHashingContext<'gcx>>
|
||||
|
||||
impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(region_scope) });
|
||||
|
||||
impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Lvalue<'gcx> {
|
||||
impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Place<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'gcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
match *self {
|
||||
mir::Lvalue::Local(ref local) => {
|
||||
mir::Place::Local(ref local) => {
|
||||
local.hash_stable(hcx, hasher);
|
||||
}
|
||||
mir::Lvalue::Static(ref statik) => {
|
||||
mir::Place::Static(ref statik) => {
|
||||
statik.hash_stable(hcx, hasher);
|
||||
}
|
||||
mir::Lvalue::Projection(ref lvalue_projection) => {
|
||||
mir::Place::Projection(ref lvalue_projection) => {
|
||||
lvalue_projection.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use hir::def_id::DefId;
|
||||
use middle::free_region::{FreeRegionMap, RegionRelations};
|
||||
use middle::region;
|
||||
use middle::lang_items;
|
||||
use mir::tcx::LvalueTy;
|
||||
use mir::tcx::PlaceTy;
|
||||
use ty::subst::{Kind, Subst, Substs};
|
||||
use ty::{TyVid, IntVid, FloatVid};
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
@ -518,15 +518,15 @@ impl_trans_normalize!('gcx,
|
||||
ty::ExistentialTraitRef<'gcx>
|
||||
);
|
||||
|
||||
impl<'gcx> TransNormalize<'gcx> for LvalueTy<'gcx> {
|
||||
impl<'gcx> TransNormalize<'gcx> for PlaceTy<'gcx> {
|
||||
fn trans_normalize<'a, 'tcx>(&self,
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>)
|
||||
-> Self {
|
||||
match *self {
|
||||
LvalueTy::Ty { ty } => LvalueTy::Ty { ty: ty.trans_normalize(infcx, param_env) },
|
||||
LvalueTy::Downcast { adt_def, substs, variant_index } => {
|
||||
LvalueTy::Downcast {
|
||||
PlaceTy::Ty { ty } => PlaceTy::Ty { ty: ty.trans_normalize(infcx, param_env) },
|
||||
PlaceTy::Downcast { adt_def, substs, variant_index } => {
|
||||
PlaceTy::Downcast {
|
||||
adt_def,
|
||||
substs: substs.trans_normalize(infcx, param_env),
|
||||
variant_index,
|
||||
|
@ -641,14 +641,14 @@ pub enum TerminatorKind<'tcx> {
|
||||
/// Indicates a terminator that can never be reached.
|
||||
Unreachable,
|
||||
|
||||
/// Drop the Lvalue
|
||||
/// Drop the Place
|
||||
Drop {
|
||||
location: Lvalue<'tcx>,
|
||||
location: Place<'tcx>,
|
||||
target: BasicBlock,
|
||||
unwind: Option<BasicBlock>
|
||||
},
|
||||
|
||||
/// Drop the Lvalue and assign the new value over it. This ensures
|
||||
/// Drop the Place and assign the new value over it. This ensures
|
||||
/// that the assignment to LV occurs *even if* the destructor for
|
||||
/// lvalue unwinds. Its semantics are best explained by by the
|
||||
/// elaboration:
|
||||
@ -675,7 +675,7 @@ pub enum TerminatorKind<'tcx> {
|
||||
/// }
|
||||
/// ```
|
||||
DropAndReplace {
|
||||
location: Lvalue<'tcx>,
|
||||
location: Place<'tcx>,
|
||||
value: Operand<'tcx>,
|
||||
target: BasicBlock,
|
||||
unwind: Option<BasicBlock>,
|
||||
@ -691,7 +691,7 @@ pub enum TerminatorKind<'tcx> {
|
||||
/// reused across function calls without duplicating the contents.
|
||||
args: Vec<Operand<'tcx>>,
|
||||
/// Destination for the return value. If some, the call is converging.
|
||||
destination: Option<(Lvalue<'tcx>, BasicBlock)>,
|
||||
destination: Option<(Place<'tcx>, BasicBlock)>,
|
||||
/// Cleanups to be done if the call unwinds.
|
||||
cleanup: Option<BasicBlock>
|
||||
},
|
||||
@ -1002,11 +1002,11 @@ impl<'tcx> Statement<'tcx> {
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub enum StatementKind<'tcx> {
|
||||
/// Write the RHS Rvalue to the LHS Lvalue.
|
||||
Assign(Lvalue<'tcx>, Rvalue<'tcx>),
|
||||
/// Write the RHS Rvalue to the LHS Place.
|
||||
Assign(Place<'tcx>, Rvalue<'tcx>),
|
||||
|
||||
/// Write the discriminant for a variant to the enum Lvalue.
|
||||
SetDiscriminant { lvalue: Lvalue<'tcx>, variant_index: usize },
|
||||
/// Write the discriminant for a variant to the enum Place.
|
||||
SetDiscriminant { lvalue: Place<'tcx>, variant_index: usize },
|
||||
|
||||
/// Start a live range for the storage of the local.
|
||||
StorageLive(Local),
|
||||
@ -1017,14 +1017,14 @@ pub enum StatementKind<'tcx> {
|
||||
/// Execute a piece of inline Assembly.
|
||||
InlineAsm {
|
||||
asm: Box<InlineAsm>,
|
||||
outputs: Vec<Lvalue<'tcx>>,
|
||||
outputs: Vec<Place<'tcx>>,
|
||||
inputs: Vec<Operand<'tcx>>
|
||||
},
|
||||
|
||||
/// Assert the given lvalues to be valid inhabitants of their type. These statements are
|
||||
/// currently only interpreted by miri and only generated when "-Z mir-emit-validate" is passed.
|
||||
/// See <https://internals.rust-lang.org/t/types-as-contracts/5562/73> for more details.
|
||||
Validate(ValidationOp, Vec<ValidationOperand<'tcx, Lvalue<'tcx>>>),
|
||||
Validate(ValidationOp, Vec<ValidationOperand<'tcx, Place<'tcx>>>),
|
||||
|
||||
/// Mark one terminating point of a region scope (i.e. static region).
|
||||
/// (The starting point(s) arise implicitly from borrows.)
|
||||
@ -1107,12 +1107,12 @@ impl<'tcx> Debug for Statement<'tcx> {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Lvalues
|
||||
// Places
|
||||
|
||||
/// A path to a value; something that can be evaluated without
|
||||
/// changing or disturbing program state.
|
||||
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
|
||||
pub enum Lvalue<'tcx> {
|
||||
pub enum Place<'tcx> {
|
||||
/// local variable
|
||||
Local(Local),
|
||||
|
||||
@ -1120,7 +1120,7 @@ pub enum Lvalue<'tcx> {
|
||||
Static(Box<Static<'tcx>>),
|
||||
|
||||
/// projection out of an lvalue (access a field, deref a pointer, etc)
|
||||
Projection(Box<LvalueProjection<'tcx>>),
|
||||
Projection(Box<PlaceProjection<'tcx>>),
|
||||
}
|
||||
|
||||
/// The def-id of a static, along with its normalized type (which is
|
||||
@ -1138,8 +1138,8 @@ impl_stable_hash_for!(struct Static<'tcx> {
|
||||
|
||||
/// The `Projection` data structure defines things of the form `B.x`
|
||||
/// or `*B` or `B[index]`. Note that it is parameterized because it is
|
||||
/// shared between `Constant` and `Lvalue`. See the aliases
|
||||
/// `LvalueProjection` etc below.
|
||||
/// shared between `Constant` and `Place`. See the aliases
|
||||
/// `PlaceProjection` etc below.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub struct Projection<'tcx, B, V, T> {
|
||||
pub base: B,
|
||||
@ -1186,42 +1186,42 @@ pub enum ProjectionElem<'tcx, V, T> {
|
||||
|
||||
/// Alias for projections as they appear in lvalues, where the base is an lvalue
|
||||
/// and the index is a local.
|
||||
pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Local, Ty<'tcx>>;
|
||||
pub type PlaceProjection<'tcx> = Projection<'tcx, Place<'tcx>, Local, Ty<'tcx>>;
|
||||
|
||||
/// Alias for projections as they appear in lvalues, where the base is an lvalue
|
||||
/// and the index is a local.
|
||||
pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;
|
||||
pub type PlaceElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;
|
||||
|
||||
newtype_index!(Field { DEBUG_FORMAT = "field[{}]" });
|
||||
|
||||
impl<'tcx> Lvalue<'tcx> {
|
||||
pub fn field(self, f: Field, ty: Ty<'tcx>) -> Lvalue<'tcx> {
|
||||
impl<'tcx> Place<'tcx> {
|
||||
pub fn field(self, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
|
||||
self.elem(ProjectionElem::Field(f, ty))
|
||||
}
|
||||
|
||||
pub fn deref(self) -> Lvalue<'tcx> {
|
||||
pub fn deref(self) -> Place<'tcx> {
|
||||
self.elem(ProjectionElem::Deref)
|
||||
}
|
||||
|
||||
pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: usize) -> Lvalue<'tcx> {
|
||||
pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: usize) -> Place<'tcx> {
|
||||
self.elem(ProjectionElem::Downcast(adt_def, variant_index))
|
||||
}
|
||||
|
||||
pub fn index(self, index: Local) -> Lvalue<'tcx> {
|
||||
pub fn index(self, index: Local) -> Place<'tcx> {
|
||||
self.elem(ProjectionElem::Index(index))
|
||||
}
|
||||
|
||||
pub fn elem(self, elem: LvalueElem<'tcx>) -> Lvalue<'tcx> {
|
||||
Lvalue::Projection(Box::new(LvalueProjection {
|
||||
pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> {
|
||||
Place::Projection(Box::new(PlaceProjection {
|
||||
base: self,
|
||||
elem,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Debug for Lvalue<'tcx> {
|
||||
impl<'tcx> Debug for Place<'tcx> {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||
use self::Lvalue::*;
|
||||
use self::Place::*;
|
||||
|
||||
match *self {
|
||||
Local(id) => write!(fmt, "{:?}", id),
|
||||
@ -1281,13 +1281,13 @@ pub enum Operand<'tcx> {
|
||||
///
|
||||
/// This implies that the type of the lvalue must be `Copy`; this is true
|
||||
/// by construction during build, but also checked by the MIR type checker.
|
||||
Copy(Lvalue<'tcx>),
|
||||
Copy(Place<'tcx>),
|
||||
/// Move: The value (including old borrows of it) will not be used again.
|
||||
///
|
||||
/// Safe for values of all types (modulo future developments towards `?Move`).
|
||||
/// Correct usage patterns are enforced by the borrow checker for safe code.
|
||||
/// `Copy` may be converted to `Move` to enable "last-use" optimizations.
|
||||
Move(Lvalue<'tcx>),
|
||||
Move(Place<'tcx>),
|
||||
Constant(Box<Constant<'tcx>>),
|
||||
}
|
||||
|
||||
@ -1336,10 +1336,10 @@ pub enum Rvalue<'tcx> {
|
||||
Repeat(Operand<'tcx>, ConstUsize),
|
||||
|
||||
/// &x or &mut x
|
||||
Ref(Region<'tcx>, BorrowKind, Lvalue<'tcx>),
|
||||
Ref(Region<'tcx>, BorrowKind, Place<'tcx>),
|
||||
|
||||
/// length of a [X] or [X;n] value
|
||||
Len(Lvalue<'tcx>),
|
||||
Len(Place<'tcx>),
|
||||
|
||||
Cast(CastKind, Operand<'tcx>, Ty<'tcx>),
|
||||
|
||||
@ -1353,7 +1353,7 @@ pub enum Rvalue<'tcx> {
|
||||
///
|
||||
/// Undefined (i.e. no effort is made to make it defined, but there’s no reason why it cannot
|
||||
/// be defined to return, say, a 0) if ADT is not an enum.
|
||||
Discriminant(Lvalue<'tcx>),
|
||||
Discriminant(Place<'tcx>),
|
||||
|
||||
/// Create an aggregate value, like a tuple or struct. This is
|
||||
/// only needed because we want to distinguish `dest = Foo { x:
|
||||
@ -1828,7 +1828,7 @@ impl<'tcx> TypeFoldable<'tcx> for BasicBlockData<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ValidationOperand<'tcx, Lvalue<'tcx>> {
|
||||
impl<'tcx> TypeFoldable<'tcx> for ValidationOperand<'tcx, Place<'tcx>> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
ValidationOperand {
|
||||
lval: self.lval.fold_with(folder),
|
||||
@ -2012,16 +2012,16 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Lvalue<'tcx> {
|
||||
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
match self {
|
||||
&Lvalue::Projection(ref p) => Lvalue::Projection(p.fold_with(folder)),
|
||||
&Place::Projection(ref p) => Place::Projection(p.fold_with(folder)),
|
||||
_ => self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
if let &Lvalue::Projection(ref p) = self {
|
||||
if let &Place::Projection(ref p) = self {
|
||||
p.visit_with(visitor)
|
||||
} else {
|
||||
false
|
||||
|
@ -21,7 +21,7 @@ use hir;
|
||||
use ty::util::IntTypeExt;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum LvalueTy<'tcx> {
|
||||
pub enum PlaceTy<'tcx> {
|
||||
/// Normal type.
|
||||
Ty { ty: Ty<'tcx> },
|
||||
|
||||
@ -31,23 +31,23 @@ pub enum LvalueTy<'tcx> {
|
||||
variant_index: usize },
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> LvalueTy<'tcx> {
|
||||
pub fn from_ty(ty: Ty<'tcx>) -> LvalueTy<'tcx> {
|
||||
LvalueTy::Ty { ty: ty }
|
||||
impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
|
||||
pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> {
|
||||
PlaceTy::Ty { ty: ty }
|
||||
}
|
||||
|
||||
pub fn to_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
|
||||
match *self {
|
||||
LvalueTy::Ty { ty } =>
|
||||
PlaceTy::Ty { ty } =>
|
||||
ty,
|
||||
LvalueTy::Downcast { adt_def, substs, variant_index: _ } =>
|
||||
PlaceTy::Downcast { adt_def, substs, variant_index: _ } =>
|
||||
tcx.mk_adt(adt_def, substs),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn projection_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
elem: &LvalueElem<'tcx>)
|
||||
-> LvalueTy<'tcx>
|
||||
elem: &PlaceElem<'tcx>)
|
||||
-> PlaceTy<'tcx>
|
||||
{
|
||||
match *elem {
|
||||
ProjectionElem::Deref => {
|
||||
@ -57,17 +57,17 @@ impl<'a, 'gcx, 'tcx> LvalueTy<'tcx> {
|
||||
bug!("deref projection of non-dereferencable ty {:?}", self)
|
||||
})
|
||||
.ty;
|
||||
LvalueTy::Ty {
|
||||
PlaceTy::Ty {
|
||||
ty,
|
||||
}
|
||||
}
|
||||
ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } =>
|
||||
LvalueTy::Ty {
|
||||
PlaceTy::Ty {
|
||||
ty: self.to_ty(tcx).builtin_index().unwrap()
|
||||
},
|
||||
ProjectionElem::Subslice { from, to } => {
|
||||
let ty = self.to_ty(tcx);
|
||||
LvalueTy::Ty {
|
||||
PlaceTy::Ty {
|
||||
ty: match ty.sty {
|
||||
ty::TyArray(inner, size) => {
|
||||
let size = size.val.to_const_int().unwrap().to_u64().unwrap();
|
||||
@ -87,7 +87,7 @@ impl<'a, 'gcx, 'tcx> LvalueTy<'tcx> {
|
||||
assert!(adt_def.is_enum());
|
||||
assert!(index < adt_def.variants.len());
|
||||
assert_eq!(adt_def, adt_def1);
|
||||
LvalueTy::Downcast { adt_def,
|
||||
PlaceTy::Downcast { adt_def,
|
||||
substs,
|
||||
variant_index: index }
|
||||
}
|
||||
@ -95,17 +95,17 @@ impl<'a, 'gcx, 'tcx> LvalueTy<'tcx> {
|
||||
bug!("cannot downcast non-ADT type: `{:?}`", self)
|
||||
}
|
||||
},
|
||||
ProjectionElem::Field(_, fty) => LvalueTy::Ty { ty: fty }
|
||||
ProjectionElem::Field(_, fty) => PlaceTy::Ty { ty: fty }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for LvalueTy<'tcx> {
|
||||
impl<'tcx> TypeFoldable<'tcx> for PlaceTy<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
match *self {
|
||||
LvalueTy::Ty { ty } => LvalueTy::Ty { ty: ty.fold_with(folder) },
|
||||
LvalueTy::Downcast { adt_def, substs, variant_index } => {
|
||||
LvalueTy::Downcast {
|
||||
PlaceTy::Ty { ty } => PlaceTy::Ty { ty: ty.fold_with(folder) },
|
||||
PlaceTy::Downcast { adt_def, substs, variant_index } => {
|
||||
PlaceTy::Downcast {
|
||||
adt_def,
|
||||
substs: substs.fold_with(folder),
|
||||
variant_index,
|
||||
@ -116,22 +116,22 @@ impl<'tcx> TypeFoldable<'tcx> for LvalueTy<'tcx> {
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
match *self {
|
||||
LvalueTy::Ty { ty } => ty.visit_with(visitor),
|
||||
LvalueTy::Downcast { substs, .. } => substs.visit_with(visitor)
|
||||
PlaceTy::Ty { ty } => ty.visit_with(visitor),
|
||||
PlaceTy::Downcast { substs, .. } => substs.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Lvalue<'tcx> {
|
||||
pub fn ty<'a, 'gcx, D>(&self, local_decls: &D, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> LvalueTy<'tcx>
|
||||
impl<'tcx> Place<'tcx> {
|
||||
pub fn ty<'a, 'gcx, D>(&self, local_decls: &D, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> PlaceTy<'tcx>
|
||||
where D: HasLocalDecls<'tcx>
|
||||
{
|
||||
match *self {
|
||||
Lvalue::Local(index) =>
|
||||
LvalueTy::Ty { ty: local_decls.local_decls()[index].ty },
|
||||
Lvalue::Static(ref data) =>
|
||||
LvalueTy::Ty { ty: data.ty },
|
||||
Lvalue::Projection(ref proj) =>
|
||||
Place::Local(index) =>
|
||||
PlaceTy::Ty { ty: local_decls.local_decls()[index].ty },
|
||||
Place::Static(ref data) =>
|
||||
PlaceTy::Ty { ty: data.ty },
|
||||
Place::Projection(ref proj) =>
|
||||
proj.base.ty(local_decls, tcx).projection_ty(tcx, &proj.elem),
|
||||
}
|
||||
}
|
||||
@ -184,7 +184,7 @@ impl<'tcx> Rvalue<'tcx> {
|
||||
} else {
|
||||
// Undefined behaviour, bug for now; may want to return something for
|
||||
// the `discriminant` intrinsic later.
|
||||
bug!("Rvalue::Discriminant on Lvalue of type {:?}", ty);
|
||||
bug!("Rvalue::Discriminant on Place of type {:?}", ty);
|
||||
}
|
||||
}
|
||||
Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t),
|
||||
|
@ -107,7 +107,7 @@ macro_rules! make_mir_visitor {
|
||||
|
||||
fn visit_assign(&mut self,
|
||||
block: BasicBlock,
|
||||
lvalue: & $($mutability)* Lvalue<'tcx>,
|
||||
lvalue: & $($mutability)* Place<'tcx>,
|
||||
rvalue: & $($mutability)* Rvalue<'tcx>,
|
||||
location: Location) {
|
||||
self.super_assign(block, lvalue, rvalue, location);
|
||||
@ -146,29 +146,29 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
|
||||
fn visit_lvalue(&mut self,
|
||||
lvalue: & $($mutability)* Lvalue<'tcx>,
|
||||
context: LvalueContext<'tcx>,
|
||||
lvalue: & $($mutability)* Place<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
self.super_lvalue(lvalue, context, location);
|
||||
}
|
||||
|
||||
fn visit_static(&mut self,
|
||||
static_: & $($mutability)* Static<'tcx>,
|
||||
context: LvalueContext<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
self.super_static(static_, context, location);
|
||||
}
|
||||
|
||||
fn visit_projection(&mut self,
|
||||
lvalue: & $($mutability)* LvalueProjection<'tcx>,
|
||||
context: LvalueContext<'tcx>,
|
||||
lvalue: & $($mutability)* PlaceProjection<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
self.super_projection(lvalue, context, location);
|
||||
}
|
||||
|
||||
fn visit_projection_elem(&mut self,
|
||||
lvalue: & $($mutability)* LvalueElem<'tcx>,
|
||||
context: LvalueContext<'tcx>,
|
||||
lvalue: & $($mutability)* PlaceElem<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
self.super_projection_elem(lvalue, context, location);
|
||||
}
|
||||
@ -263,7 +263,7 @@ macro_rules! make_mir_visitor {
|
||||
|
||||
fn visit_local(&mut self,
|
||||
_local: & $($mutability)* Local,
|
||||
_context: LvalueContext<'tcx>,
|
||||
_context: PlaceContext<'tcx>,
|
||||
_location: Location) {
|
||||
}
|
||||
|
||||
@ -358,25 +358,25 @@ macro_rules! make_mir_visitor {
|
||||
StatementKind::Validate(_, ref $($mutability)* lvalues) => {
|
||||
for operand in lvalues {
|
||||
self.visit_lvalue(& $($mutability)* operand.lval,
|
||||
LvalueContext::Validate, location);
|
||||
PlaceContext::Validate, location);
|
||||
self.visit_ty(& $($mutability)* operand.ty,
|
||||
TyContext::Location(location));
|
||||
}
|
||||
}
|
||||
StatementKind::SetDiscriminant{ ref $($mutability)* lvalue, .. } => {
|
||||
self.visit_lvalue(lvalue, LvalueContext::Store, location);
|
||||
self.visit_lvalue(lvalue, PlaceContext::Store, location);
|
||||
}
|
||||
StatementKind::StorageLive(ref $($mutability)* local) => {
|
||||
self.visit_local(local, LvalueContext::StorageLive, location);
|
||||
self.visit_local(local, PlaceContext::StorageLive, location);
|
||||
}
|
||||
StatementKind::StorageDead(ref $($mutability)* local) => {
|
||||
self.visit_local(local, LvalueContext::StorageDead, location);
|
||||
self.visit_local(local, PlaceContext::StorageDead, location);
|
||||
}
|
||||
StatementKind::InlineAsm { ref $($mutability)* outputs,
|
||||
ref $($mutability)* inputs,
|
||||
asm: _ } => {
|
||||
for output in & $($mutability)* outputs[..] {
|
||||
self.visit_lvalue(output, LvalueContext::Store, location);
|
||||
self.visit_lvalue(output, PlaceContext::Store, location);
|
||||
}
|
||||
for input in & $($mutability)* inputs[..] {
|
||||
self.visit_operand(input, location);
|
||||
@ -388,10 +388,10 @@ macro_rules! make_mir_visitor {
|
||||
|
||||
fn super_assign(&mut self,
|
||||
_block: BasicBlock,
|
||||
lvalue: &$($mutability)* Lvalue<'tcx>,
|
||||
lvalue: &$($mutability)* Place<'tcx>,
|
||||
rvalue: &$($mutability)* Rvalue<'tcx>,
|
||||
location: Location) {
|
||||
self.visit_lvalue(lvalue, LvalueContext::Store, location);
|
||||
self.visit_lvalue(lvalue, PlaceContext::Store, location);
|
||||
self.visit_rvalue(rvalue, location);
|
||||
}
|
||||
|
||||
@ -440,7 +440,7 @@ macro_rules! make_mir_visitor {
|
||||
TerminatorKind::Drop { ref $($mutability)* location,
|
||||
target,
|
||||
unwind } => {
|
||||
self.visit_lvalue(location, LvalueContext::Drop, source_location);
|
||||
self.visit_lvalue(location, PlaceContext::Drop, source_location);
|
||||
self.visit_branch(block, target);
|
||||
unwind.map(|t| self.visit_branch(block, t));
|
||||
}
|
||||
@ -449,7 +449,7 @@ macro_rules! make_mir_visitor {
|
||||
ref $($mutability)* value,
|
||||
target,
|
||||
unwind } => {
|
||||
self.visit_lvalue(location, LvalueContext::Drop, source_location);
|
||||
self.visit_lvalue(location, PlaceContext::Drop, source_location);
|
||||
self.visit_operand(value, source_location);
|
||||
self.visit_branch(block, target);
|
||||
unwind.map(|t| self.visit_branch(block, t));
|
||||
@ -464,7 +464,7 @@ macro_rules! make_mir_visitor {
|
||||
self.visit_operand(arg, source_location);
|
||||
}
|
||||
if let Some((ref $($mutability)* destination, target)) = *destination {
|
||||
self.visit_lvalue(destination, LvalueContext::Call, source_location);
|
||||
self.visit_lvalue(destination, PlaceContext::Call, source_location);
|
||||
self.visit_branch(block, target);
|
||||
}
|
||||
cleanup.map(|t| self.visit_branch(block, t));
|
||||
@ -532,14 +532,14 @@ macro_rules! make_mir_visitor {
|
||||
|
||||
Rvalue::Ref(ref $($mutability)* r, bk, ref $($mutability)* path) => {
|
||||
self.visit_region(r, location);
|
||||
self.visit_lvalue(path, LvalueContext::Borrow {
|
||||
self.visit_lvalue(path, PlaceContext::Borrow {
|
||||
region: *r,
|
||||
kind: bk
|
||||
}, location);
|
||||
}
|
||||
|
||||
Rvalue::Len(ref $($mutability)* path) => {
|
||||
self.visit_lvalue(path, LvalueContext::Inspect, location);
|
||||
self.visit_lvalue(path, PlaceContext::Inspect, location);
|
||||
}
|
||||
|
||||
Rvalue::Cast(_cast_kind,
|
||||
@ -564,7 +564,7 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
|
||||
Rvalue::Discriminant(ref $($mutability)* lvalue) => {
|
||||
self.visit_lvalue(lvalue, LvalueContext::Inspect, location);
|
||||
self.visit_lvalue(lvalue, PlaceContext::Inspect, location);
|
||||
}
|
||||
|
||||
Rvalue::NullaryOp(_op, ref $($mutability)* ty) => {
|
||||
@ -612,10 +612,10 @@ macro_rules! make_mir_visitor {
|
||||
location: Location) {
|
||||
match *operand {
|
||||
Operand::Copy(ref $($mutability)* lvalue) => {
|
||||
self.visit_lvalue(lvalue, LvalueContext::Copy, location);
|
||||
self.visit_lvalue(lvalue, PlaceContext::Copy, location);
|
||||
}
|
||||
Operand::Move(ref $($mutability)* lvalue) => {
|
||||
self.visit_lvalue(lvalue, LvalueContext::Move, location);
|
||||
self.visit_lvalue(lvalue, PlaceContext::Move, location);
|
||||
}
|
||||
Operand::Constant(ref $($mutability)* constant) => {
|
||||
self.visit_constant(constant, location);
|
||||
@ -624,17 +624,17 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
|
||||
fn super_lvalue(&mut self,
|
||||
lvalue: & $($mutability)* Lvalue<'tcx>,
|
||||
context: LvalueContext<'tcx>,
|
||||
lvalue: & $($mutability)* Place<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
match *lvalue {
|
||||
Lvalue::Local(ref $($mutability)* local) => {
|
||||
Place::Local(ref $($mutability)* local) => {
|
||||
self.visit_local(local, context, location);
|
||||
}
|
||||
Lvalue::Static(ref $($mutability)* static_) => {
|
||||
Place::Static(ref $($mutability)* static_) => {
|
||||
self.visit_static(static_, context, location);
|
||||
}
|
||||
Lvalue::Projection(ref $($mutability)* proj) => {
|
||||
Place::Projection(ref $($mutability)* proj) => {
|
||||
self.visit_projection(proj, context, location);
|
||||
}
|
||||
}
|
||||
@ -642,7 +642,7 @@ macro_rules! make_mir_visitor {
|
||||
|
||||
fn super_static(&mut self,
|
||||
static_: & $($mutability)* Static<'tcx>,
|
||||
_context: LvalueContext<'tcx>,
|
||||
_context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
let Static {
|
||||
ref $($mutability)* def_id,
|
||||
@ -653,25 +653,25 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
|
||||
fn super_projection(&mut self,
|
||||
proj: & $($mutability)* LvalueProjection<'tcx>,
|
||||
context: LvalueContext<'tcx>,
|
||||
proj: & $($mutability)* PlaceProjection<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
let Projection {
|
||||
ref $($mutability)* base,
|
||||
ref $($mutability)* elem,
|
||||
} = *proj;
|
||||
let context = if context.is_mutating_use() {
|
||||
LvalueContext::Projection(Mutability::Mut)
|
||||
PlaceContext::Projection(Mutability::Mut)
|
||||
} else {
|
||||
LvalueContext::Projection(Mutability::Not)
|
||||
PlaceContext::Projection(Mutability::Not)
|
||||
};
|
||||
self.visit_lvalue(base, context, location);
|
||||
self.visit_projection_elem(elem, context, location);
|
||||
}
|
||||
|
||||
fn super_projection_elem(&mut self,
|
||||
proj: & $($mutability)* LvalueElem<'tcx>,
|
||||
_context: LvalueContext<'tcx>,
|
||||
proj: & $($mutability)* PlaceElem<'tcx>,
|
||||
_context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
match *proj {
|
||||
ProjectionElem::Deref => {
|
||||
@ -682,7 +682,7 @@ macro_rules! make_mir_visitor {
|
||||
self.visit_ty(ty, TyContext::Location(location));
|
||||
}
|
||||
ProjectionElem::Index(ref $($mutability)* local) => {
|
||||
self.visit_local(local, LvalueContext::Copy, location);
|
||||
self.visit_local(local, PlaceContext::Copy, location);
|
||||
}
|
||||
ProjectionElem::ConstantIndex { offset: _,
|
||||
min_length: _,
|
||||
@ -831,7 +831,7 @@ pub enum TyContext {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum LvalueContext<'tcx> {
|
||||
pub enum PlaceContext<'tcx> {
|
||||
// Appears as LHS of an assignment
|
||||
Store,
|
||||
|
||||
@ -874,11 +874,11 @@ pub enum LvalueContext<'tcx> {
|
||||
Validate,
|
||||
}
|
||||
|
||||
impl<'tcx> LvalueContext<'tcx> {
|
||||
impl<'tcx> PlaceContext<'tcx> {
|
||||
/// Returns true if this lvalue context represents a drop.
|
||||
pub fn is_drop(&self) -> bool {
|
||||
match *self {
|
||||
LvalueContext::Drop => true,
|
||||
PlaceContext::Drop => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -886,7 +886,7 @@ impl<'tcx> LvalueContext<'tcx> {
|
||||
/// Returns true if this lvalue context represents a storage live or storage dead marker.
|
||||
pub fn is_storage_marker(&self) -> bool {
|
||||
match *self {
|
||||
LvalueContext::StorageLive | LvalueContext::StorageDead => true,
|
||||
PlaceContext::StorageLive | PlaceContext::StorageDead => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -894,7 +894,7 @@ impl<'tcx> LvalueContext<'tcx> {
|
||||
/// Returns true if this lvalue context represents a storage live marker.
|
||||
pub fn is_storage_live_marker(&self) -> bool {
|
||||
match *self {
|
||||
LvalueContext::StorageLive => true,
|
||||
PlaceContext::StorageLive => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -902,7 +902,7 @@ impl<'tcx> LvalueContext<'tcx> {
|
||||
/// Returns true if this lvalue context represents a storage dead marker.
|
||||
pub fn is_storage_dead_marker(&self) -> bool {
|
||||
match *self {
|
||||
LvalueContext::StorageDead => true,
|
||||
PlaceContext::StorageDead => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -910,31 +910,31 @@ impl<'tcx> LvalueContext<'tcx> {
|
||||
/// Returns true if this lvalue context represents a use that potentially changes the value.
|
||||
pub fn is_mutating_use(&self) -> bool {
|
||||
match *self {
|
||||
LvalueContext::Store | LvalueContext::Call |
|
||||
LvalueContext::Borrow { kind: BorrowKind::Mut, .. } |
|
||||
LvalueContext::Projection(Mutability::Mut) |
|
||||
LvalueContext::Drop => true,
|
||||
LvalueContext::Inspect |
|
||||
LvalueContext::Borrow { kind: BorrowKind::Shared, .. } |
|
||||
LvalueContext::Borrow { kind: BorrowKind::Unique, .. } |
|
||||
LvalueContext::Projection(Mutability::Not) |
|
||||
LvalueContext::Copy | LvalueContext::Move |
|
||||
LvalueContext::StorageLive | LvalueContext::StorageDead |
|
||||
LvalueContext::Validate => false,
|
||||
PlaceContext::Store | PlaceContext::Call |
|
||||
PlaceContext::Borrow { kind: BorrowKind::Mut, .. } |
|
||||
PlaceContext::Projection(Mutability::Mut) |
|
||||
PlaceContext::Drop => true,
|
||||
PlaceContext::Inspect |
|
||||
PlaceContext::Borrow { kind: BorrowKind::Shared, .. } |
|
||||
PlaceContext::Borrow { kind: BorrowKind::Unique, .. } |
|
||||
PlaceContext::Projection(Mutability::Not) |
|
||||
PlaceContext::Copy | PlaceContext::Move |
|
||||
PlaceContext::StorageLive | PlaceContext::StorageDead |
|
||||
PlaceContext::Validate => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if this lvalue context represents a use that does not change the value.
|
||||
pub fn is_nonmutating_use(&self) -> bool {
|
||||
match *self {
|
||||
LvalueContext::Inspect | LvalueContext::Borrow { kind: BorrowKind::Shared, .. } |
|
||||
LvalueContext::Borrow { kind: BorrowKind::Unique, .. } |
|
||||
LvalueContext::Projection(Mutability::Not) |
|
||||
LvalueContext::Copy | LvalueContext::Move => true,
|
||||
LvalueContext::Borrow { kind: BorrowKind::Mut, .. } | LvalueContext::Store |
|
||||
LvalueContext::Call | LvalueContext::Projection(Mutability::Mut) |
|
||||
LvalueContext::Drop | LvalueContext::StorageLive | LvalueContext::StorageDead |
|
||||
LvalueContext::Validate => false,
|
||||
PlaceContext::Inspect | PlaceContext::Borrow { kind: BorrowKind::Shared, .. } |
|
||||
PlaceContext::Borrow { kind: BorrowKind::Unique, .. } |
|
||||
PlaceContext::Projection(Mutability::Not) |
|
||||
PlaceContext::Copy | PlaceContext::Move => true,
|
||||
PlaceContext::Borrow { kind: BorrowKind::Mut, .. } | PlaceContext::Store |
|
||||
PlaceContext::Call | PlaceContext::Projection(Mutability::Mut) |
|
||||
PlaceContext::Drop | PlaceContext::StorageLive | PlaceContext::StorageDead |
|
||||
PlaceContext::Validate => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ use rustc::hir::def_id::{DefId};
|
||||
use rustc::infer::{InferCtxt};
|
||||
use rustc::ty::{self, TyCtxt, ParamEnv};
|
||||
use rustc::ty::maps::Providers;
|
||||
use rustc::mir::{AssertMessage, BasicBlock, BorrowKind, Location, Lvalue, Local};
|
||||
use rustc::mir::{AssertMessage, BasicBlock, BorrowKind, Location, Place, Local};
|
||||
use rustc::mir::{Mir, Mutability, Operand, Projection, ProjectionElem, Rvalue};
|
||||
use rustc::mir::{Field, Statement, StatementKind, Terminator, TerminatorKind};
|
||||
use transform::nll;
|
||||
@ -300,7 +300,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
|
||||
|
||||
StatementKind::StorageDead(local) => {
|
||||
self.access_lvalue(ContextKind::StorageDead.new(location),
|
||||
(&Lvalue::Local(local), span),
|
||||
(&Place::Local(local), span),
|
||||
(Shallow(None), Write(WriteKind::StorageDeadOrDrop)),
|
||||
LocalMutationIsAllowed::Yes,
|
||||
flow_state);
|
||||
@ -390,7 +390,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
|
||||
PrefixSet::All
|
||||
).last().unwrap();
|
||||
match root_lvalue {
|
||||
Lvalue::Static(_) => {
|
||||
Place::Static(_) => {
|
||||
self.access_lvalue(
|
||||
ContextKind::StorageDead.new(loc),
|
||||
(&root_lvalue, self.mir.source_info(borrow.location).span),
|
||||
@ -399,7 +399,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
|
||||
flow_state
|
||||
);
|
||||
}
|
||||
Lvalue::Local(_) => {
|
||||
Place::Local(_) => {
|
||||
self.access_lvalue(
|
||||
ContextKind::StorageDead.new(loc),
|
||||
(&root_lvalue, self.mir.source_info(borrow.location).span),
|
||||
@ -408,7 +408,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
|
||||
flow_state
|
||||
);
|
||||
}
|
||||
Lvalue::Projection(_) => ()
|
||||
Place::Projection(_) => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -534,14 +534,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
/// Returns true if an error is reported, false otherwise.
|
||||
fn access_lvalue(&mut self,
|
||||
context: Context,
|
||||
lvalue_span: (&Lvalue<'tcx>, Span),
|
||||
lvalue_span: (&Place<'tcx>, Span),
|
||||
kind: (ShallowOrDeep, ReadOrWrite),
|
||||
is_local_mutation_allowed: LocalMutationIsAllowed,
|
||||
flow_state: &InProgress<'cx, 'gcx, 'tcx>) {
|
||||
let (sd, rw) = kind;
|
||||
|
||||
let storage_dead_or_drop_local = match (lvalue_span.0, rw) {
|
||||
(&Lvalue::Local(local), Write(WriteKind::StorageDeadOrDrop)) => Some(local),
|
||||
(&Place::Local(local), Write(WriteKind::StorageDeadOrDrop)) => Some(local),
|
||||
_ => None
|
||||
};
|
||||
|
||||
@ -627,7 +627,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
|
||||
fn mutate_lvalue(&mut self,
|
||||
context: Context,
|
||||
lvalue_span: (&Lvalue<'tcx>, Span),
|
||||
lvalue_span: (&Place<'tcx>, Span),
|
||||
kind: ShallowOrDeep,
|
||||
mode: MutateMode,
|
||||
flow_state: &InProgress<'cx, 'gcx, 'tcx>) {
|
||||
@ -756,7 +756,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
fn check_if_reassignment_to_immutable_state(&mut self,
|
||||
context: Context,
|
||||
(lvalue, span): (&Lvalue<'tcx>, Span),
|
||||
(lvalue, span): (&Place<'tcx>, Span),
|
||||
flow_state: &InProgress<'cx, 'gcx, 'tcx>) {
|
||||
let move_data = self.move_data;
|
||||
|
||||
@ -795,7 +795,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
fn check_if_path_is_moved(&mut self,
|
||||
context: Context,
|
||||
desired_action: InitializationRequiringAction,
|
||||
lvalue_span: (&Lvalue<'tcx>, Span),
|
||||
lvalue_span: (&Place<'tcx>, Span),
|
||||
flow_state: &InProgress<'cx, 'gcx, 'tcx>) {
|
||||
// FIXME: analogous code in check_loans first maps `lvalue` to
|
||||
// its base_path ... but is that what we want here?
|
||||
@ -890,7 +890,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
/// An Err result includes a tag indicated why the search failed.
|
||||
/// Currenly this can only occur if the lvalue is built off of a
|
||||
/// static variable, as we do not track those in the MoveData.
|
||||
fn move_path_closest_to(&mut self, lvalue: &Lvalue<'tcx>)
|
||||
fn move_path_closest_to(&mut self, lvalue: &Place<'tcx>)
|
||||
-> Result<MovePathIndex, NoMovePathFound>
|
||||
{
|
||||
let mut last_prefix = lvalue;
|
||||
@ -901,14 +901,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
last_prefix = prefix;
|
||||
}
|
||||
match *last_prefix {
|
||||
Lvalue::Local(_) => panic!("should have move path for every Local"),
|
||||
Lvalue::Projection(_) => panic!("PrefixSet::All meant dont stop for Projection"),
|
||||
Lvalue::Static(_) => return Err(NoMovePathFound::ReachedStatic),
|
||||
Place::Local(_) => panic!("should have move path for every Local"),
|
||||
Place::Projection(_) => panic!("PrefixSet::All meant dont stop for Projection"),
|
||||
Place::Static(_) => return Err(NoMovePathFound::ReachedStatic),
|
||||
}
|
||||
}
|
||||
|
||||
fn move_path_for_lvalue(&mut self,
|
||||
lvalue: &Lvalue<'tcx>)
|
||||
lvalue: &Place<'tcx>)
|
||||
-> Option<MovePathIndex>
|
||||
{
|
||||
// If returns None, then there is no move path corresponding
|
||||
@ -923,17 +923,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
|
||||
fn check_if_assigned_path_is_moved(&mut self,
|
||||
context: Context,
|
||||
(lvalue, span): (&Lvalue<'tcx>, Span),
|
||||
(lvalue, span): (&Place<'tcx>, Span),
|
||||
flow_state: &InProgress<'cx, 'gcx, 'tcx>) {
|
||||
// recur down lvalue; dispatch to check_if_path_is_moved when necessary
|
||||
let mut lvalue = lvalue;
|
||||
loop {
|
||||
match *lvalue {
|
||||
Lvalue::Local(_) | Lvalue::Static(_) => {
|
||||
Place::Local(_) | Place::Static(_) => {
|
||||
// assigning to `x` does not require `x` be initialized.
|
||||
break;
|
||||
}
|
||||
Lvalue::Projection(ref proj) => {
|
||||
Place::Projection(ref proj) => {
|
||||
let Projection { ref base, ref elem } = **proj;
|
||||
match *elem {
|
||||
ProjectionElem::Deref |
|
||||
@ -988,7 +988,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
///
|
||||
/// Returns true if an error is reported, false otherwise.
|
||||
fn check_access_permissions(&self,
|
||||
(lvalue, span): (&Lvalue<'tcx>, Span),
|
||||
(lvalue, span): (&Place<'tcx>, Span),
|
||||
kind: ReadOrWrite,
|
||||
is_local_mutation_allowed: LocalMutationIsAllowed)
|
||||
-> bool {
|
||||
@ -1068,11 +1068,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
|
||||
/// Can this value be written or borrowed mutably
|
||||
fn is_mutable<'d>(&self,
|
||||
lvalue: &'d Lvalue<'tcx>,
|
||||
lvalue: &'d Place<'tcx>,
|
||||
is_local_mutation_allowed: LocalMutationIsAllowed)
|
||||
-> Result<(), &'d Lvalue<'tcx>> {
|
||||
-> Result<(), &'d Place<'tcx>> {
|
||||
match *lvalue {
|
||||
Lvalue::Local(local) => {
|
||||
Place::Local(local) => {
|
||||
let local = &self.mir.local_decls[local];
|
||||
match local.mutability {
|
||||
Mutability::Not =>
|
||||
@ -1083,14 +1083,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
Mutability::Mut => Ok(())
|
||||
}
|
||||
},
|
||||
Lvalue::Static(ref static_) => {
|
||||
Place::Static(ref static_) => {
|
||||
if !self.tcx.is_static_mut(static_.def_id) {
|
||||
Err(lvalue)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
Lvalue::Projection(ref proj) => {
|
||||
Place::Projection(ref proj) => {
|
||||
match proj.elem {
|
||||
ProjectionElem::Deref => {
|
||||
let base_ty = proj.base.ty(self.mir, self.tcx).to_ty(self.tcx);
|
||||
@ -1154,17 +1154,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
/// Does this lvalue have a unique path
|
||||
fn is_unique<'d>(&self, lvalue: &'d Lvalue<'tcx>) -> Result<(), &'d Lvalue<'tcx>> {
|
||||
fn is_unique<'d>(&self, lvalue: &'d Place<'tcx>) -> Result<(), &'d Place<'tcx>> {
|
||||
match *lvalue {
|
||||
Lvalue::Local(..) => {
|
||||
Place::Local(..) => {
|
||||
// Local variables are unique
|
||||
Ok(())
|
||||
},
|
||||
Lvalue::Static(..) => {
|
||||
Place::Static(..) => {
|
||||
// Static variables are not
|
||||
Err(lvalue)
|
||||
},
|
||||
Lvalue::Projection(ref proj) => {
|
||||
Place::Projection(ref proj) => {
|
||||
match proj.elem {
|
||||
ProjectionElem::Deref => {
|
||||
let base_ty = proj.base.ty(self.mir, self.tcx).to_ty(self.tcx);
|
||||
@ -1217,10 +1217,10 @@ enum NoMovePathFound {
|
||||
impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
fn each_borrow_involving_path<F>(&mut self,
|
||||
_context: Context,
|
||||
access_lvalue: (ShallowOrDeep, &Lvalue<'tcx>),
|
||||
access_lvalue: (ShallowOrDeep, &Place<'tcx>),
|
||||
flow_state: &InProgress<'cx, 'gcx, 'tcx>,
|
||||
mut op: F)
|
||||
where F: FnMut(&mut Self, BorrowIndex, &BorrowData<'tcx>, &Lvalue<'tcx>) -> Control
|
||||
where F: FnMut(&mut Self, BorrowIndex, &BorrowData<'tcx>, &Place<'tcx>) -> Control
|
||||
{
|
||||
let (access, lvalue) = access_lvalue;
|
||||
|
||||
@ -1292,14 +1292,14 @@ mod prefixes {
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::mir::{Lvalue, Mir, ProjectionElem};
|
||||
use rustc::mir::{Place, Mir, ProjectionElem};
|
||||
|
||||
pub trait IsPrefixOf<'tcx> {
|
||||
fn is_prefix_of(&self, other: &Lvalue<'tcx>) -> bool;
|
||||
fn is_prefix_of(&self, other: &Place<'tcx>) -> bool;
|
||||
}
|
||||
|
||||
impl<'tcx> IsPrefixOf<'tcx> for Lvalue<'tcx> {
|
||||
fn is_prefix_of(&self, other: &Lvalue<'tcx>) -> bool {
|
||||
impl<'tcx> IsPrefixOf<'tcx> for Place<'tcx> {
|
||||
fn is_prefix_of(&self, other: &Place<'tcx>) -> bool {
|
||||
let mut cursor = other;
|
||||
loop {
|
||||
if self == cursor {
|
||||
@ -1307,9 +1307,9 @@ mod prefixes {
|
||||
}
|
||||
|
||||
match *cursor {
|
||||
Lvalue::Local(_) |
|
||||
Lvalue::Static(_) => return false,
|
||||
Lvalue::Projection(ref proj) => {
|
||||
Place::Local(_) |
|
||||
Place::Static(_) => return false,
|
||||
Place::Projection(ref proj) => {
|
||||
cursor = &proj.base;
|
||||
}
|
||||
}
|
||||
@ -1322,7 +1322,7 @@ mod prefixes {
|
||||
mir: &'cx Mir<'tcx>,
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
kind: PrefixSet,
|
||||
next: Option<&'cx Lvalue<'tcx>>,
|
||||
next: Option<&'cx Place<'tcx>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
@ -1341,7 +1341,7 @@ mod prefixes {
|
||||
/// (inclusive) from longest to smallest, potentially
|
||||
/// terminating the iteration early based on `kind`.
|
||||
pub(super) fn prefixes(&self,
|
||||
lvalue: &'cx Lvalue<'tcx>,
|
||||
lvalue: &'cx Place<'tcx>,
|
||||
kind: PrefixSet)
|
||||
-> Prefixes<'cx, 'gcx, 'tcx>
|
||||
{
|
||||
@ -1350,7 +1350,7 @@ mod prefixes {
|
||||
}
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> {
|
||||
type Item = &'cx Lvalue<'tcx>;
|
||||
type Item = &'cx Place<'tcx>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let mut cursor = match self.next {
|
||||
None => return None,
|
||||
@ -1364,13 +1364,13 @@ mod prefixes {
|
||||
|
||||
'cursor: loop {
|
||||
let proj = match *cursor {
|
||||
Lvalue::Local(_) | // search yielded this leaf
|
||||
Lvalue::Static(_) => {
|
||||
Place::Local(_) | // search yielded this leaf
|
||||
Place::Static(_) => {
|
||||
self.next = None;
|
||||
return Some(cursor);
|
||||
}
|
||||
|
||||
Lvalue::Projection(ref proj) => proj,
|
||||
Place::Projection(ref proj) => proj,
|
||||
};
|
||||
|
||||
match proj.elem {
|
||||
@ -1447,7 +1447,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
fn report_use_of_moved_or_uninitialized(&mut self,
|
||||
_context: Context,
|
||||
desired_action: InitializationRequiringAction,
|
||||
(lvalue, span): (&Lvalue<'tcx>, Span),
|
||||
(lvalue, span): (&Place<'tcx>, Span),
|
||||
mpi: MovePathIndex,
|
||||
curr_move_out: &IdxSetBuf<MoveOutIndex>) {
|
||||
|
||||
@ -1496,7 +1496,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
|
||||
fn report_move_out_while_borrowed(&mut self,
|
||||
_context: Context,
|
||||
(lvalue, span): (&Lvalue<'tcx>, Span),
|
||||
(lvalue, span): (&Place<'tcx>, Span),
|
||||
borrow: &BorrowData<'tcx>) {
|
||||
let value_msg = match self.describe_lvalue(lvalue) {
|
||||
Some(name) => format!("`{}`", name),
|
||||
@ -1517,7 +1517,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
|
||||
fn report_use_while_mutably_borrowed(&mut self,
|
||||
_context: Context,
|
||||
(lvalue, span): (&Lvalue<'tcx>, Span),
|
||||
(lvalue, span): (&Place<'tcx>, Span),
|
||||
borrow : &BorrowData<'tcx>) {
|
||||
|
||||
let mut err = self.tcx.cannot_use_when_mutably_borrowed(
|
||||
@ -1542,7 +1542,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
use rustc::hir::ExprClosure;
|
||||
use rustc::mir::AggregateKind;
|
||||
|
||||
let local = if let StatementKind::Assign(Lvalue::Local(local), _) =
|
||||
let local = if let StatementKind::Assign(Place::Local(local), _) =
|
||||
self.mir[location.block].statements[location.statement_index].kind
|
||||
{
|
||||
local
|
||||
@ -1571,8 +1571,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
self.tcx.with_freevars(node_id, |freevars| {
|
||||
for (v, lv) in freevars.iter().zip(lvs) {
|
||||
match *lv {
|
||||
Operand::Copy(Lvalue::Local(l)) |
|
||||
Operand::Move(Lvalue::Local(l)) if local == l => {
|
||||
Operand::Copy(Place::Local(l)) |
|
||||
Operand::Move(Place::Local(l)) if local == l => {
|
||||
debug!(
|
||||
"find_closure_span: found captured local {:?}",
|
||||
l
|
||||
@ -1596,8 +1596,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
|
||||
fn report_conflicting_borrow(&mut self,
|
||||
context: Context,
|
||||
common_prefix: &Lvalue<'tcx>,
|
||||
(lvalue, span): (&Lvalue<'tcx>, Span),
|
||||
common_prefix: &Place<'tcx>,
|
||||
(lvalue, span): (&Place<'tcx>, Span),
|
||||
gen_borrow_kind: BorrowKind,
|
||||
issued_borrow: &BorrowData,
|
||||
end_issued_loan_span: Option<Span>) {
|
||||
@ -1667,10 +1667,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
|
||||
fn report_borrowed_value_does_not_live_long_enough(&mut self,
|
||||
_: Context,
|
||||
(lvalue, span): (&Lvalue, Span),
|
||||
(lvalue, span): (&Place, Span),
|
||||
end_span: Option<Span>) {
|
||||
let proper_span = match *lvalue {
|
||||
Lvalue::Local(local) => self.mir.local_decls[local].source_info.span,
|
||||
Place::Local(local) => self.mir.local_decls[local].source_info.span,
|
||||
_ => span
|
||||
};
|
||||
|
||||
@ -1688,7 +1688,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
|
||||
fn report_illegal_mutation_of_borrowed(&mut self,
|
||||
_: Context,
|
||||
(lvalue, span): (&Lvalue<'tcx>, Span),
|
||||
(lvalue, span): (&Place<'tcx>, Span),
|
||||
loan: &BorrowData) {
|
||||
let mut err = self.tcx.cannot_assign_to_borrowed(
|
||||
span,
|
||||
@ -1701,7 +1701,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
|
||||
fn report_illegal_reassignment(&mut self,
|
||||
_context: Context,
|
||||
(lvalue, span): (&Lvalue<'tcx>, Span),
|
||||
(lvalue, span): (&Place<'tcx>, Span),
|
||||
assigned_span: Span) {
|
||||
let mut err = self.tcx.cannot_reassign_immutable(span,
|
||||
&self.describe_lvalue(lvalue).unwrap_or("_".to_owned()),
|
||||
@ -1721,7 +1721,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
// End-user visible description of `lvalue` if one can be found. If the
|
||||
// lvalue is a temporary for instance, None will be returned.
|
||||
fn describe_lvalue(&self, lvalue: &Lvalue<'tcx>) -> Option<String> {
|
||||
fn describe_lvalue(&self, lvalue: &Place<'tcx>) -> Option<String> {
|
||||
let mut buf = String::new();
|
||||
match self.append_lvalue_to_string(lvalue, &mut buf, false) {
|
||||
Ok(()) => Some(buf),
|
||||
@ -1733,9 +1733,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
/// then returns the index of the field being projected. Note that this closure will always
|
||||
/// be `self` in the current MIR, because that is the only time we directly access the fields
|
||||
/// of a closure type.
|
||||
fn is_upvar_field_projection(&self, lvalue: &Lvalue<'tcx>) -> Option<Field> {
|
||||
fn is_upvar_field_projection(&self, lvalue: &Place<'tcx>) -> Option<Field> {
|
||||
match *lvalue {
|
||||
Lvalue::Projection(ref proj) => {
|
||||
Place::Projection(ref proj) => {
|
||||
match proj.elem {
|
||||
ProjectionElem::Field(field, _ty) => {
|
||||
let is_projection_from_ty_closure = proj.base.ty(self.mir, self.tcx)
|
||||
@ -1756,17 +1756,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
|
||||
// Appends end-user visible description of `lvalue` to `buf`.
|
||||
fn append_lvalue_to_string(&self,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
buf: &mut String,
|
||||
mut autoderef: bool) -> Result<(), ()> {
|
||||
match *lvalue {
|
||||
Lvalue::Local(local) => {
|
||||
Place::Local(local) => {
|
||||
self.append_local_to_string(local, buf,)?;
|
||||
}
|
||||
Lvalue::Static(ref static_) => {
|
||||
Place::Static(ref static_) => {
|
||||
buf.push_str(&format!("{}", &self.tcx.item_name(static_.def_id)));
|
||||
}
|
||||
Lvalue::Projection(ref proj) => {
|
||||
Place::Projection(ref proj) => {
|
||||
match proj.elem {
|
||||
ProjectionElem::Deref => {
|
||||
if let Some(field) = self.is_upvar_field_projection(&proj.base) {
|
||||
@ -1841,16 +1841,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
// End-user visible description of the `field`nth field of `base`
|
||||
fn describe_field(&self, base: &Lvalue, field: Field) -> String {
|
||||
fn describe_field(&self, base: &Place, field: Field) -> String {
|
||||
match *base {
|
||||
Lvalue::Local(local) => {
|
||||
Place::Local(local) => {
|
||||
let local = &self.mir.local_decls[local];
|
||||
self.describe_field_from_ty(&local.ty, field)
|
||||
},
|
||||
Lvalue::Static(ref static_) => {
|
||||
Place::Static(ref static_) => {
|
||||
self.describe_field_from_ty(&static_.ty, field)
|
||||
},
|
||||
Lvalue::Projection(ref proj) => {
|
||||
Place::Projection(ref proj) => {
|
||||
match proj.elem {
|
||||
ProjectionElem::Deref =>
|
||||
self.describe_field(&proj.base, field),
|
||||
@ -1923,7 +1923,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
// moves out of a Box. They should be removed when/if we stop
|
||||
// treating Box specially (e.g. when/if DerefMove is added...)
|
||||
|
||||
fn base_path<'d>(&self, lvalue: &'d Lvalue<'tcx>) -> &'d Lvalue<'tcx> {
|
||||
fn base_path<'d>(&self, lvalue: &'d Place<'tcx>) -> &'d Place<'tcx> {
|
||||
//! Returns the base of the leftmost (deepest) dereference of an
|
||||
//! Box in `lvalue`. If there is no dereference of an Box
|
||||
//! in `lvalue`, then it just returns `lvalue` itself.
|
||||
@ -1932,8 +1932,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
let mut deepest = lvalue;
|
||||
loop {
|
||||
let proj = match *cursor {
|
||||
Lvalue::Local(..) | Lvalue::Static(..) => return deepest,
|
||||
Lvalue::Projection(ref proj) => proj,
|
||||
Place::Local(..) | Place::Static(..) => return deepest,
|
||||
Place::Projection(ref proj) => proj,
|
||||
};
|
||||
if proj.elem == ProjectionElem::Deref &&
|
||||
lvalue.ty(self.mir, self.tcx).to_ty(self.tcx).is_box()
|
||||
|
@ -16,7 +16,7 @@ use syntax_pos::Span;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn ast_block(&mut self,
|
||||
destination: &Lvalue<'tcx>,
|
||||
destination: &Place<'tcx>,
|
||||
block: BasicBlock,
|
||||
ast_block: &'tcx hir::Block,
|
||||
source_info: SourceInfo)
|
||||
@ -53,7 +53,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn ast_block_stmts(&mut self,
|
||||
destination: &Lvalue<'tcx>,
|
||||
destination: &Place<'tcx>,
|
||||
mut block: BasicBlock,
|
||||
span: Span,
|
||||
stmts: Vec<StmtRef<'tcx>>,
|
||||
|
@ -61,7 +61,7 @@ impl<'tcx> CFG<'tcx> {
|
||||
pub fn push_assign(&mut self,
|
||||
block: BasicBlock,
|
||||
source_info: SourceInfo,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
rvalue: Rvalue<'tcx>) {
|
||||
self.push(block, Statement {
|
||||
source_info,
|
||||
@ -72,7 +72,7 @@ impl<'tcx> CFG<'tcx> {
|
||||
pub fn push_assign_constant(&mut self,
|
||||
block: BasicBlock,
|
||||
source_info: SourceInfo,
|
||||
temp: &Lvalue<'tcx>,
|
||||
temp: &Place<'tcx>,
|
||||
constant: Constant<'tcx>) {
|
||||
self.push_assign(block, source_info, temp,
|
||||
Rvalue::Use(Operand::Constant(box constant)));
|
||||
@ -81,7 +81,7 @@ impl<'tcx> CFG<'tcx> {
|
||||
pub fn push_assign_unit(&mut self,
|
||||
block: BasicBlock,
|
||||
source_info: SourceInfo,
|
||||
lvalue: &Lvalue<'tcx>) {
|
||||
lvalue: &Place<'tcx>) {
|
||||
self.push_assign(block, source_info, lvalue, Rvalue::Aggregate(
|
||||
box AggregateKind::Tuple, vec![]
|
||||
));
|
||||
|
@ -22,7 +22,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn as_lvalue<M>(&mut self,
|
||||
block: BasicBlock,
|
||||
expr: M)
|
||||
-> BlockAnd<Lvalue<'tcx>>
|
||||
-> BlockAnd<Place<'tcx>>
|
||||
where M: Mirror<'tcx, Output=Expr<'tcx>>
|
||||
{
|
||||
let expr = self.hir.mirror(expr);
|
||||
@ -32,7 +32,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
fn expr_as_lvalue(&mut self,
|
||||
mut block: BasicBlock,
|
||||
expr: Expr<'tcx>)
|
||||
-> BlockAnd<Lvalue<'tcx>> {
|
||||
-> BlockAnd<Place<'tcx>> {
|
||||
debug!("expr_as_lvalue(block={:?}, expr={:?})", block, expr);
|
||||
|
||||
let this = self;
|
||||
@ -70,26 +70,26 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
&len, Rvalue::Len(slice.clone()));
|
||||
this.cfg.push_assign(block, source_info, // lt = idx < len
|
||||
<, Rvalue::BinaryOp(BinOp::Lt,
|
||||
Operand::Copy(Lvalue::Local(idx)),
|
||||
Operand::Copy(Place::Local(idx)),
|
||||
Operand::Copy(len.clone())));
|
||||
|
||||
let msg = AssertMessage::BoundsCheck {
|
||||
len: Operand::Move(len),
|
||||
index: Operand::Copy(Lvalue::Local(idx))
|
||||
index: Operand::Copy(Place::Local(idx))
|
||||
};
|
||||
let success = this.assert(block, Operand::Move(lt), true,
|
||||
msg, expr_span);
|
||||
success.and(slice.index(idx))
|
||||
}
|
||||
ExprKind::SelfRef => {
|
||||
block.and(Lvalue::Local(Local::new(1)))
|
||||
block.and(Place::Local(Local::new(1)))
|
||||
}
|
||||
ExprKind::VarRef { id } => {
|
||||
let index = this.var_indices[&id];
|
||||
block.and(Lvalue::Local(index))
|
||||
block.and(Place::Local(index))
|
||||
}
|
||||
ExprKind::StaticRef { id } => {
|
||||
block.and(Lvalue::Static(Box::new(Static { def_id: id, ty: expr.ty })))
|
||||
block.and(Place::Static(Box::new(Static { def_id: id, ty: expr.ty })))
|
||||
}
|
||||
|
||||
ExprKind::Array { .. } |
|
||||
@ -124,11 +124,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
ExprKind::Call { .. } => {
|
||||
// these are not lvalues, so we need to make a temporary.
|
||||
debug_assert!(match Category::of(&expr.kind) {
|
||||
Some(Category::Lvalue) => false,
|
||||
Some(Category::Place) => false,
|
||||
_ => true,
|
||||
});
|
||||
let temp = unpack!(block = this.as_temp(block, expr.temp_lifetime, expr));
|
||||
block.and(Lvalue::Local(temp))
|
||||
block.and(Place::Local(temp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,11 +70,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
let constant = this.as_constant(expr);
|
||||
block.and(Operand::Constant(box constant))
|
||||
}
|
||||
Category::Lvalue |
|
||||
Category::Place |
|
||||
Category::Rvalue(..) => {
|
||||
let operand =
|
||||
unpack!(block = this.as_temp(block, scope, expr));
|
||||
block.and(Operand::Move(Lvalue::Local(operand)))
|
||||
block.and(Operand::Move(Place::Local(operand)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,16 +108,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
});
|
||||
if let Some(scope) = scope {
|
||||
// schedule a shallow free of that memory, lest we unwind:
|
||||
this.schedule_drop(expr_span, scope, &Lvalue::Local(result), value.ty);
|
||||
this.schedule_drop(expr_span, scope, &Place::Local(result), value.ty);
|
||||
}
|
||||
|
||||
// malloc some memory of suitable type (thus far, uninitialized):
|
||||
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
|
||||
this.cfg.push_assign(block, source_info, &Lvalue::Local(result), box_);
|
||||
this.cfg.push_assign(block, source_info, &Place::Local(result), box_);
|
||||
|
||||
// initialize the box contents:
|
||||
unpack!(block = this.into(&Lvalue::Local(result).deref(), block, value));
|
||||
block.and(Rvalue::Use(Operand::Move(Lvalue::Local(result))))
|
||||
unpack!(block = this.into(&Place::Local(result).deref(), block, value));
|
||||
block.and(Rvalue::Use(Operand::Move(Place::Local(result))))
|
||||
}
|
||||
ExprKind::Cast { source } => {
|
||||
let source = this.hir.mirror(source);
|
||||
|
@ -65,13 +65,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
// semantics of `into`, `as_operand`, `as_rvalue`, and (of
|
||||
// course) `as_temp`.
|
||||
match Category::of(&expr.kind).unwrap() {
|
||||
Category::Lvalue => {
|
||||
Category::Place => {
|
||||
let lvalue = unpack!(block = this.as_lvalue(block, expr));
|
||||
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(lvalue));
|
||||
this.cfg.push_assign(block, source_info, &Lvalue::Local(temp), rvalue);
|
||||
this.cfg.push_assign(block, source_info, &Place::Local(temp), rvalue);
|
||||
}
|
||||
_ => {
|
||||
unpack!(block = this.into(&Lvalue::Local(temp), block, expr));
|
||||
unpack!(block = this.into(&Place::Local(temp), block, expr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
// 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, &Lvalue::Local(temp), expr_ty);
|
||||
this.schedule_drop(expr_span, temp_lifetime, &Place::Local(temp), expr_ty);
|
||||
}
|
||||
|
||||
block.and(temp)
|
||||
|
@ -15,7 +15,7 @@ pub enum Category {
|
||||
// An assignable memory location like `x`, `x.f`, `foo()[3]`, that
|
||||
// sort of thing. Something that could appear on the LHS of an `=`
|
||||
// sign.
|
||||
Lvalue,
|
||||
Place,
|
||||
|
||||
// A literal like `23` or `"foo"`. Does not include constant
|
||||
// expressions like `3 + 5`.
|
||||
@ -51,7 +51,7 @@ impl Category {
|
||||
ExprKind::SelfRef |
|
||||
ExprKind::VarRef { .. } |
|
||||
ExprKind::StaticRef { .. } =>
|
||||
Some(Category::Lvalue),
|
||||
Some(Category::Place),
|
||||
|
||||
ExprKind::LogicalOp { .. } |
|
||||
ExprKind::If { .. } |
|
||||
|
@ -22,7 +22,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
/// Compile `expr`, storing the result into `destination`, which
|
||||
/// is assumed to be uninitialized.
|
||||
pub fn into_expr(&mut self,
|
||||
destination: &Lvalue<'tcx>,
|
||||
destination: &Place<'tcx>,
|
||||
mut block: BasicBlock,
|
||||
expr: Expr<'tcx>)
|
||||
-> BlockAnd<()>
|
||||
@ -241,7 +241,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
internal: true,
|
||||
is_user_variable: false
|
||||
});
|
||||
let ptr_temp = Lvalue::Local(ptr_temp);
|
||||
let ptr_temp = Place::Local(ptr_temp);
|
||||
let block = unpack!(this.into(&ptr_temp, block, ptr));
|
||||
this.into(&ptr_temp.deref(), block, val)
|
||||
} else {
|
||||
|
@ -107,12 +107,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
ExprKind::Return { value } => {
|
||||
block = match value {
|
||||
Some(value) => {
|
||||
unpack!(this.into(&Lvalue::Local(RETURN_POINTER), block, value))
|
||||
unpack!(this.into(&Place::Local(RETURN_POINTER), block, value))
|
||||
}
|
||||
None => {
|
||||
this.cfg.push_assign_unit(block,
|
||||
source_info,
|
||||
&Lvalue::Local(RETURN_POINTER));
|
||||
&Place::Local(RETURN_POINTER));
|
||||
block
|
||||
}
|
||||
};
|
||||
|
@ -21,14 +21,14 @@ use rustc::mir::*;
|
||||
pub(in build) trait EvalInto<'tcx> {
|
||||
fn eval_into<'a, 'gcx>(self,
|
||||
builder: &mut Builder<'a, 'gcx, 'tcx>,
|
||||
destination: &Lvalue<'tcx>,
|
||||
destination: &Place<'tcx>,
|
||||
block: BasicBlock)
|
||||
-> BlockAnd<()>;
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn into<E>(&mut self,
|
||||
destination: &Lvalue<'tcx>,
|
||||
destination: &Place<'tcx>,
|
||||
block: BasicBlock,
|
||||
expr: E)
|
||||
-> BlockAnd<()>
|
||||
@ -41,7 +41,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
impl<'tcx> EvalInto<'tcx> for ExprRef<'tcx> {
|
||||
fn eval_into<'a, 'gcx>(self,
|
||||
builder: &mut Builder<'a, 'gcx, 'tcx>,
|
||||
destination: &Lvalue<'tcx>,
|
||||
destination: &Place<'tcx>,
|
||||
block: BasicBlock)
|
||||
-> BlockAnd<()> {
|
||||
let expr = builder.hir.mirror(self);
|
||||
@ -52,7 +52,7 @@ impl<'tcx> EvalInto<'tcx> for ExprRef<'tcx> {
|
||||
impl<'tcx> EvalInto<'tcx> for Expr<'tcx> {
|
||||
fn eval_into<'a, 'gcx>(self,
|
||||
builder: &mut Builder<'a, 'gcx, 'tcx>,
|
||||
destination: &Lvalue<'tcx>,
|
||||
destination: &Place<'tcx>,
|
||||
block: BasicBlock)
|
||||
-> BlockAnd<()> {
|
||||
builder.into_expr(destination, block, self)
|
||||
|
@ -30,7 +30,7 @@ mod util;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn match_expr(&mut self,
|
||||
destination: &Lvalue<'tcx>,
|
||||
destination: &Place<'tcx>,
|
||||
span: Span,
|
||||
mut block: BasicBlock,
|
||||
discriminant: ExprRef<'tcx>,
|
||||
@ -154,7 +154,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn lvalue_into_pattern(&mut self,
|
||||
mut block: BasicBlock,
|
||||
irrefutable_pat: Pattern<'tcx>,
|
||||
initializer: &Lvalue<'tcx>)
|
||||
initializer: &Place<'tcx>)
|
||||
-> BlockAnd<()> {
|
||||
// create a dummy candidate
|
||||
let mut candidate = Candidate {
|
||||
@ -223,7 +223,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn storage_live_binding(&mut self, block: BasicBlock, var: NodeId, span: Span)
|
||||
-> Lvalue<'tcx>
|
||||
-> Place<'tcx>
|
||||
{
|
||||
let local_id = self.var_indices[&var];
|
||||
let source_info = self.source_info(span);
|
||||
@ -231,7 +231,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
source_info,
|
||||
kind: StatementKind::StorageLive(local_id)
|
||||
});
|
||||
Lvalue::Local(local_id)
|
||||
Place::Local(local_id)
|
||||
}
|
||||
|
||||
pub fn schedule_drop_for_binding(&mut self, var: NodeId, span: Span) {
|
||||
@ -239,7 +239,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
let var_ty = self.local_decls[local_id].ty;
|
||||
let hir_id = self.hir.tcx().hir.node_to_hir_id(var);
|
||||
let region_scope = self.hir.region_scope_tree.var_scope(hir_id.local_id);
|
||||
self.schedule_drop(span, region_scope, &Lvalue::Local(local_id), var_ty);
|
||||
self.schedule_drop(span, region_scope, &Place::Local(local_id), var_ty);
|
||||
}
|
||||
|
||||
pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, f: &mut F)
|
||||
@ -305,7 +305,7 @@ pub struct Candidate<'pat, 'tcx:'pat> {
|
||||
#[derive(Clone, Debug)]
|
||||
struct Binding<'tcx> {
|
||||
span: Span,
|
||||
source: Lvalue<'tcx>,
|
||||
source: Place<'tcx>,
|
||||
name: Name,
|
||||
var_id: NodeId,
|
||||
var_ty: Ty<'tcx>,
|
||||
@ -316,7 +316,7 @@ struct Binding<'tcx> {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MatchPair<'pat, 'tcx:'pat> {
|
||||
// this lvalue...
|
||||
lvalue: Lvalue<'tcx>,
|
||||
lvalue: Place<'tcx>,
|
||||
|
||||
// ... must match this pattern.
|
||||
pattern: &'pat Pattern<'tcx>,
|
||||
|
@ -109,7 +109,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn add_cases_to_switch<'pat>(&mut self,
|
||||
test_lvalue: &Lvalue<'tcx>,
|
||||
test_lvalue: &Place<'tcx>,
|
||||
candidate: &Candidate<'pat, 'tcx>,
|
||||
switch_ty: Ty<'tcx>,
|
||||
options: &mut Vec<&'tcx ty::Const<'tcx>>,
|
||||
@ -150,7 +150,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn add_variants_to_switch<'pat>(&mut self,
|
||||
test_lvalue: &Lvalue<'tcx>,
|
||||
test_lvalue: &Place<'tcx>,
|
||||
candidate: &Candidate<'pat, 'tcx>,
|
||||
variants: &mut BitVector)
|
||||
-> bool
|
||||
@ -177,7 +177,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
/// Generates the code to perform a test.
|
||||
pub fn perform_test(&mut self,
|
||||
block: BasicBlock,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
test: &Test<'tcx>)
|
||||
-> Vec<BasicBlock> {
|
||||
let source_info = self.source_info(test.span);
|
||||
@ -430,7 +430,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
/// not apply to this candidate, but it might be we can get
|
||||
/// tighter match code if we do something a bit different.
|
||||
pub fn sort_candidate<'pat>(&mut self,
|
||||
test_lvalue: &Lvalue<'tcx>,
|
||||
test_lvalue: &Place<'tcx>,
|
||||
test: &Test<'tcx>,
|
||||
candidate: &Candidate<'pat, 'tcx>,
|
||||
resulting_candidates: &mut [Vec<Candidate<'pat, 'tcx>>])
|
||||
|
@ -16,7 +16,7 @@ use std::u32;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn field_match_pairs<'pat>(&mut self,
|
||||
lvalue: Lvalue<'tcx>,
|
||||
lvalue: Place<'tcx>,
|
||||
subpatterns: &'pat [FieldPattern<'tcx>])
|
||||
-> Vec<MatchPair<'pat, 'tcx>> {
|
||||
subpatterns.iter()
|
||||
@ -30,7 +30,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
|
||||
pub fn prefix_slice_suffix<'pat>(&mut self,
|
||||
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
prefix: &'pat [Pattern<'tcx>],
|
||||
opt_slice: Option<&'pat Pattern<'tcx>>,
|
||||
suffix: &'pat [Pattern<'tcx>]) {
|
||||
@ -78,7 +78,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
pub fn new(lvalue: Lvalue<'tcx>, pattern: &'pat Pattern<'tcx>) -> MatchPair<'pat, 'tcx> {
|
||||
pub fn new(lvalue: Place<'tcx>, pattern: &'pat Pattern<'tcx>) -> MatchPair<'pat, 'tcx> {
|
||||
MatchPair {
|
||||
lvalue,
|
||||
pattern,
|
||||
|
@ -27,9 +27,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
///
|
||||
/// NB: **No cleanup is scheduled for this temporary.** You should
|
||||
/// call `schedule_drop` once the temporary is initialized.
|
||||
pub fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Lvalue<'tcx> {
|
||||
pub fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> {
|
||||
let temp = self.local_decls.push(LocalDecl::new_temp(ty, span));
|
||||
let lvalue = Lvalue::Local(temp);
|
||||
let lvalue = Place::Local(temp);
|
||||
debug!("temp: created temp {:?} with type {:?}",
|
||||
lvalue, self.local_decls[temp].ty);
|
||||
lvalue
|
||||
@ -121,7 +121,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
block: BasicBlock,
|
||||
source_info: SourceInfo,
|
||||
value: u64)
|
||||
-> Lvalue<'tcx> {
|
||||
-> Place<'tcx> {
|
||||
let usize_ty = self.hir.usize_ty();
|
||||
let temp = self.temp(usize_ty, source_info.span);
|
||||
self.cfg.push_assign_constant(
|
||||
@ -134,7 +134,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
temp
|
||||
}
|
||||
|
||||
pub fn consume_by_copy_or_move(&self, lvalue: Lvalue<'tcx>) -> Operand<'tcx> {
|
||||
pub fn consume_by_copy_or_move(&self, lvalue: Place<'tcx>) -> Operand<'tcx> {
|
||||
let tcx = self.hir.tcx();
|
||||
let ty = lvalue.ty(&self.local_decls, tcx).to_ty(tcx);
|
||||
if self.hir.type_moves_by_default(ty, DUMMY_SP) {
|
||||
|
@ -309,7 +309,7 @@ struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
/// Maps node ids of variable bindings to the `Local`s created for them.
|
||||
var_indices: NodeMap<Local>,
|
||||
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
|
||||
unit_temp: Option<Lvalue<'tcx>>,
|
||||
unit_temp: Option<Place<'tcx>>,
|
||||
|
||||
/// cached block with the RESUME terminator; this is created
|
||||
/// when first set of cleanups are built.
|
||||
@ -480,7 +480,7 @@ fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
|
||||
|
||||
let mut block = START_BLOCK;
|
||||
let expr = builder.hir.mirror(ast_expr);
|
||||
unpack!(block = builder.into_expr(&Lvalue::Local(RETURN_POINTER), block, expr));
|
||||
unpack!(block = builder.into_expr(&Place::Local(RETURN_POINTER), block, expr));
|
||||
|
||||
let source_info = builder.source_info(span);
|
||||
builder.cfg.terminate(block, source_info, TerminatorKind::Return);
|
||||
@ -599,7 +599,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
for (index, &(ty, pattern)) in arguments.iter().enumerate() {
|
||||
// Function arguments always get the first Local indices after the return pointer
|
||||
let local = Local::new(index + 1);
|
||||
let lvalue = Lvalue::Local(local);
|
||||
let lvalue = Place::Local(local);
|
||||
|
||||
if let Some(pattern) = pattern {
|
||||
let pattern = self.hir.pattern_from_hir(pattern);
|
||||
@ -630,10 +630,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
let body = self.hir.mirror(ast_body);
|
||||
self.into(&Lvalue::Local(RETURN_POINTER), block, body)
|
||||
self.into(&Place::Local(RETURN_POINTER), block, body)
|
||||
}
|
||||
|
||||
fn get_unit_temp(&mut self) -> Lvalue<'tcx> {
|
||||
fn get_unit_temp(&mut self) -> Place<'tcx> {
|
||||
match self.unit_temp {
|
||||
Some(ref tmp) => tmp.clone(),
|
||||
None => {
|
||||
|
@ -142,7 +142,7 @@ struct DropData<'tcx> {
|
||||
span: Span,
|
||||
|
||||
/// lvalue to drop
|
||||
location: Lvalue<'tcx>,
|
||||
location: Place<'tcx>,
|
||||
|
||||
/// Whether this is a full value Drop, or just a StorageDead.
|
||||
kind: DropKind
|
||||
@ -184,7 +184,7 @@ pub struct BreakableScope<'tcx> {
|
||||
pub break_block: BasicBlock,
|
||||
/// The destination of the loop/block expression itself (i.e. where to put the result of a
|
||||
/// `break` expression)
|
||||
pub break_destination: Lvalue<'tcx>,
|
||||
pub break_destination: Place<'tcx>,
|
||||
}
|
||||
|
||||
impl CachedBlock {
|
||||
@ -270,7 +270,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn in_breakable_scope<F, R>(&mut self,
|
||||
loop_block: Option<BasicBlock>,
|
||||
break_block: BasicBlock,
|
||||
break_destination: Lvalue<'tcx>,
|
||||
break_destination: Place<'tcx>,
|
||||
f: F) -> R
|
||||
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> R
|
||||
{
|
||||
@ -613,7 +613,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn schedule_drop(&mut self,
|
||||
span: Span,
|
||||
region_scope: region::Scope,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
lvalue_ty: Ty<'tcx>) {
|
||||
let needs_drop = self.hir.needs_drop(lvalue_ty);
|
||||
let drop_kind = if needs_drop {
|
||||
@ -621,7 +621,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
} else {
|
||||
// Only temps and vars need their storage dead.
|
||||
match *lvalue {
|
||||
Lvalue::Local(index) if index.index() > self.arg_count => DropKind::Storage,
|
||||
Place::Local(index) if index.index() > self.arg_count => DropKind::Storage,
|
||||
_ => return
|
||||
}
|
||||
};
|
||||
@ -748,7 +748,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn build_drop(&mut self,
|
||||
block: BasicBlock,
|
||||
span: Span,
|
||||
location: Lvalue<'tcx>,
|
||||
location: Place<'tcx>,
|
||||
ty: Ty<'tcx>) -> BlockAnd<()> {
|
||||
if !self.hir.needs_drop(ty) {
|
||||
return block.unit();
|
||||
@ -769,7 +769,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn build_drop_and_replace(&mut self,
|
||||
block: BasicBlock,
|
||||
span: Span,
|
||||
location: Lvalue<'tcx>,
|
||||
location: Place<'tcx>,
|
||||
value: Operand<'tcx>) -> BlockAnd<()> {
|
||||
let source_info = self.source_info(span);
|
||||
let next_target = self.cfg.start_new_block();
|
||||
@ -883,7 +883,7 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>,
|
||||
// Drop the storage for both value and storage drops.
|
||||
// Only temps and vars need their storage dead.
|
||||
match drop_data.location {
|
||||
Lvalue::Local(index) if index.index() > arg_count => {
|
||||
Place::Local(index) if index.index() > arg_count => {
|
||||
cfg.push(block, Statement {
|
||||
source_info,
|
||||
kind: StatementKind::StorageDead(index)
|
||||
|
@ -20,12 +20,12 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
|
||||
path: MovePathIndex,
|
||||
mut cond: F)
|
||||
-> Option<MovePathIndex>
|
||||
where F: FnMut(&mir::LvalueProjection<'tcx>) -> bool
|
||||
where F: FnMut(&mir::PlaceProjection<'tcx>) -> bool
|
||||
{
|
||||
let mut next_child = move_data.move_paths[path].first_child;
|
||||
while let Some(child_index) = next_child {
|
||||
match move_data.move_paths[child_index].lvalue {
|
||||
mir::Lvalue::Projection(ref proj) => {
|
||||
mir::Place::Projection(ref proj) => {
|
||||
if cond(proj) {
|
||||
return Some(child_index)
|
||||
}
|
||||
@ -42,12 +42,12 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
|
||||
/// paths (1.) past arrays, slices, and pointers, nor (2.) into a type
|
||||
/// that implements `Drop`.
|
||||
///
|
||||
/// Lvalues behind references or arrays are not tracked by elaboration
|
||||
/// Places behind references or arrays are not tracked by elaboration
|
||||
/// and are always assumed to be initialized when accessible. As
|
||||
/// references and indexes can be reseated, trying to track them can
|
||||
/// only lead to trouble.
|
||||
///
|
||||
/// Lvalues behind ADT's with a Drop impl are not tracked by
|
||||
/// Places behind ADT's with a Drop impl are not tracked by
|
||||
/// elaboration since they can never have a drop-flag state that
|
||||
/// differs from that of the parent with the Drop impl.
|
||||
///
|
||||
@ -58,7 +58,7 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
|
||||
/// FIXME: we have to do something for moving slice patterns.
|
||||
fn lvalue_contents_drop_state_cannot_differ<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
lv: &mir::Lvalue<'tcx>) -> bool {
|
||||
lv: &mir::Place<'tcx>) -> bool {
|
||||
let ty = lv.ty(mir, tcx).to_ty(tcx);
|
||||
match ty.sty {
|
||||
ty::TyArray(..) | ty::TySlice(..) | ty::TyRef(..) | ty::TyRawPtr(..) => {
|
||||
@ -168,7 +168,7 @@ pub(crate) fn drop_flag_effects_for_function_entry<'a, 'gcx, 'tcx, F>(
|
||||
{
|
||||
let move_data = &ctxt.move_data;
|
||||
for arg in mir.args_iter() {
|
||||
let lvalue = mir::Lvalue::Local(arg);
|
||||
let lvalue = mir::Place::Local(arg);
|
||||
let lookup_result = move_data.rev_lookup.find(&lvalue);
|
||||
on_lookup_result_bits(tcx, mir, move_data,
|
||||
lookup_result,
|
||||
|
@ -50,7 +50,7 @@ pub struct BorrowData<'tcx> {
|
||||
pub(crate) location: Location,
|
||||
pub(crate) kind: mir::BorrowKind,
|
||||
pub(crate) region: Region<'tcx>,
|
||||
pub(crate) lvalue: mir::Lvalue<'tcx>,
|
||||
pub(crate) lvalue: mir::Place<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Display for BorrowData<'tcx> {
|
||||
@ -269,7 +269,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
|
||||
_in_out: &mut IdxSet<BorrowIndex>,
|
||||
_call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
_dest_lval: &mir::Lvalue) {
|
||||
_dest_lval: &mir::Place) {
|
||||
// there are no effects on the region scopes from method calls.
|
||||
}
|
||||
}
|
||||
@ -291,9 +291,9 @@ impl<'a, 'gcx, 'tcx> DataflowOperator for Borrows<'a, 'gcx, 'tcx> {
|
||||
fn is_unsafe_lvalue<'a, 'gcx: 'tcx, 'tcx: 'a>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Mir<'tcx>,
|
||||
lvalue: &mir::Lvalue<'tcx>
|
||||
lvalue: &mir::Place<'tcx>
|
||||
) -> bool {
|
||||
use self::mir::Lvalue::*;
|
||||
use self::mir::Place::*;
|
||||
use self::mir::ProjectionElem;
|
||||
|
||||
match *lvalue {
|
||||
|
@ -368,7 +368,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
in_out: &mut IdxSet<MovePathIndex>,
|
||||
_call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
dest_lval: &mir::Lvalue) {
|
||||
dest_lval: &mir::Place) {
|
||||
// when a call returns successfully, that means we need to set
|
||||
// the bits for that dest_lval to 1 (initialized).
|
||||
on_lookup_result_bits(self.tcx, self.mir, self.move_data(),
|
||||
@ -423,7 +423,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
|
||||
in_out: &mut IdxSet<MovePathIndex>,
|
||||
_call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
dest_lval: &mir::Lvalue) {
|
||||
dest_lval: &mir::Place) {
|
||||
// when a call returns successfully, that means we need to set
|
||||
// the bits for that dest_lval to 0 (initialized).
|
||||
on_lookup_result_bits(self.tcx, self.mir, self.move_data(),
|
||||
@ -477,7 +477,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'gcx, 'tcx
|
||||
in_out: &mut IdxSet<MovePathIndex>,
|
||||
_call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
dest_lval: &mir::Lvalue) {
|
||||
dest_lval: &mir::Place) {
|
||||
// when a call returns successfully, that means we need to set
|
||||
// the bits for that dest_lval to 1 (initialized).
|
||||
on_lookup_result_bits(self.tcx, self.mir, self.move_data(),
|
||||
@ -561,7 +561,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
|
||||
in_out: &mut IdxSet<MoveOutIndex>,
|
||||
_call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
dest_lval: &mir::Lvalue) {
|
||||
dest_lval: &mir::Place) {
|
||||
let move_data = self.move_data();
|
||||
let bits_per_block = self.bits_per_block();
|
||||
|
||||
@ -612,7 +612,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
mir::StatementKind::StorageDead(local) => {
|
||||
// End inits for StorageDead, so that an immutable variable can
|
||||
// be reinitialized on the next iteration of the loop.
|
||||
if let LookupResult::Exact(mpi) = rev_lookup.find(&mir::Lvalue::Local(local)) {
|
||||
if let LookupResult::Exact(mpi) = rev_lookup.find(&mir::Place::Local(local)) {
|
||||
debug!("stmt {:?} at loc {:?} clears the ever initialized status of {:?}",
|
||||
stmt, location, &init_path_map[mpi]);
|
||||
for ii in &init_path_map[mpi] {
|
||||
@ -647,7 +647,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
in_out: &mut IdxSet<InitIndex>,
|
||||
call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
_dest_lval: &mir::Lvalue) {
|
||||
_dest_lval: &mir::Place) {
|
||||
let move_data = self.move_data();
|
||||
let bits_per_block = self.bits_per_block();
|
||||
let init_loc_map = &move_data.init_loc_map;
|
||||
|
@ -62,7 +62,7 @@ impl<'a, 'tcx> BitDenotation for MaybeStorageLive<'a, 'tcx> {
|
||||
_in_out: &mut IdxSet<Local>,
|
||||
_call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
_dest_lval: &mir::Lvalue) {
|
||||
_dest_lval: &mir::Place) {
|
||||
// Nothing to do when a call returns successfully
|
||||
}
|
||||
}
|
||||
|
@ -610,7 +610,7 @@ pub trait BitDenotation: DataflowOperator {
|
||||
in_out: &mut IdxSet<Self::Idx>,
|
||||
call_bb: mir::BasicBlock,
|
||||
dest_bb: mir::BasicBlock,
|
||||
dest_lval: &mir::Lvalue);
|
||||
dest_lval: &mir::Place);
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
//! The move-analysis portion of borrowck needs to work in an abstract
|
||||
//! domain of lifted Lvalues. Most of the Lvalue variants fall into a
|
||||
//! domain of lifted Places. Most of the Place variants fall into a
|
||||
//! one-to-one mapping between the concrete and abstract (e.g. a
|
||||
//! field-deref on a local-variable, `x.field`, has the same meaning
|
||||
//! in both domains). Indexed-Projections are the exception: `a[x]`
|
||||
@ -21,7 +21,7 @@
|
||||
//! `a[x]` would still overlap them both. But that is not this
|
||||
//! representation does today.)
|
||||
|
||||
use rustc::mir::{Local, LvalueElem, Operand, ProjectionElem};
|
||||
use rustc::mir::{Local, PlaceElem, Operand, ProjectionElem};
|
||||
use rustc::ty::Ty;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
@ -47,7 +47,7 @@ impl<'tcx> Lift for Ty<'tcx> {
|
||||
type Abstract = AbstractType;
|
||||
fn lift(&self) -> Self::Abstract { AbstractType }
|
||||
}
|
||||
impl<'tcx> Lift for LvalueElem<'tcx> {
|
||||
impl<'tcx> Lift for PlaceElem<'tcx> {
|
||||
type Abstract = AbstractElem<'tcx>;
|
||||
fn lift(&self) -> Self::Abstract {
|
||||
match *self {
|
||||
|
@ -44,7 +44,7 @@ impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
||||
moves: IndexVec::new(),
|
||||
loc_map: LocationMap::new(mir),
|
||||
rev_lookup: MovePathLookup {
|
||||
locals: mir.local_decls.indices().map(Lvalue::Local).map(|v| {
|
||||
locals: mir.local_decls.indices().map(Place::Local).map(|v| {
|
||||
Self::new_move_path(
|
||||
&mut move_paths,
|
||||
&mut path_map,
|
||||
@ -68,7 +68,7 @@ impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
||||
path_map: &mut IndexVec<MovePathIndex, Vec<MoveOutIndex>>,
|
||||
init_path_map: &mut IndexVec<MovePathIndex, Vec<InitIndex>>,
|
||||
parent: Option<MovePathIndex>,
|
||||
lvalue: Lvalue<'tcx>)
|
||||
lvalue: Place<'tcx>)
|
||||
-> MovePathIndex
|
||||
{
|
||||
let move_path = move_paths.push(MovePath {
|
||||
@ -102,31 +102,31 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
/// problematic for borrowck.
|
||||
///
|
||||
/// Maybe we should have separate "borrowck" and "moveck" modes.
|
||||
fn move_path_for(&mut self, lval: &Lvalue<'tcx>)
|
||||
fn move_path_for(&mut self, lval: &Place<'tcx>)
|
||||
-> Result<MovePathIndex, MoveError<'tcx>>
|
||||
{
|
||||
debug!("lookup({:?})", lval);
|
||||
match *lval {
|
||||
Lvalue::Local(local) => Ok(self.builder.data.rev_lookup.locals[local]),
|
||||
Lvalue::Static(..) => {
|
||||
Place::Local(local) => Ok(self.builder.data.rev_lookup.locals[local]),
|
||||
Place::Static(..) => {
|
||||
let span = self.builder.mir.source_info(self.loc).span;
|
||||
Err(MoveError::cannot_move_out_of(span, Static))
|
||||
}
|
||||
Lvalue::Projection(ref proj) => {
|
||||
Place::Projection(ref proj) => {
|
||||
self.move_path_for_projection(lval, proj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_move_path(&mut self, lval: &Lvalue<'tcx>) {
|
||||
fn create_move_path(&mut self, lval: &Place<'tcx>) {
|
||||
// This is an assignment, not a move, so this not being a valid
|
||||
// move path is OK.
|
||||
let _ = self.move_path_for(lval);
|
||||
}
|
||||
|
||||
fn move_path_for_projection(&mut self,
|
||||
lval: &Lvalue<'tcx>,
|
||||
proj: &LvalueProjection<'tcx>)
|
||||
lval: &Place<'tcx>,
|
||||
proj: &PlaceProjection<'tcx>)
|
||||
-> Result<MovePathIndex, MoveError<'tcx>>
|
||||
{
|
||||
let base = try!(self.move_path_for(&proj.base));
|
||||
@ -280,7 +280,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
}
|
||||
StatementKind::StorageLive(_) => {}
|
||||
StatementKind::StorageDead(local) => {
|
||||
self.gather_move(&Lvalue::Local(local));
|
||||
self.gather_move(&Place::Local(local));
|
||||
}
|
||||
StatementKind::SetDiscriminant{ .. } => {
|
||||
span_bug!(stmt.source_info.span,
|
||||
@ -339,7 +339,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
TerminatorKind::Unreachable => { }
|
||||
|
||||
TerminatorKind::Return => {
|
||||
self.gather_move(&Lvalue::Local(RETURN_POINTER));
|
||||
self.gather_move(&Place::Local(RETURN_POINTER));
|
||||
}
|
||||
|
||||
TerminatorKind::Assert { .. } |
|
||||
@ -382,7 +382,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn gather_move(&mut self, lval: &Lvalue<'tcx>) {
|
||||
fn gather_move(&mut self, lval: &Place<'tcx>) {
|
||||
debug!("gather_move({:?}, {:?})", self.loc, lval);
|
||||
|
||||
let path = match self.move_path_for(lval) {
|
||||
@ -401,7 +401,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
self.builder.data.loc_map[self.loc].push(move_out);
|
||||
}
|
||||
|
||||
fn gather_init(&mut self, lval: &Lvalue<'tcx>, kind: InitKind) {
|
||||
fn gather_init(&mut self, lval: &Place<'tcx>, kind: InitKind) {
|
||||
debug!("gather_init({:?}, {:?})", self.loc, lval);
|
||||
|
||||
if let LookupResult::Exact(path) = self.builder.data.rev_lookup.find(lval) {
|
||||
|
@ -94,7 +94,7 @@ pub struct MovePath<'tcx> {
|
||||
pub next_sibling: Option<MovePathIndex>,
|
||||
pub first_child: Option<MovePathIndex>,
|
||||
pub parent: Option<MovePathIndex>,
|
||||
pub lvalue: Lvalue<'tcx>,
|
||||
pub lvalue: Place<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for MovePath<'tcx> {
|
||||
@ -246,11 +246,11 @@ impl<'tcx> MovePathLookup<'tcx> {
|
||||
// alternative will *not* create a MovePath on the fly for an
|
||||
// unknown l-value, but will rather return the nearest available
|
||||
// parent.
|
||||
pub fn find(&self, lval: &Lvalue<'tcx>) -> LookupResult {
|
||||
pub fn find(&self, lval: &Place<'tcx>) -> LookupResult {
|
||||
match *lval {
|
||||
Lvalue::Local(local) => LookupResult::Exact(self.locals[local]),
|
||||
Lvalue::Static(..) => LookupResult::Parent(None),
|
||||
Lvalue::Projection(ref proj) => {
|
||||
Place::Local(local) => LookupResult::Exact(self.locals[local]),
|
||||
Place::Static(..) => LookupResult::Parent(None),
|
||||
Place::Projection(ref proj) => {
|
||||
match self.find(&proj.base) {
|
||||
LookupResult::Exact(base_path) => {
|
||||
match self.projections.get(&(base_path, proj.elem.lift())) {
|
||||
|
@ -216,7 +216,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
tcx,
|
||||
param_env
|
||||
};
|
||||
let dropee = Lvalue::Local(Local::new(1+0)).deref();
|
||||
let dropee = Place::Local(Local::new(1+0)).deref();
|
||||
let resume_block = elaborator.patch.resume_block();
|
||||
elaborate_drops::elaborate_drop(
|
||||
&mut elaborator,
|
||||
@ -381,19 +381,19 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn copy_shim(&mut self) {
|
||||
let rcvr = Lvalue::Local(Local::new(1+0)).deref();
|
||||
let rcvr = Place::Local(Local::new(1+0)).deref();
|
||||
let ret_statement = self.make_statement(
|
||||
StatementKind::Assign(
|
||||
Lvalue::Local(RETURN_POINTER),
|
||||
Place::Local(RETURN_POINTER),
|
||||
Rvalue::Use(Operand::Copy(rcvr))
|
||||
)
|
||||
);
|
||||
self.block(vec![ret_statement], TerminatorKind::Return, false);
|
||||
}
|
||||
|
||||
fn make_lvalue(&mut self, mutability: Mutability, ty: Ty<'tcx>) -> Lvalue<'tcx> {
|
||||
fn make_lvalue(&mut self, mutability: Mutability, ty: Ty<'tcx>) -> Place<'tcx> {
|
||||
let span = self.span;
|
||||
Lvalue::Local(
|
||||
Place::Local(
|
||||
self.local_decls.push(temp_decl(mutability, ty, span))
|
||||
)
|
||||
}
|
||||
@ -401,10 +401,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
fn make_clone_call(
|
||||
&mut self,
|
||||
ty: Ty<'tcx>,
|
||||
rcvr_field: Lvalue<'tcx>,
|
||||
rcvr_field: Place<'tcx>,
|
||||
next: BasicBlock,
|
||||
cleanup: BasicBlock
|
||||
) -> Lvalue<'tcx> {
|
||||
) -> Place<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
|
||||
let substs = Substs::for_item(
|
||||
@ -458,8 +458,8 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
|
||||
fn loop_header(
|
||||
&mut self,
|
||||
beg: Lvalue<'tcx>,
|
||||
end: Lvalue<'tcx>,
|
||||
beg: Place<'tcx>,
|
||||
end: Place<'tcx>,
|
||||
loop_body: BasicBlock,
|
||||
loop_end: BasicBlock,
|
||||
is_cleanup: bool
|
||||
@ -499,7 +499,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
fn array_shim(&mut self, ty: Ty<'tcx>, len: u64) {
|
||||
let tcx = self.tcx;
|
||||
let span = self.span;
|
||||
let rcvr = Lvalue::Local(Local::new(1+0)).deref();
|
||||
let rcvr = Place::Local(Local::new(1+0)).deref();
|
||||
|
||||
let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
|
||||
let end = self.make_lvalue(Mutability::Not, tcx.types.usize);
|
||||
@ -512,7 +512,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
let inits = vec![
|
||||
self.make_statement(
|
||||
StatementKind::Assign(
|
||||
Lvalue::Local(beg),
|
||||
Place::Local(beg),
|
||||
Rvalue::Use(Operand::Constant(self.make_usize(0)))
|
||||
)
|
||||
),
|
||||
@ -530,7 +530,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
// BB #3;
|
||||
// }
|
||||
// BB #4;
|
||||
self.loop_header(Lvalue::Local(beg), end, BasicBlock::new(2), BasicBlock::new(4), false);
|
||||
self.loop_header(Place::Local(beg), end, BasicBlock::new(2), BasicBlock::new(4), false);
|
||||
|
||||
// BB #2
|
||||
// `let cloned = Clone::clone(rcvr[beg])`;
|
||||
@ -552,10 +552,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
),
|
||||
self.make_statement(
|
||||
StatementKind::Assign(
|
||||
Lvalue::Local(beg),
|
||||
Place::Local(beg),
|
||||
Rvalue::BinaryOp(
|
||||
BinOp::Add,
|
||||
Operand::Copy(Lvalue::Local(beg)),
|
||||
Operand::Copy(Place::Local(beg)),
|
||||
Operand::Constant(self.make_usize(1))
|
||||
)
|
||||
)
|
||||
@ -567,7 +567,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
// `return ret;`
|
||||
let ret_statement = self.make_statement(
|
||||
StatementKind::Assign(
|
||||
Lvalue::Local(RETURN_POINTER),
|
||||
Place::Local(RETURN_POINTER),
|
||||
Rvalue::Use(Operand::Move(ret.clone())),
|
||||
)
|
||||
);
|
||||
@ -581,7 +581,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
|
||||
let init = self.make_statement(
|
||||
StatementKind::Assign(
|
||||
Lvalue::Local(beg),
|
||||
Place::Local(beg),
|
||||
Rvalue::Use(Operand::Constant(self.make_usize(0)))
|
||||
)
|
||||
);
|
||||
@ -592,7 +592,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
// BB #8;
|
||||
// }
|
||||
// BB #9;
|
||||
self.loop_header(Lvalue::Local(beg), Lvalue::Local(end),
|
||||
self.loop_header(Place::Local(beg), Place::Local(end),
|
||||
BasicBlock::new(7), BasicBlock::new(9), true);
|
||||
|
||||
// BB #7 (cleanup)
|
||||
@ -608,10 +608,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
// `goto #6;`
|
||||
let statement = self.make_statement(
|
||||
StatementKind::Assign(
|
||||
Lvalue::Local(beg),
|
||||
Place::Local(beg),
|
||||
Rvalue::BinaryOp(
|
||||
BinOp::Add,
|
||||
Operand::Copy(Lvalue::Local(beg)),
|
||||
Operand::Copy(Place::Local(beg)),
|
||||
Operand::Constant(self.make_usize(1))
|
||||
)
|
||||
)
|
||||
@ -628,7 +628,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
_ => bug!("only tuples and closures are accepted"),
|
||||
};
|
||||
|
||||
let rcvr = Lvalue::Local(Local::new(1+0)).deref();
|
||||
let rcvr = Place::Local(Local::new(1+0)).deref();
|
||||
|
||||
let mut returns = Vec::new();
|
||||
for (i, ity) in tys.iter().enumerate() {
|
||||
@ -663,7 +663,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||
// `return kind(returns[0], returns[1], ..., returns[tys.len() - 1]);`
|
||||
let ret_statement = self.make_statement(
|
||||
StatementKind::Assign(
|
||||
Lvalue::Local(RETURN_POINTER),
|
||||
Place::Local(RETURN_POINTER),
|
||||
Rvalue::Aggregate(
|
||||
box kind,
|
||||
returns.into_iter().map(Operand::Move).collect()
|
||||
@ -701,7 +701,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let source_info = SourceInfo { span, scope: ARGUMENT_VISIBILITY_SCOPE };
|
||||
|
||||
let rcvr_arg = Local::new(1+0);
|
||||
let rcvr_l = Lvalue::Local(rcvr_arg);
|
||||
let rcvr_l = Place::Local(rcvr_arg);
|
||||
let mut statements = vec![];
|
||||
|
||||
let rcvr = match rcvr_adjustment {
|
||||
@ -720,11 +720,11 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
statements.push(Statement {
|
||||
source_info,
|
||||
kind: StatementKind::Assign(
|
||||
Lvalue::Local(ref_rcvr),
|
||||
Place::Local(ref_rcvr),
|
||||
Rvalue::Ref(tcx.types.re_erased, BorrowKind::Mut, rcvr_l)
|
||||
)
|
||||
});
|
||||
Operand::Move(Lvalue::Local(ref_rcvr))
|
||||
Operand::Move(Place::Local(ref_rcvr))
|
||||
}
|
||||
};
|
||||
|
||||
@ -749,12 +749,12 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
if let Some(untuple_args) = untuple_args {
|
||||
args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
|
||||
let arg_lv = Lvalue::Local(Local::new(1+1));
|
||||
let arg_lv = Place::Local(Local::new(1+1));
|
||||
Operand::Move(arg_lv.field(Field::new(i), *ity))
|
||||
}));
|
||||
} else {
|
||||
args.extend((1..sig.inputs().len()).map(|i| {
|
||||
Operand::Move(Lvalue::Local(Local::new(1+i)))
|
||||
Operand::Move(Place::Local(Local::new(1+i)))
|
||||
}));
|
||||
}
|
||||
|
||||
@ -771,7 +771,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
block(&mut blocks, statements, TerminatorKind::Call {
|
||||
func: callee,
|
||||
args,
|
||||
destination: Some((Lvalue::Local(RETURN_POINTER),
|
||||
destination: Some((Place::Local(RETURN_POINTER),
|
||||
BasicBlock::new(1))),
|
||||
cleanup: if let Adjustment::RefMut = rcvr_adjustment {
|
||||
Some(BasicBlock::new(3))
|
||||
@ -783,7 +783,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
if let Adjustment::RefMut = rcvr_adjustment {
|
||||
// BB #1 - drop for Self
|
||||
block(&mut blocks, vec![], TerminatorKind::Drop {
|
||||
location: Lvalue::Local(rcvr_arg),
|
||||
location: Place::Local(rcvr_arg),
|
||||
target: BasicBlock::new(2),
|
||||
unwind: None
|
||||
}, false);
|
||||
@ -793,7 +793,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
if let Adjustment::RefMut = rcvr_adjustment {
|
||||
// BB #3 - drop if closure panics
|
||||
block(&mut blocks, vec![], TerminatorKind::Drop {
|
||||
location: Lvalue::Local(rcvr_arg),
|
||||
location: Place::Local(rcvr_arg),
|
||||
target: BasicBlock::new(4),
|
||||
unwind: None
|
||||
}, true);
|
||||
@ -864,11 +864,11 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
|
||||
statements: vec![Statement {
|
||||
source_info,
|
||||
kind: StatementKind::Assign(
|
||||
Lvalue::Local(RETURN_POINTER),
|
||||
Place::Local(RETURN_POINTER),
|
||||
Rvalue::Aggregate(
|
||||
box AggregateKind::Adt(adt_def, variant_no, substs, None),
|
||||
(1..sig.inputs().len()+1).map(|i| {
|
||||
Operand::Move(Lvalue::Local(Local::new(i)))
|
||||
Operand::Move(Place::Local(Local::new(i)))
|
||||
}).collect()
|
||||
)
|
||||
)
|
||||
|
@ -131,10 +131,10 @@ fn add_move_for_packed_drop<'a, 'tcx>(
|
||||
|
||||
patch.add_statement(
|
||||
loc, StatementKind::StorageLive(temp));
|
||||
patch.add_assign(loc, Lvalue::Local(temp),
|
||||
patch.add_assign(loc, Place::Local(temp),
|
||||
Rvalue::Use(Operand::Move(location.clone())));
|
||||
patch.patch_terminator(loc.block, TerminatorKind::Drop {
|
||||
location: Lvalue::Local(temp),
|
||||
location: Place::Local(temp),
|
||||
target: storage_dead_block,
|
||||
unwind
|
||||
});
|
||||
|
@ -24,13 +24,13 @@ pub struct AddValidation;
|
||||
|
||||
/// Determine the "context" of the lval: Mutability and region.
|
||||
fn lval_context<'a, 'tcx, D>(
|
||||
lval: &Lvalue<'tcx>,
|
||||
lval: &Place<'tcx>,
|
||||
local_decls: &D,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>
|
||||
) -> (Option<region::Scope>, hir::Mutability)
|
||||
where D: HasLocalDecls<'tcx>
|
||||
{
|
||||
use rustc::mir::Lvalue::*;
|
||||
use rustc::mir::Place::*;
|
||||
|
||||
match *lval {
|
||||
Local { .. } => (None, hir::MutMutable),
|
||||
@ -199,7 +199,7 @@ impl MirPass for AddValidation {
|
||||
let local_decls = mir.local_decls.clone(); // FIXME: Find a way to get rid of this clone.
|
||||
|
||||
// Convert an lvalue to a validation operand.
|
||||
let lval_to_operand = |lval: Lvalue<'tcx>| -> ValidationOperand<'tcx, Lvalue<'tcx>> {
|
||||
let lval_to_operand = |lval: Place<'tcx>| -> ValidationOperand<'tcx, Place<'tcx>> {
|
||||
let (re, mutbl) = lval_context(&lval, &local_decls, tcx);
|
||||
let ty = lval.ty(&local_decls, tcx).to_ty(tcx);
|
||||
ValidationOperand { lval, ty, re, mutbl }
|
||||
@ -237,14 +237,14 @@ impl MirPass for AddValidation {
|
||||
};
|
||||
// Gather all arguments, skip return value.
|
||||
let operands = mir.local_decls.iter_enumerated().skip(1).take(mir.arg_count)
|
||||
.map(|(local, _)| lval_to_operand(Lvalue::Local(local))).collect();
|
||||
.map(|(local, _)| lval_to_operand(Place::Local(local))).collect();
|
||||
emit_acquire(&mut mir.basic_blocks_mut()[START_BLOCK], source_info, operands);
|
||||
}
|
||||
|
||||
// PART 2
|
||||
// Add ReleaseValid/AcquireValid around function call terminators. We don't use a visitor
|
||||
// because we need to access the block that a Call jumps to.
|
||||
let mut returns : Vec<(SourceInfo, Lvalue<'tcx>, BasicBlock)> = Vec::new();
|
||||
let mut returns : Vec<(SourceInfo, Place<'tcx>, BasicBlock)> = Vec::new();
|
||||
for block_data in mir.basic_blocks_mut() {
|
||||
match block_data.terminator {
|
||||
Some(Terminator { kind: TerminatorKind::Call { ref args, ref destination, .. },
|
||||
@ -332,7 +332,7 @@ impl MirPass for AddValidation {
|
||||
// Do an acquire of the result -- but only what it points to, so add a Deref
|
||||
// projection.
|
||||
let dest_lval = Projection { base: dest_lval, elem: ProjectionElem::Deref };
|
||||
let dest_lval = Lvalue::Projection(Box::new(dest_lval));
|
||||
let dest_lval = Place::Projection(Box::new(dest_lval));
|
||||
let acquire_stmt = Statement {
|
||||
source_info: block_data.statements[i].source_info,
|
||||
kind: StatementKind::Validate(ValidationOp::Acquire,
|
||||
|
@ -17,7 +17,7 @@ use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSAFE};
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::{LvalueContext, Visitor};
|
||||
use rustc::mir::visit::{PlaceContext, Visitor};
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::symbol::Symbol;
|
||||
@ -136,10 +136,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_lvalue(&mut self,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
context: LvalueContext<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
if let LvalueContext::Borrow { .. } = context {
|
||||
if let PlaceContext::Borrow { .. } = context {
|
||||
if util::is_disaligned(self.tcx, self.mir, self.param_env, lvalue) {
|
||||
let source_info = self.source_info;
|
||||
let lint_root =
|
||||
@ -153,11 +153,11 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
match lvalue {
|
||||
&Lvalue::Projection(box Projection {
|
||||
&Place::Projection(box Projection {
|
||||
ref base, ref elem
|
||||
}) => {
|
||||
let old_source_info = self.source_info;
|
||||
if let &Lvalue::Local(local) = base {
|
||||
if let &Place::Local(local) = base {
|
||||
if self.mir.local_decls[local].internal {
|
||||
// Internal locals are used in the `move_val_init` desugaring.
|
||||
// We want to check unsafety against the source info of the
|
||||
@ -172,8 +172,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
}
|
||||
ty::TyAdt(adt, _) => {
|
||||
if adt.is_union() {
|
||||
if context == LvalueContext::Store ||
|
||||
context == LvalueContext::Drop
|
||||
if context == PlaceContext::Store ||
|
||||
context == PlaceContext::Drop
|
||||
{
|
||||
let elem_ty = match elem {
|
||||
&ProjectionElem::Field(_, ty) => ty,
|
||||
@ -198,10 +198,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
}
|
||||
self.source_info = old_source_info;
|
||||
}
|
||||
&Lvalue::Local(..) => {
|
||||
&Place::Local(..) => {
|
||||
// locals are safe
|
||||
}
|
||||
&Lvalue::Static(box Static { def_id, ty: _ }) => {
|
||||
&Place::Static(box Static { def_id, ty: _ }) => {
|
||||
if self.tcx.is_static_mut(def_id) {
|
||||
self.require_unsafe("use of mutable static");
|
||||
} else if self.tcx.is_foreign_item(def_id) {
|
||||
|
@ -30,7 +30,7 @@
|
||||
//! future.
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::mir::{Constant, Local, LocalKind, Location, Lvalue, Mir, Operand, Rvalue, StatementKind};
|
||||
use rustc::mir::{Constant, Local, LocalKind, Location, Place, Mir, Operand, Rvalue, StatementKind};
|
||||
use rustc::mir::visit::MutVisitor;
|
||||
use rustc::ty::TyCtxt;
|
||||
use transform::{MirPass, MirSource};
|
||||
@ -123,7 +123,7 @@ impl MirPass for CopyPropagation {
|
||||
|
||||
// That use of the source must be an assignment.
|
||||
match statement.kind {
|
||||
StatementKind::Assign(Lvalue::Local(local), Rvalue::Use(ref operand)) if
|
||||
StatementKind::Assign(Place::Local(local), Rvalue::Use(ref operand)) if
|
||||
local == dest_local => {
|
||||
let maybe_action = match *operand {
|
||||
Operand::Copy(ref src_lvalue) |
|
||||
@ -173,12 +173,12 @@ fn eliminate_self_assignments<'tcx>(
|
||||
if let Some(stmt) = mir[location.block].statements.get(location.statement_index) {
|
||||
match stmt.kind {
|
||||
StatementKind::Assign(
|
||||
Lvalue::Local(local),
|
||||
Rvalue::Use(Operand::Copy(Lvalue::Local(src_local))),
|
||||
Place::Local(local),
|
||||
Rvalue::Use(Operand::Copy(Place::Local(src_local))),
|
||||
) |
|
||||
StatementKind::Assign(
|
||||
Lvalue::Local(local),
|
||||
Rvalue::Use(Operand::Move(Lvalue::Local(src_local))),
|
||||
Place::Local(local),
|
||||
Rvalue::Use(Operand::Move(Place::Local(src_local))),
|
||||
) if local == dest_local && dest_local == src_local => {}
|
||||
_ => {
|
||||
continue;
|
||||
@ -202,10 +202,10 @@ enum Action<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> Action<'tcx> {
|
||||
fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis, src_lvalue: &Lvalue<'tcx>)
|
||||
fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis, src_lvalue: &Place<'tcx>)
|
||||
-> Option<Action<'tcx>> {
|
||||
// The source must be a local.
|
||||
let src_local = if let Lvalue::Local(local) = *src_lvalue {
|
||||
let src_local = if let Place::Local(local) = *src_lvalue {
|
||||
local
|
||||
} else {
|
||||
debug!(" Can't copy-propagate local: source is not a local");
|
||||
@ -356,8 +356,8 @@ impl<'tcx> MutVisitor<'tcx> for ConstantPropagationVisitor<'tcx> {
|
||||
self.super_operand(operand, location);
|
||||
|
||||
match *operand {
|
||||
Operand::Copy(Lvalue::Local(local)) |
|
||||
Operand::Move(Lvalue::Local(local)) if local == self.dest_local => {}
|
||||
Operand::Copy(Place::Local(local)) |
|
||||
Operand::Move(Place::Local(local)) if local == self.dest_local => {}
|
||||
_ => return,
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ impl MirPass for Deaggregator {
|
||||
let rhs = Rvalue::Use(op.clone());
|
||||
|
||||
let lhs_cast = if adt_def.is_enum() {
|
||||
Lvalue::Projection(Box::new(LvalueProjection {
|
||||
Place::Projection(Box::new(PlaceProjection {
|
||||
base: lhs.clone(),
|
||||
elem: ProjectionElem::Downcast(adt_def, variant),
|
||||
}))
|
||||
@ -76,7 +76,7 @@ impl MirPass for Deaggregator {
|
||||
lhs.clone()
|
||||
};
|
||||
|
||||
let lhs_proj = Lvalue::Projection(Box::new(LvalueProjection {
|
||||
let lhs_proj = Place::Projection(Box::new(PlaceProjection {
|
||||
base: lhs_cast,
|
||||
elem: ProjectionElem::Field(Field::new(i), ty),
|
||||
}));
|
||||
|
@ -322,8 +322,8 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||
});
|
||||
}
|
||||
|
||||
fn drop_flag(&mut self, index: MovePathIndex) -> Option<Lvalue<'tcx>> {
|
||||
self.drop_flags.get(&index).map(|t| Lvalue::Local(*t))
|
||||
fn drop_flag(&mut self, index: MovePathIndex) -> Option<Place<'tcx>> {
|
||||
self.drop_flags.get(&index).map(|t| Place::Local(*t))
|
||||
}
|
||||
|
||||
/// create a patch that elaborates all drops in the input
|
||||
@ -451,7 +451,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||
fn elaborate_replace(
|
||||
&mut self,
|
||||
loc: Location,
|
||||
location: &Lvalue<'tcx>,
|
||||
location: &Place<'tcx>,
|
||||
value: &Operand<'tcx>,
|
||||
target: BasicBlock,
|
||||
unwind: Option<BasicBlock>)
|
||||
@ -538,7 +538,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||
if let Some(&flag) = self.drop_flags.get(&path) {
|
||||
let span = self.patch.source_info_for_location(self.mir, loc).span;
|
||||
let val = self.constant_bool(span, val.value());
|
||||
self.patch.add_assign(loc, Lvalue::Local(flag), val);
|
||||
self.patch.add_assign(loc, Place::Local(flag), val);
|
||||
}
|
||||
}
|
||||
|
||||
@ -547,7 +547,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||
let span = self.patch.source_info_for_location(self.mir, loc).span;
|
||||
let false_ = self.constant_bool(span, false);
|
||||
for flag in self.drop_flags.values() {
|
||||
self.patch.add_assign(loc, Lvalue::Local(*flag), false_.clone());
|
||||
self.patch.add_assign(loc, Place::Local(*flag), false_.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::{LvalueContext, Visitor, MutVisitor};
|
||||
use rustc::mir::visit::{PlaceContext, Visitor, MutVisitor};
|
||||
use rustc::ty::{self, TyCtxt, AdtDef, Ty, GeneratorInterior};
|
||||
use rustc::ty::subst::{Kind, Substs};
|
||||
use util::dump_mir;
|
||||
@ -90,7 +90,7 @@ struct RenameLocalVisitor {
|
||||
impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor {
|
||||
fn visit_local(&mut self,
|
||||
local: &mut Local,
|
||||
_: LvalueContext<'tcx>,
|
||||
_: PlaceContext<'tcx>,
|
||||
_: Location) {
|
||||
if *local == self.from {
|
||||
*local = self.to;
|
||||
@ -103,17 +103,17 @@ struct DerefArgVisitor;
|
||||
impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor {
|
||||
fn visit_local(&mut self,
|
||||
local: &mut Local,
|
||||
_: LvalueContext<'tcx>,
|
||||
_: PlaceContext<'tcx>,
|
||||
_: Location) {
|
||||
assert_ne!(*local, self_arg());
|
||||
}
|
||||
|
||||
fn visit_lvalue(&mut self,
|
||||
lvalue: &mut Lvalue<'tcx>,
|
||||
context: LvalueContext<'tcx>,
|
||||
lvalue: &mut Place<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
if *lvalue == Lvalue::Local(self_arg()) {
|
||||
*lvalue = Lvalue::Projection(Box::new(Projection {
|
||||
if *lvalue == Place::Local(self_arg()) {
|
||||
*lvalue = Place::Projection(Box::new(Projection {
|
||||
base: lvalue.clone(),
|
||||
elem: ProjectionElem::Deref,
|
||||
}));
|
||||
@ -162,14 +162,14 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
|
||||
Rvalue::Aggregate(box adt, vec![val])
|
||||
}
|
||||
|
||||
// Create a Lvalue referencing a generator struct field
|
||||
fn make_field(&self, idx: usize, ty: Ty<'tcx>) -> Lvalue<'tcx> {
|
||||
let base = Lvalue::Local(self_arg());
|
||||
// Create a Place referencing a generator struct field
|
||||
fn make_field(&self, idx: usize, ty: Ty<'tcx>) -> Place<'tcx> {
|
||||
let base = Place::Local(self_arg());
|
||||
let field = Projection {
|
||||
base: base,
|
||||
elem: ProjectionElem::Field(Field::new(idx), ty),
|
||||
};
|
||||
Lvalue::Projection(Box::new(field))
|
||||
Place::Projection(Box::new(field))
|
||||
}
|
||||
|
||||
// Create a statement which changes the generator state
|
||||
@ -195,16 +195,16 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
|
||||
impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
|
||||
fn visit_local(&mut self,
|
||||
local: &mut Local,
|
||||
_: LvalueContext<'tcx>,
|
||||
_: PlaceContext<'tcx>,
|
||||
_: Location) {
|
||||
assert_eq!(self.remap.get(local), None);
|
||||
}
|
||||
|
||||
fn visit_lvalue(&mut self,
|
||||
lvalue: &mut Lvalue<'tcx>,
|
||||
context: LvalueContext<'tcx>,
|
||||
lvalue: &mut Place<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
if let Lvalue::Local(l) = *lvalue {
|
||||
if let Place::Local(l) = *lvalue {
|
||||
// Replace an Local in the remap with a generator struct access
|
||||
if let Some(&(ty, idx)) = self.remap.get(&l) {
|
||||
*lvalue = self.make_field(idx, ty);
|
||||
@ -230,7 +230,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
|
||||
let ret_val = match data.terminator().kind {
|
||||
TerminatorKind::Return => Some((1,
|
||||
None,
|
||||
Operand::Move(Lvalue::Local(self.new_ret_local)),
|
||||
Operand::Move(Place::Local(self.new_ret_local)),
|
||||
None)),
|
||||
TerminatorKind::Yield { ref value, resume, drop } => Some((0,
|
||||
Some(resume),
|
||||
@ -244,7 +244,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
|
||||
// We must assign the value first in case it gets declared dead below
|
||||
data.statements.push(Statement {
|
||||
source_info,
|
||||
kind: StatementKind::Assign(Lvalue::Local(RETURN_POINTER),
|
||||
kind: StatementKind::Assign(Place::Local(RETURN_POINTER),
|
||||
self.make_state(state_idx, v)),
|
||||
});
|
||||
let state = if let Some(resume) = resume { // Yield
|
||||
@ -494,7 +494,7 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
&Terminator {
|
||||
source_info,
|
||||
kind: TerminatorKind::Drop {
|
||||
location: Lvalue::Local(local),
|
||||
location: Place::Local(local),
|
||||
target,
|
||||
unwind
|
||||
}
|
||||
@ -516,7 +516,7 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
elaborate_drop(
|
||||
&mut elaborator,
|
||||
source_info,
|
||||
&Lvalue::Local(gen),
|
||||
&Place::Local(gen),
|
||||
(),
|
||||
target,
|
||||
unwind,
|
||||
@ -691,7 +691,7 @@ fn insert_clean_drop<'a, 'tcx>(mir: &mut Mir<'tcx>) -> BasicBlock {
|
||||
// Create a block to destroy an unresumed generators. This can only destroy upvars.
|
||||
let drop_clean = BasicBlock::new(mir.basic_blocks().len());
|
||||
let term = TerminatorKind::Drop {
|
||||
location: Lvalue::Local(self_arg()),
|
||||
location: Place::Local(self_arg()),
|
||||
target: return_block,
|
||||
unwind: None,
|
||||
};
|
||||
@ -794,7 +794,7 @@ impl MirPass for StateTransform {
|
||||
|
||||
let state_field = mir.upvar_decls.len();
|
||||
|
||||
// Run the transformation which converts Lvalues from Local to generator struct
|
||||
// Run the transformation which converts Places from Local to generator struct
|
||||
// accesses for locals in `remap`.
|
||||
// It also rewrites `return x` and `yield y` as writing a new generator state and returning
|
||||
// GeneratorState::Complete(x) and GeneratorState::Yielded(y) respectively.
|
||||
|
@ -404,12 +404,12 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
|
||||
// If the call is something like `a[*i] = f(i)`, where
|
||||
// `i : &mut usize`, then just duplicating the `a[*i]`
|
||||
// Lvalue could result in two different locations if `f`
|
||||
// Place could result in two different locations if `f`
|
||||
// writes to `i`. To prevent this we need to create a temporary
|
||||
// borrow of the lvalue and pass the destination as `*temp` instead.
|
||||
fn dest_needs_borrow(lval: &Lvalue) -> bool {
|
||||
fn dest_needs_borrow(lval: &Place) -> bool {
|
||||
match *lval {
|
||||
Lvalue::Projection(ref p) => {
|
||||
Place::Projection(ref p) => {
|
||||
match p.elem {
|
||||
ProjectionElem::Deref |
|
||||
ProjectionElem::Index(_) => true,
|
||||
@ -418,7 +418,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
}
|
||||
// Static variables need a borrow because the callee
|
||||
// might modify the same static.
|
||||
Lvalue::Static(_) => true,
|
||||
Place::Static(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
@ -435,7 +435,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
let temp = LocalDecl::new_temp(ty, callsite.location.span);
|
||||
|
||||
let tmp = caller_mir.local_decls.push(temp);
|
||||
let tmp = Lvalue::Local(tmp);
|
||||
let tmp = Place::Local(tmp);
|
||||
|
||||
let stmt = Statement {
|
||||
source_info: callsite.location,
|
||||
@ -508,7 +508,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn cast_box_free_arg(&self, arg: Lvalue<'tcx>, ptr_ty: Ty<'tcx>,
|
||||
fn cast_box_free_arg(&self, arg: Place<'tcx>, ptr_ty: Ty<'tcx>,
|
||||
callsite: &CallSite<'tcx>, caller_mir: &mut Mir<'tcx>) -> Local {
|
||||
let arg = Rvalue::Ref(
|
||||
self.tcx.types.re_erased,
|
||||
@ -518,7 +518,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
let ty = arg.ty(caller_mir, self.tcx);
|
||||
let ref_tmp = LocalDecl::new_temp(ty, callsite.location.span);
|
||||
let ref_tmp = caller_mir.local_decls.push(ref_tmp);
|
||||
let ref_tmp = Lvalue::Local(ref_tmp);
|
||||
let ref_tmp = Place::Local(ref_tmp);
|
||||
|
||||
let ref_stmt = Statement {
|
||||
source_info: callsite.location,
|
||||
@ -542,7 +542,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
|
||||
let cast_stmt = Statement {
|
||||
source_info: callsite.location,
|
||||
kind: StatementKind::Assign(Lvalue::Local(cast_tmp), raw_ptr)
|
||||
kind: StatementKind::Assign(Place::Local(cast_tmp), raw_ptr)
|
||||
};
|
||||
|
||||
caller_mir[callsite.bb]
|
||||
@ -588,7 +588,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_mir);
|
||||
assert!(args.next().is_none());
|
||||
|
||||
let tuple = Lvalue::Local(tuple);
|
||||
let tuple = Place::Local(tuple);
|
||||
let tuple_tys = if let ty::TyTuple(s, _) = tuple.ty(caller_mir, tcx).to_ty(tcx).sty {
|
||||
s
|
||||
} else {
|
||||
@ -627,7 +627,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
// FIXME: Analysis of the usage of the arguments to avoid
|
||||
// unnecessary temporaries.
|
||||
|
||||
if let Operand::Move(Lvalue::Local(local)) = arg {
|
||||
if let Operand::Move(Place::Local(local)) = arg {
|
||||
if caller_mir.local_kind(local) == LocalKind::Temp {
|
||||
// Reuse the operand if it's a temporary already
|
||||
return local;
|
||||
@ -645,7 +645,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
|
||||
let stmt = Statement {
|
||||
source_info: callsite.location,
|
||||
kind: StatementKind::Assign(Lvalue::Local(arg_tmp), arg),
|
||||
kind: StatementKind::Assign(Place::Local(arg_tmp), arg),
|
||||
};
|
||||
caller_mir[callsite.bb].statements.push(stmt);
|
||||
arg_tmp
|
||||
@ -696,7 +696,7 @@ struct Integrator<'a, 'tcx: 'a> {
|
||||
scope_map: IndexVec<VisibilityScope, VisibilityScope>,
|
||||
promoted_map: IndexVec<Promoted, Promoted>,
|
||||
_callsite: CallSite<'tcx>,
|
||||
destination: Lvalue<'tcx>,
|
||||
destination: Place<'tcx>,
|
||||
return_block: BasicBlock,
|
||||
cleanup_block: Option<BasicBlock>,
|
||||
in_cleanup_block: bool,
|
||||
@ -713,11 +713,11 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> {
|
||||
impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
|
||||
fn visit_local(&mut self,
|
||||
local: &mut Local,
|
||||
_ctxt: LvalueContext<'tcx>,
|
||||
_ctxt: PlaceContext<'tcx>,
|
||||
_location: Location) {
|
||||
if *local == RETURN_POINTER {
|
||||
match self.destination {
|
||||
Lvalue::Local(l) => {
|
||||
Place::Local(l) => {
|
||||
*local = l;
|
||||
return;
|
||||
},
|
||||
@ -733,10 +733,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_lvalue(&mut self,
|
||||
lvalue: &mut Lvalue<'tcx>,
|
||||
_ctxt: LvalueContext<'tcx>,
|
||||
lvalue: &mut Place<'tcx>,
|
||||
_ctxt: PlaceContext<'tcx>,
|
||||
_location: Location) {
|
||||
if let Lvalue::Local(RETURN_POINTER) = *lvalue {
|
||||
if let Place::Local(RETURN_POINTER) = *lvalue {
|
||||
// Return pointer; update the lvalue itself
|
||||
*lvalue = self.destination.clone();
|
||||
} else {
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
//! Performs various peephole optimizations.
|
||||
|
||||
use rustc::mir::{Constant, Literal, Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local};
|
||||
use rustc::mir::{Constant, Literal, Location, Place, Mir, Operand, ProjectionElem, Rvalue, Local};
|
||||
use rustc::mir::visit::{MutVisitor, Visitor};
|
||||
use rustc::ty::{TyCtxt, TypeVariants};
|
||||
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
||||
@ -32,7 +32,7 @@ impl MirPass for InstCombine {
|
||||
|
||||
// First, find optimization opportunities. This is done in a pre-pass to keep the MIR
|
||||
// read-only so that we can do global analyses on the MIR in the process (e.g.
|
||||
// `Lvalue::ty()`).
|
||||
// `Place::ty()`).
|
||||
let optimizations = {
|
||||
let mut optimization_finder = OptimizationFinder::new(mir, tcx);
|
||||
optimization_finder.visit_mir(mir);
|
||||
@ -53,9 +53,9 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
|
||||
if self.optimizations.and_stars.remove(&location) {
|
||||
debug!("Replacing `&*`: {:?}", rvalue);
|
||||
let new_lvalue = match *rvalue {
|
||||
Rvalue::Ref(_, _, Lvalue::Projection(ref mut projection)) => {
|
||||
Rvalue::Ref(_, _, Place::Projection(ref mut projection)) => {
|
||||
// Replace with dummy
|
||||
mem::replace(&mut projection.base, Lvalue::Local(Local::new(0)))
|
||||
mem::replace(&mut projection.base, Place::Local(Local::new(0)))
|
||||
}
|
||||
_ => bug!("Detected `&*` but didn't find `&*`!"),
|
||||
};
|
||||
@ -90,7 +90,7 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
|
||||
|
||||
impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> {
|
||||
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
if let Rvalue::Ref(_, _, Lvalue::Projection(ref projection)) = *rvalue {
|
||||
if let Rvalue::Ref(_, _, Place::Projection(ref projection)) = *rvalue {
|
||||
if let ProjectionElem::Deref = projection.elem {
|
||||
if projection.base.ty(self.mir, self.tcx).to_ty(self.tcx).is_region_ptr() {
|
||||
self.optimizations.and_stars.insert(location);
|
||||
|
@ -99,13 +99,13 @@ impl Lower128Bit {
|
||||
block.statements.push(Statement {
|
||||
source_info: source_info,
|
||||
kind: StatementKind::Assign(
|
||||
Lvalue::Local(local),
|
||||
Place::Local(local),
|
||||
Rvalue::Cast(
|
||||
CastKind::Misc,
|
||||
rhs,
|
||||
rhs_override_ty.unwrap())),
|
||||
});
|
||||
rhs = Operand::Move(Lvalue::Local(local));
|
||||
rhs = Operand::Move(Place::Local(local));
|
||||
}
|
||||
|
||||
let call_did = check_lang_item_type(
|
||||
@ -134,7 +134,7 @@ impl Lower128Bit {
|
||||
|
||||
fn check_lang_item_type<'a, 'tcx, D>(
|
||||
lang_item: LangItem,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
lhs: &Operand<'tcx>,
|
||||
rhs: &Operand<'tcx>,
|
||||
local_decls: &D,
|
||||
|
@ -9,10 +9,10 @@
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::mir::{Location, Lvalue, Mir, Rvalue};
|
||||
use rustc::mir::{Location, Place, Mir, Rvalue};
|
||||
use rustc::mir::visit::Visitor;
|
||||
use rustc::mir::Lvalue::Projection;
|
||||
use rustc::mir::{LvalueProjection, ProjectionElem};
|
||||
use rustc::mir::Place::Projection;
|
||||
use rustc::mir::{PlaceProjection, ProjectionElem};
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::traits::{self, ObligationCause};
|
||||
use rustc::ty::{self, Ty};
|
||||
@ -189,10 +189,10 @@ impl<'cx, 'gcx, 'tcx> ConstraintGeneration<'cx, 'gcx, 'tcx> {
|
||||
&mut self,
|
||||
location: Location,
|
||||
borrow_region: ty::Region<'tcx>,
|
||||
borrowed_lv: &Lvalue<'tcx>,
|
||||
borrowed_lv: &Place<'tcx>,
|
||||
) {
|
||||
if let Projection(ref proj) = *borrowed_lv {
|
||||
let LvalueProjection { ref base, ref elem } = **proj;
|
||||
let PlaceProjection { ref base, ref elem } = **proj;
|
||||
|
||||
if let ProjectionElem::Deref = *elem {
|
||||
let tcx = self.infcx.tcx;
|
||||
|
@ -23,7 +23,7 @@
|
||||
//! move analysis runs after promotion on broken MIR.
|
||||
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::{LvalueContext, MutVisitor, Visitor};
|
||||
use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor};
|
||||
use rustc::mir::traversal::ReversePostorder;
|
||||
use rustc::ty::TyCtxt;
|
||||
use syntax_pos::Span;
|
||||
@ -85,7 +85,7 @@ struct TempCollector<'tcx> {
|
||||
impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
|
||||
fn visit_local(&mut self,
|
||||
&index: &Local,
|
||||
context: LvalueContext<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
// We're only interested in temporaries
|
||||
if self.mir.local_kind(index) != LocalKind::Temp {
|
||||
@ -102,8 +102,8 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
|
||||
let temp = &mut self.temps[index];
|
||||
if *temp == TempState::Undefined {
|
||||
match context {
|
||||
LvalueContext::Store |
|
||||
LvalueContext::Call => {
|
||||
PlaceContext::Store |
|
||||
PlaceContext::Call => {
|
||||
*temp = TempState::Defined {
|
||||
location,
|
||||
uses: 0
|
||||
@ -116,7 +116,7 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
|
||||
// We always allow borrows, even mutable ones, as we need
|
||||
// to promote mutable borrows of some ZSTs e.g. `&mut []`.
|
||||
let allowed_use = match context {
|
||||
LvalueContext::Borrow {..} => true,
|
||||
PlaceContext::Borrow {..} => true,
|
||||
_ => context.is_nonmutating_use()
|
||||
};
|
||||
if allowed_use {
|
||||
@ -179,7 +179,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
span,
|
||||
scope: ARGUMENT_VISIBILITY_SCOPE
|
||||
},
|
||||
kind: StatementKind::Assign(Lvalue::Local(dest), rvalue)
|
||||
kind: StatementKind::Assign(Place::Local(dest), rvalue)
|
||||
});
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
func,
|
||||
args,
|
||||
cleanup: None,
|
||||
destination: Some((Lvalue::Local(new_temp), new_target))
|
||||
destination: Some((Place::Local(new_temp), new_target))
|
||||
},
|
||||
..terminator
|
||||
};
|
||||
@ -325,7 +325,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
|
||||
fn visit_local(&mut self,
|
||||
local: &mut Local,
|
||||
_: LvalueContext<'tcx>,
|
||||
_: PlaceContext<'tcx>,
|
||||
_: Location) {
|
||||
if self.source.local_kind(*local) == LocalKind::Temp {
|
||||
*local = self.promote_temp(*local);
|
||||
@ -350,7 +350,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
|
||||
"expected assignment to promote");
|
||||
}
|
||||
};
|
||||
if let Lvalue::Local(index) = *dest {
|
||||
if let Place::Local(index) = *dest {
|
||||
if temps[index] == TempState::PromotedOut {
|
||||
// Already promoted.
|
||||
continue;
|
||||
@ -404,7 +404,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
|
||||
for block in mir.basic_blocks_mut() {
|
||||
block.statements.retain(|statement| {
|
||||
match statement.kind {
|
||||
StatementKind::Assign(Lvalue::Local(index), _) |
|
||||
StatementKind::Assign(Place::Local(index), _) |
|
||||
StatementKind::StorageLive(index) |
|
||||
StatementKind::StorageDead(index) => {
|
||||
!promoted(index)
|
||||
@ -414,7 +414,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
|
||||
});
|
||||
let terminator = block.terminator_mut();
|
||||
match terminator.kind {
|
||||
TerminatorKind::Drop { location: Lvalue::Local(index), target, .. } => {
|
||||
TerminatorKind::Drop { location: Place::Local(index), target, .. } => {
|
||||
if promoted(index) {
|
||||
terminator.kind = TerminatorKind::Goto {
|
||||
target,
|
||||
|
@ -26,7 +26,7 @@ use rustc::ty::cast::CastTy;
|
||||
use rustc::ty::maps::Providers;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::traversal::ReversePostorder;
|
||||
use rustc::mir::visit::{LvalueContext, Visitor};
|
||||
use rustc::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc::middle::lang_items;
|
||||
use syntax::abi::Abi;
|
||||
use syntax::attr;
|
||||
@ -197,7 +197,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
||||
self.add(original);
|
||||
}
|
||||
|
||||
/// Check if an Lvalue with the current qualifications could
|
||||
/// Check if an Place with the current qualifications could
|
||||
/// be consumed, by either an operand or a Deref projection.
|
||||
fn try_consume(&mut self) -> bool {
|
||||
if self.qualif.intersects(Qualif::STATIC) && self.mode != Mode::Fn {
|
||||
@ -224,7 +224,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
||||
}
|
||||
|
||||
/// Assign the current qualification to the given destination.
|
||||
fn assign(&mut self, dest: &Lvalue<'tcx>, location: Location) {
|
||||
fn assign(&mut self, dest: &Place<'tcx>, location: Location) {
|
||||
let qualif = self.qualif;
|
||||
let span = self.span;
|
||||
let store = |slot: &mut Option<Qualif>| {
|
||||
@ -236,7 +236,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
||||
|
||||
// Only handle promotable temps in non-const functions.
|
||||
if self.mode == Mode::Fn {
|
||||
if let Lvalue::Local(index) = *dest {
|
||||
if let Place::Local(index) = *dest {
|
||||
if self.mir.local_kind(index) == LocalKind::Temp
|
||||
&& self.temp_promotion_state[index].is_promotable() {
|
||||
debug!("store to promotable temp {:?}", index);
|
||||
@ -249,24 +249,24 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
||||
// When initializing a local, record whether the *value* being
|
||||
// stored in it needs dropping, which it may not, even if its
|
||||
// type does, e.g. `None::<String>`.
|
||||
if let Lvalue::Local(local) = *dest {
|
||||
if let Place::Local(local) = *dest {
|
||||
if qualif.intersects(Qualif::NEEDS_DROP) {
|
||||
self.local_needs_drop[local] = Some(self.span);
|
||||
}
|
||||
}
|
||||
|
||||
match *dest {
|
||||
Lvalue::Local(index) if self.mir.local_kind(index) == LocalKind::Temp => {
|
||||
Place::Local(index) if self.mir.local_kind(index) == LocalKind::Temp => {
|
||||
debug!("store to temp {:?}", index);
|
||||
store(&mut self.temp_qualif[index])
|
||||
}
|
||||
Lvalue::Local(index) if self.mir.local_kind(index) == LocalKind::ReturnPointer => {
|
||||
Place::Local(index) if self.mir.local_kind(index) == LocalKind::ReturnPointer => {
|
||||
debug!("store to return pointer {:?}", index);
|
||||
store(&mut self.return_qualif)
|
||||
}
|
||||
|
||||
Lvalue::Projection(box Projection {
|
||||
base: Lvalue::Local(index),
|
||||
Place::Projection(box Projection {
|
||||
base: Place::Local(index),
|
||||
elem: ProjectionElem::Deref
|
||||
}) if self.mir.local_kind(index) == LocalKind::Temp
|
||||
&& self.mir.local_decls[index].ty.is_box()
|
||||
@ -280,7 +280,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
||||
// This must be an explicit assignment.
|
||||
_ => {
|
||||
// Catch more errors in the destination.
|
||||
self.visit_lvalue(dest, LvalueContext::Store, location);
|
||||
self.visit_lvalue(dest, PlaceContext::Store, location);
|
||||
self.statement_like();
|
||||
}
|
||||
}
|
||||
@ -351,7 +351,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
||||
for index in mir.vars_iter() {
|
||||
if !self.const_fn_arg_vars.contains(index.index()) {
|
||||
debug!("unassigned variable {:?}", index);
|
||||
self.assign(&Lvalue::Local(index), Location {
|
||||
self.assign(&Place::Local(index), Location {
|
||||
block: bb,
|
||||
statement_index: usize::MAX,
|
||||
});
|
||||
@ -392,7 +392,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
||||
match *candidate {
|
||||
Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
|
||||
match self.mir[bb].statements[stmt_idx].kind {
|
||||
StatementKind::Assign(_, Rvalue::Ref(_, _, Lvalue::Local(index))) => {
|
||||
StatementKind::Assign(_, Rvalue::Ref(_, _, Place::Local(index))) => {
|
||||
promoted_temps.add(&index);
|
||||
}
|
||||
_ => {}
|
||||
@ -412,7 +412,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
||||
impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
||||
fn visit_local(&mut self,
|
||||
&local: &Local,
|
||||
_: LvalueContext<'tcx>,
|
||||
_: PlaceContext<'tcx>,
|
||||
_: Location) {
|
||||
match self.mir.local_kind(local) {
|
||||
LocalKind::ReturnPointer => {
|
||||
@ -439,12 +439,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_lvalue(&mut self,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
context: LvalueContext<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
match *lvalue {
|
||||
Lvalue::Local(ref local) => self.visit_local(local, context, location),
|
||||
Lvalue::Static(ref global) => {
|
||||
Place::Local(ref local) => self.visit_local(local, context, location),
|
||||
Place::Static(ref global) => {
|
||||
self.add(Qualif::STATIC);
|
||||
|
||||
if self.mode != Mode::Fn {
|
||||
@ -465,7 +465,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
||||
a constant instead", self.mode);
|
||||
}
|
||||
}
|
||||
Lvalue::Projection(ref proj) => {
|
||||
Place::Projection(ref proj) => {
|
||||
self.nest(|this| {
|
||||
this.super_lvalue(lvalue, context, location);
|
||||
match proj.elem {
|
||||
@ -527,7 +527,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
||||
});
|
||||
|
||||
// Mark the consumed locals to indicate later drops are noops.
|
||||
if let Lvalue::Local(local) = *lvalue {
|
||||
if let Place::Local(local) = *lvalue {
|
||||
self.local_needs_drop[local] = None;
|
||||
}
|
||||
}
|
||||
@ -635,7 +635,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
||||
let candidate = Candidate::Ref(location);
|
||||
if !self.qualif.intersects(Qualif::NEVER_PROMOTE) {
|
||||
// We can only promote direct borrows of temps.
|
||||
if let Lvalue::Local(local) = *lvalue {
|
||||
if let Place::Local(local) = *lvalue {
|
||||
if self.mir.local_kind(local) == LocalKind::Temp {
|
||||
self.promotion_candidates.push(candidate);
|
||||
}
|
||||
@ -836,7 +836,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
||||
if self.mode != Mode::Fn {
|
||||
// HACK(eddyb) Emulate a bit of dataflow analysis,
|
||||
// conservatively, that drop elaboration will do.
|
||||
let needs_drop = if let Lvalue::Local(local) = *lvalue {
|
||||
let needs_drop = if let Place::Local(local) = *lvalue {
|
||||
self.local_needs_drop[local]
|
||||
} else {
|
||||
None
|
||||
@ -862,20 +862,20 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
||||
|
||||
fn visit_assign(&mut self,
|
||||
_: BasicBlock,
|
||||
dest: &Lvalue<'tcx>,
|
||||
dest: &Place<'tcx>,
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
location: Location) {
|
||||
self.visit_rvalue(rvalue, location);
|
||||
|
||||
// Check the allowed const fn argument forms.
|
||||
if let (Mode::ConstFn, &Lvalue::Local(index)) = (self.mode, dest) {
|
||||
if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) {
|
||||
if self.mir.local_kind(index) == LocalKind::Var &&
|
||||
self.const_fn_arg_vars.insert(index.index()) {
|
||||
|
||||
// Direct use of an argument is permitted.
|
||||
match *rvalue {
|
||||
Rvalue::Use(Operand::Copy(Lvalue::Local(local))) |
|
||||
Rvalue::Use(Operand::Move(Lvalue::Local(local))) => {
|
||||
Rvalue::Use(Operand::Copy(Place::Local(local))) |
|
||||
Rvalue::Use(Operand::Move(Place::Local(local))) => {
|
||||
if self.mir.local_kind(local) == LocalKind::Arg {
|
||||
return;
|
||||
}
|
||||
@ -1030,7 +1030,7 @@ impl MirPass for QualifyAndPromoteConstants {
|
||||
});
|
||||
let terminator = block.terminator_mut();
|
||||
match terminator.kind {
|
||||
TerminatorKind::Drop { location: Lvalue::Local(index), target, .. } => {
|
||||
TerminatorKind::Drop { location: Place::Local(index), target, .. } => {
|
||||
if promoted_temps.contains(&index) {
|
||||
terminator.kind = TerminatorKind::Goto {
|
||||
target,
|
||||
|
@ -124,8 +124,8 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
};
|
||||
assert!(args.len() == 1);
|
||||
let peek_arg_lval = match args[0] {
|
||||
mir::Operand::Copy(ref lval @ mir::Lvalue::Local(_)) |
|
||||
mir::Operand::Move(ref lval @ mir::Lvalue::Local(_)) => Some(lval),
|
||||
mir::Operand::Copy(ref lval @ mir::Place::Local(_)) |
|
||||
mir::Operand::Move(ref lval @ mir::Place::Local(_)) => Some(lval),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
@ -41,7 +41,7 @@ use rustc_data_structures::bitvec::BitVector;
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::{MutVisitor, Visitor, LvalueContext};
|
||||
use rustc::mir::visit::{MutVisitor, Visitor, PlaceContext};
|
||||
use std::borrow::Cow;
|
||||
use transform::{MirPass, MirSource};
|
||||
|
||||
@ -352,9 +352,9 @@ struct DeclMarker {
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for DeclMarker {
|
||||
fn visit_local(&mut self, local: &Local, ctx: LvalueContext<'tcx>, _: Location) {
|
||||
fn visit_local(&mut self, local: &Local, ctx: PlaceContext<'tcx>, _: Location) {
|
||||
// ignore these altogether, they get removed along with their otherwise unused decls.
|
||||
if ctx != LvalueContext::StorageLive && ctx != LvalueContext::StorageDead {
|
||||
if ctx != PlaceContext::StorageLive && ctx != PlaceContext::StorageDead {
|
||||
self.locals.insert(local.index());
|
||||
}
|
||||
}
|
||||
@ -377,7 +377,7 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater {
|
||||
});
|
||||
self.super_basic_block_data(block, data);
|
||||
}
|
||||
fn visit_local(&mut self, l: &mut Local, _: LvalueContext<'tcx>, _: Location) {
|
||||
fn visit_local(&mut self, l: &mut Local, _: PlaceContext<'tcx>, _: Location) {
|
||||
*l = Local::new(self.map[l.index()]);
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::tcx::LvalueTy;
|
||||
use rustc::mir::visit::{LvalueContext, Visitor};
|
||||
use rustc::mir::tcx::PlaceTy;
|
||||
use rustc::mir::visit::{PlaceContext, Visitor};
|
||||
use std::fmt;
|
||||
use syntax::ast;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
@ -106,8 +106,8 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
|
||||
fn visit_lvalue(
|
||||
&mut self,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
context: LvalueContext,
|
||||
lvalue: &Place<'tcx>,
|
||||
context: PlaceContext,
|
||||
location: Location,
|
||||
) {
|
||||
self.sanitize_lvalue(lvalue, location, context);
|
||||
@ -165,16 +165,16 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn sanitize_lvalue(&mut self,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
location: Location,
|
||||
context: LvalueContext)
|
||||
-> LvalueTy<'tcx> {
|
||||
context: PlaceContext)
|
||||
-> PlaceTy<'tcx> {
|
||||
debug!("sanitize_lvalue: {:?}", lvalue);
|
||||
let lvalue_ty = match *lvalue {
|
||||
Lvalue::Local(index) => LvalueTy::Ty {
|
||||
Place::Local(index) => PlaceTy::Ty {
|
||||
ty: self.mir.local_decls[index].ty,
|
||||
},
|
||||
Lvalue::Static(box Static { def_id, ty: sty }) => {
|
||||
Place::Static(box Static { def_id, ty: sty }) => {
|
||||
let sty = self.sanitize_type(lvalue, sty);
|
||||
let ty = self.tcx().type_of(def_id);
|
||||
let ty = self.cx.normalize(&ty, location);
|
||||
@ -190,19 +190,19 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
terr
|
||||
);
|
||||
}
|
||||
LvalueTy::Ty { ty: sty }
|
||||
PlaceTy::Ty { ty: sty }
|
||||
}
|
||||
Lvalue::Projection(ref proj) => {
|
||||
Place::Projection(ref proj) => {
|
||||
let base_context = if context.is_mutating_use() {
|
||||
LvalueContext::Projection(Mutability::Mut)
|
||||
PlaceContext::Projection(Mutability::Mut)
|
||||
} else {
|
||||
LvalueContext::Projection(Mutability::Not)
|
||||
PlaceContext::Projection(Mutability::Not)
|
||||
};
|
||||
let base_ty = self.sanitize_lvalue(&proj.base, location, base_context);
|
||||
if let LvalueTy::Ty { ty } = base_ty {
|
||||
if let PlaceTy::Ty { ty } = base_ty {
|
||||
if ty.references_error() {
|
||||
assert!(self.errors_reported);
|
||||
return LvalueTy::Ty {
|
||||
return PlaceTy::Ty {
|
||||
ty: self.tcx().types.err,
|
||||
};
|
||||
}
|
||||
@ -210,7 +210,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
self.sanitize_projection(base_ty, &proj.elem, lvalue, location)
|
||||
}
|
||||
};
|
||||
if let LvalueContext::Copy = context {
|
||||
if let PlaceContext::Copy = context {
|
||||
let ty = lvalue_ty.to_ty(self.tcx());
|
||||
if self.cx.infcx.type_moves_by_default(self.cx.param_env, ty, DUMMY_SP) {
|
||||
span_mirbug!(self, lvalue,
|
||||
@ -222,11 +222,11 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
|
||||
fn sanitize_projection(
|
||||
&mut self,
|
||||
base: LvalueTy<'tcx>,
|
||||
pi: &LvalueElem<'tcx>,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
base: PlaceTy<'tcx>,
|
||||
pi: &PlaceElem<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
location: Location,
|
||||
) -> LvalueTy<'tcx> {
|
||||
) -> PlaceTy<'tcx> {
|
||||
debug!("sanitize_projection: {:?} {:?} {:?}", base, pi, lvalue);
|
||||
let tcx = self.tcx();
|
||||
let base_ty = base.to_ty(tcx);
|
||||
@ -234,20 +234,20 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
match *pi {
|
||||
ProjectionElem::Deref => {
|
||||
let deref_ty = base_ty.builtin_deref(true, ty::LvaluePreference::NoPreference);
|
||||
LvalueTy::Ty {
|
||||
PlaceTy::Ty {
|
||||
ty: deref_ty.map(|t| t.ty).unwrap_or_else(|| {
|
||||
span_mirbug_and_err!(self, lvalue, "deref of non-pointer {:?}", base_ty)
|
||||
}),
|
||||
}
|
||||
}
|
||||
ProjectionElem::Index(i) => {
|
||||
let index_ty = Lvalue::Local(i).ty(self.mir, tcx).to_ty(tcx);
|
||||
let index_ty = Place::Local(i).ty(self.mir, tcx).to_ty(tcx);
|
||||
if index_ty != tcx.types.usize {
|
||||
LvalueTy::Ty {
|
||||
PlaceTy::Ty {
|
||||
ty: span_mirbug_and_err!(self, i, "index by non-usize {:?}", i),
|
||||
}
|
||||
} else {
|
||||
LvalueTy::Ty {
|
||||
PlaceTy::Ty {
|
||||
ty: base_ty.builtin_index().unwrap_or_else(|| {
|
||||
span_mirbug_and_err!(self, lvalue, "index of non-array {:?}", base_ty)
|
||||
}),
|
||||
@ -256,13 +256,13 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
}
|
||||
ProjectionElem::ConstantIndex { .. } => {
|
||||
// consider verifying in-bounds
|
||||
LvalueTy::Ty {
|
||||
PlaceTy::Ty {
|
||||
ty: base_ty.builtin_index().unwrap_or_else(|| {
|
||||
span_mirbug_and_err!(self, lvalue, "index of non-array {:?}", base_ty)
|
||||
}),
|
||||
}
|
||||
}
|
||||
ProjectionElem::Subslice { from, to } => LvalueTy::Ty {
|
||||
ProjectionElem::Subslice { from, to } => PlaceTy::Ty {
|
||||
ty: match base_ty.sty {
|
||||
ty::TyArray(inner, size) => {
|
||||
let size = size.val.to_const_int().unwrap().to_u64().unwrap();
|
||||
@ -285,7 +285,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
ProjectionElem::Downcast(adt_def1, index) => match base_ty.sty {
|
||||
ty::TyAdt(adt_def, substs) if adt_def.is_enum() && adt_def == adt_def1 => {
|
||||
if index >= adt_def.variants.len() {
|
||||
LvalueTy::Ty {
|
||||
PlaceTy::Ty {
|
||||
ty: span_mirbug_and_err!(
|
||||
self,
|
||||
lvalue,
|
||||
@ -295,14 +295,14 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
),
|
||||
}
|
||||
} else {
|
||||
LvalueTy::Downcast {
|
||||
PlaceTy::Downcast {
|
||||
adt_def,
|
||||
substs,
|
||||
variant_index: index,
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => LvalueTy::Ty {
|
||||
_ => PlaceTy::Ty {
|
||||
ty: span_mirbug_and_err!(
|
||||
self,
|
||||
lvalue,
|
||||
@ -335,7 +335,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
field_count
|
||||
),
|
||||
}
|
||||
LvalueTy::Ty { ty: fty }
|
||||
PlaceTy::Ty { ty: fty }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -348,19 +348,19 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
fn field_ty(
|
||||
&mut self,
|
||||
parent: &fmt::Debug,
|
||||
base_ty: LvalueTy<'tcx>,
|
||||
base_ty: PlaceTy<'tcx>,
|
||||
field: Field,
|
||||
location: Location,
|
||||
) -> Result<Ty<'tcx>, FieldAccessError> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
let (variant, substs) = match base_ty {
|
||||
LvalueTy::Downcast {
|
||||
PlaceTy::Downcast {
|
||||
adt_def,
|
||||
substs,
|
||||
variant_index,
|
||||
} => (&adt_def.variants[variant_index], substs),
|
||||
LvalueTy::Ty { ty } => match ty.sty {
|
||||
PlaceTy::Ty { ty } => match ty.sty {
|
||||
ty::TyAdt(adt_def, substs) if !adt_def.is_enum() => {
|
||||
(&adt_def.variants[0], substs)
|
||||
}
|
||||
@ -771,7 +771,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
mir: &Mir<'tcx>,
|
||||
term: &Terminator<'tcx>,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
destination: &Option<(Lvalue<'tcx>, BasicBlock)>,
|
||||
destination: &Option<(Place<'tcx>, BasicBlock)>,
|
||||
term_location: Location,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
|
@ -18,7 +18,7 @@ use rustc::mir::*;
|
||||
pub fn is_disaligned<'a, 'tcx, L>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
local_decls: &L,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
lvalue: &Lvalue<'tcx>)
|
||||
lvalue: &Place<'tcx>)
|
||||
-> bool
|
||||
where L: HasLocalDecls<'tcx>
|
||||
{
|
||||
@ -45,12 +45,12 @@ pub fn is_disaligned<'a, 'tcx, L>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
fn is_within_packed<'a, 'tcx, L>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
local_decls: &L,
|
||||
lvalue: &Lvalue<'tcx>)
|
||||
lvalue: &Place<'tcx>)
|
||||
-> bool
|
||||
where L: HasLocalDecls<'tcx>
|
||||
{
|
||||
let mut lvalue = lvalue;
|
||||
while let &Lvalue::Projection(box Projection {
|
||||
while let &Place::Projection(box Projection {
|
||||
ref base, ref elem
|
||||
}) = lvalue {
|
||||
match *elem {
|
||||
|
@ -11,7 +11,7 @@
|
||||
//! Def-use analysis.
|
||||
|
||||
use rustc::mir::{Local, Location, Mir};
|
||||
use rustc::mir::visit::{LvalueContext, MutVisitor, Visitor};
|
||||
use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor};
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
@ -29,7 +29,7 @@ pub struct Info<'tcx> {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Use<'tcx> {
|
||||
pub context: LvalueContext<'tcx>,
|
||||
pub context: PlaceContext<'tcx>,
|
||||
pub location: Location,
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ impl<'tcx> DefUseAnalysis<'tcx> {
|
||||
|
||||
fn mutate_defs_and_uses<F>(&self, local: Local, mir: &mut Mir<'tcx>, mut callback: F)
|
||||
where F: for<'a> FnMut(&'a mut Local,
|
||||
LvalueContext<'tcx>,
|
||||
PlaceContext<'tcx>,
|
||||
Location) {
|
||||
for lvalue_use in &self.info[local].defs_and_uses {
|
||||
MutateUseVisitor::new(local,
|
||||
@ -87,7 +87,7 @@ struct DefUseFinder<'tcx> {
|
||||
impl<'tcx> Visitor<'tcx> for DefUseFinder<'tcx> {
|
||||
fn visit_local(&mut self,
|
||||
&local: &Local,
|
||||
context: LvalueContext<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
self.info[local].defs_and_uses.push(Use {
|
||||
context,
|
||||
@ -139,7 +139,7 @@ struct MutateUseVisitor<'tcx, F> {
|
||||
impl<'tcx, F> MutateUseVisitor<'tcx, F> {
|
||||
fn new(query: Local, callback: F, _: &Mir<'tcx>)
|
||||
-> MutateUseVisitor<'tcx, F>
|
||||
where F: for<'a> FnMut(&'a mut Local, LvalueContext<'tcx>, Location) {
|
||||
where F: for<'a> FnMut(&'a mut Local, PlaceContext<'tcx>, Location) {
|
||||
MutateUseVisitor {
|
||||
query,
|
||||
callback,
|
||||
@ -149,10 +149,10 @@ impl<'tcx, F> MutateUseVisitor<'tcx, F> {
|
||||
}
|
||||
|
||||
impl<'tcx, F> MutVisitor<'tcx> for MutateUseVisitor<'tcx, F>
|
||||
where F: for<'a> FnMut(&'a mut Local, LvalueContext<'tcx>, Location) {
|
||||
where F: for<'a> FnMut(&'a mut Local, PlaceContext<'tcx>, Location) {
|
||||
fn visit_local(&mut self,
|
||||
local: &mut Local,
|
||||
context: LvalueContext<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
if *local == self.query {
|
||||
(self.callback)(local, context, location)
|
||||
|
@ -105,7 +105,7 @@ struct DropCtxt<'l, 'b: 'l, 'tcx: 'b, D>
|
||||
|
||||
source_info: SourceInfo,
|
||||
|
||||
lvalue: &'l Lvalue<'tcx>,
|
||||
lvalue: &'l Place<'tcx>,
|
||||
path: D::Path,
|
||||
succ: BasicBlock,
|
||||
unwind: Unwind,
|
||||
@ -114,7 +114,7 @@ struct DropCtxt<'l, 'b: 'l, 'tcx: 'b, D>
|
||||
pub fn elaborate_drop<'b, 'tcx, D>(
|
||||
elaborator: &mut D,
|
||||
source_info: SourceInfo,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
path: D::Path,
|
||||
succ: BasicBlock,
|
||||
unwind: Unwind,
|
||||
@ -129,7 +129,7 @@ pub fn elaborate_drop<'b, 'tcx, D>(
|
||||
impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
where D: DropElaborator<'b, 'tcx>
|
||||
{
|
||||
fn lvalue_ty(&self, lvalue: &Lvalue<'tcx>) -> Ty<'tcx> {
|
||||
fn lvalue_ty(&self, lvalue: &Place<'tcx>) -> Ty<'tcx> {
|
||||
lvalue.ty(self.elaborator.mir(), self.tcx()).to_ty(self.tcx())
|
||||
}
|
||||
|
||||
@ -194,11 +194,11 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
/// Return the lvalue and move path for each field of `variant`,
|
||||
/// (the move path is `None` if the field is a rest field).
|
||||
fn move_paths_for_fields(&self,
|
||||
base_lv: &Lvalue<'tcx>,
|
||||
base_lv: &Place<'tcx>,
|
||||
variant_path: D::Path,
|
||||
variant: &'tcx ty::VariantDef,
|
||||
substs: &'tcx Substs<'tcx>)
|
||||
-> Vec<(Lvalue<'tcx>, Option<D::Path>)>
|
||||
-> Vec<(Place<'tcx>, Option<D::Path>)>
|
||||
{
|
||||
variant.fields.iter().enumerate().map(|(i, f)| {
|
||||
let field = Field::new(i);
|
||||
@ -214,7 +214,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
}
|
||||
|
||||
fn drop_subpath(&mut self,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
path: Option<D::Path>,
|
||||
succ: BasicBlock,
|
||||
unwind: Unwind)
|
||||
@ -251,7 +251,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
fn drop_halfladder(&mut self,
|
||||
unwind_ladder: &[Unwind],
|
||||
mut succ: BasicBlock,
|
||||
fields: &[(Lvalue<'tcx>, Option<D::Path>)])
|
||||
fields: &[(Place<'tcx>, Option<D::Path>)])
|
||||
-> Vec<BasicBlock>
|
||||
{
|
||||
Some(succ).into_iter().chain(
|
||||
@ -294,7 +294,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
/// NOTE: this does not clear the master drop flag, so you need
|
||||
/// to point succ/unwind on a `drop_ladder_bottom`.
|
||||
fn drop_ladder<'a>(&mut self,
|
||||
fields: Vec<(Lvalue<'tcx>, Option<D::Path>)>,
|
||||
fields: Vec<(Place<'tcx>, Option<D::Path>)>,
|
||||
succ: BasicBlock,
|
||||
unwind: Unwind)
|
||||
-> (BasicBlock, Unwind)
|
||||
@ -491,7 +491,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
// discriminant after it is free-ed, because that
|
||||
// way lies only trouble.
|
||||
let discr_ty = adt.repr.discr_type().to_ty(self.tcx());
|
||||
let discr = Lvalue::Local(self.new_temp(discr_ty));
|
||||
let discr = Place::Local(self.new_temp(discr_ty));
|
||||
let discr_rv = Rvalue::Discriminant(self.lvalue.clone());
|
||||
let switch_block = BasicBlockData {
|
||||
statements: vec![self.assign(&discr, discr_rv)],
|
||||
@ -525,18 +525,18 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
mutbl: hir::Mutability::MutMutable
|
||||
});
|
||||
let ref_lvalue = self.new_temp(ref_ty);
|
||||
let unit_temp = Lvalue::Local(self.new_temp(tcx.mk_nil()));
|
||||
let unit_temp = Place::Local(self.new_temp(tcx.mk_nil()));
|
||||
|
||||
let result = BasicBlockData {
|
||||
statements: vec![self.assign(
|
||||
&Lvalue::Local(ref_lvalue),
|
||||
&Place::Local(ref_lvalue),
|
||||
Rvalue::Ref(tcx.types.re_erased, BorrowKind::Mut, self.lvalue.clone())
|
||||
)],
|
||||
terminator: Some(Terminator {
|
||||
kind: TerminatorKind::Call {
|
||||
func: Operand::function_handle(tcx, drop_fn.def_id, substs,
|
||||
self.source_info.span),
|
||||
args: vec![Operand::Move(Lvalue::Local(ref_lvalue))],
|
||||
args: vec![Operand::Move(Place::Local(ref_lvalue))],
|
||||
destination: Some((unit_temp, succ)),
|
||||
cleanup: unwind.into_option(),
|
||||
},
|
||||
@ -566,39 +566,39 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
fn drop_loop(&mut self,
|
||||
succ: BasicBlock,
|
||||
cur: Local,
|
||||
length_or_end: &Lvalue<'tcx>,
|
||||
length_or_end: &Place<'tcx>,
|
||||
ety: Ty<'tcx>,
|
||||
unwind: Unwind,
|
||||
ptr_based: bool)
|
||||
-> BasicBlock
|
||||
{
|
||||
let copy = |lv: &Lvalue<'tcx>| Operand::Copy(lv.clone());
|
||||
let move_ = |lv: &Lvalue<'tcx>| Operand::Move(lv.clone());
|
||||
let copy = |lv: &Place<'tcx>| Operand::Copy(lv.clone());
|
||||
let move_ = |lv: &Place<'tcx>| Operand::Move(lv.clone());
|
||||
let tcx = self.tcx();
|
||||
|
||||
let ref_ty = tcx.mk_ref(tcx.types.re_erased, ty::TypeAndMut {
|
||||
ty: ety,
|
||||
mutbl: hir::Mutability::MutMutable
|
||||
});
|
||||
let ptr = &Lvalue::Local(self.new_temp(ref_ty));
|
||||
let can_go = &Lvalue::Local(self.new_temp(tcx.types.bool));
|
||||
let ptr = &Place::Local(self.new_temp(ref_ty));
|
||||
let can_go = &Place::Local(self.new_temp(tcx.types.bool));
|
||||
|
||||
let one = self.constant_usize(1);
|
||||
let (ptr_next, cur_next) = if ptr_based {
|
||||
(Rvalue::Use(copy(&Lvalue::Local(cur))),
|
||||
Rvalue::BinaryOp(BinOp::Offset, copy(&Lvalue::Local(cur)), one))
|
||||
(Rvalue::Use(copy(&Place::Local(cur))),
|
||||
Rvalue::BinaryOp(BinOp::Offset, copy(&Place::Local(cur)), one))
|
||||
} else {
|
||||
(Rvalue::Ref(
|
||||
tcx.types.re_erased,
|
||||
BorrowKind::Mut,
|
||||
self.lvalue.clone().index(cur)),
|
||||
Rvalue::BinaryOp(BinOp::Add, copy(&Lvalue::Local(cur)), one))
|
||||
Rvalue::BinaryOp(BinOp::Add, copy(&Place::Local(cur)), one))
|
||||
};
|
||||
|
||||
let drop_block = BasicBlockData {
|
||||
statements: vec![
|
||||
self.assign(ptr, ptr_next),
|
||||
self.assign(&Lvalue::Local(cur), cur_next)
|
||||
self.assign(&Place::Local(cur), cur_next)
|
||||
],
|
||||
is_cleanup: unwind.is_cleanup(),
|
||||
terminator: Some(Terminator {
|
||||
@ -612,7 +612,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
let loop_block = BasicBlockData {
|
||||
statements: vec![
|
||||
self.assign(can_go, Rvalue::BinaryOp(BinOp::Eq,
|
||||
copy(&Lvalue::Local(cur)),
|
||||
copy(&Place::Local(cur)),
|
||||
copy(length_or_end)))
|
||||
],
|
||||
is_cleanup: unwind.is_cleanup(),
|
||||
@ -643,9 +643,9 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
|
||||
let tcx = self.tcx();
|
||||
|
||||
let move_ = |lv: &Lvalue<'tcx>| Operand::Move(lv.clone());
|
||||
let size = &Lvalue::Local(self.new_temp(tcx.types.usize));
|
||||
let size_is_zero = &Lvalue::Local(self.new_temp(tcx.types.bool));
|
||||
let move_ = |lv: &Place<'tcx>| Operand::Move(lv.clone());
|
||||
let size = &Place::Local(self.new_temp(tcx.types.usize));
|
||||
let size_is_zero = &Place::Local(self.new_temp(tcx.types.bool));
|
||||
let base_block = BasicBlockData {
|
||||
statements: vec![
|
||||
self.assign(size, Rvalue::NullaryOp(NullOp::SizeOf, ety)),
|
||||
@ -680,9 +680,9 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
};
|
||||
|
||||
let cur = self.new_temp(iter_ty);
|
||||
let length = Lvalue::Local(self.new_temp(tcx.types.usize));
|
||||
let length = Place::Local(self.new_temp(tcx.types.usize));
|
||||
let length_or_end = if ptr_based {
|
||||
Lvalue::Local(self.new_temp(iter_ty))
|
||||
Place::Local(self.new_temp(iter_ty))
|
||||
} else {
|
||||
length.clone()
|
||||
};
|
||||
@ -705,13 +705,13 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
unwind,
|
||||
ptr_based);
|
||||
|
||||
let cur = Lvalue::Local(cur);
|
||||
let cur = Place::Local(cur);
|
||||
let zero = self.constant_usize(0);
|
||||
let mut drop_block_stmts = vec![];
|
||||
drop_block_stmts.push(self.assign(&length, Rvalue::Len(self.lvalue.clone())));
|
||||
if ptr_based {
|
||||
let tmp_ty = tcx.mk_mut_ptr(self.lvalue_ty(self.lvalue));
|
||||
let tmp = Lvalue::Local(self.new_temp(tmp_ty));
|
||||
let tmp = Place::Local(self.new_temp(tmp_ty));
|
||||
// tmp = &LV;
|
||||
// cur = tmp as *mut T;
|
||||
// end = Offset(cur, len);
|
||||
@ -849,7 +849,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
unwind: Unwind
|
||||
) -> BasicBlock {
|
||||
let tcx = self.tcx();
|
||||
let unit_temp = Lvalue::Local(self.new_temp(tcx.mk_nil()));
|
||||
let unit_temp = Place::Local(self.new_temp(tcx.mk_nil()));
|
||||
let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem);
|
||||
let substs = tcx.mk_substs(iter::once(Kind::from(ty)));
|
||||
|
||||
@ -932,7 +932,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
})
|
||||
}
|
||||
|
||||
fn assign(&self, lhs: &Lvalue<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
|
||||
fn assign(&self, lhs: &Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
|
||||
Statement {
|
||||
source_info: self.source_info,
|
||||
kind: StatementKind::Assign(lhs.clone(), rhs)
|
||||
|
@ -147,7 +147,7 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
if i > 0 {
|
||||
write!(w, ", ")?;
|
||||
}
|
||||
write!(w, "{:?}: {}", Lvalue::Local(arg), escape(&mir.local_decls[arg].ty))?;
|
||||
write!(w, "{:?}: {}", Place::Local(arg), escape(&mir.local_decls[arg].ty))?;
|
||||
}
|
||||
|
||||
write!(w, ") -> {}", escape(mir.return_ty()))?;
|
||||
@ -163,10 +163,10 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
|
||||
if let Some(name) = decl.name {
|
||||
write!(w, r#"{:?}: {}; // {}<br align="left"/>"#,
|
||||
Lvalue::Local(local), escape(&decl.ty), name)?;
|
||||
Place::Local(local), escape(&decl.ty), name)?;
|
||||
} else {
|
||||
write!(w, r#"let mut {:?}: {};<br align="left"/>"#,
|
||||
Lvalue::Local(local), escape(&decl.ty))?;
|
||||
Place::Local(local), escape(&decl.ty))?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
//! doesn't matter).
|
||||
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::{LvalueContext, Visitor};
|
||||
use rustc::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc_data_structures::indexed_set::IdxSetBuf;
|
||||
use util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
|
||||
@ -233,12 +233,12 @@ impl DefsUses {
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
|
||||
fn visit_local(&mut self, &local: &Local, context: LvalueContext<'tcx>, _: Location) {
|
||||
fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
|
||||
match context {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// DEFS
|
||||
|
||||
LvalueContext::Store |
|
||||
PlaceContext::Store |
|
||||
|
||||
// We let Call define the result in both the success and
|
||||
// unwind cases. This is not really correct, however it
|
||||
@ -248,12 +248,12 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
|
||||
// properly, we would apply the def in call only to the
|
||||
// input from the success path and not the unwind
|
||||
// path. -nmatsakis
|
||||
LvalueContext::Call |
|
||||
PlaceContext::Call |
|
||||
|
||||
// Storage live and storage dead aren't proper defines, but we can ignore
|
||||
// values that come before them.
|
||||
LvalueContext::StorageLive |
|
||||
LvalueContext::StorageDead => {
|
||||
PlaceContext::StorageLive |
|
||||
PlaceContext::StorageDead => {
|
||||
self.defs_uses.add_def(local);
|
||||
}
|
||||
|
||||
@ -264,18 +264,18 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
|
||||
// purposes of NLL, these are special in that **all** the
|
||||
// lifetimes appearing in the variable must be live for each regular use.
|
||||
|
||||
LvalueContext::Projection(..) |
|
||||
PlaceContext::Projection(..) |
|
||||
|
||||
// Borrows only consider their local used at the point of the borrow.
|
||||
// This won't affect the results since we use this analysis for generators
|
||||
// and we only care about the result at suspension points. Borrows cannot
|
||||
// cross suspension points so this behavior is unproblematic.
|
||||
LvalueContext::Borrow { .. } |
|
||||
PlaceContext::Borrow { .. } |
|
||||
|
||||
LvalueContext::Inspect |
|
||||
LvalueContext::Copy |
|
||||
LvalueContext::Move |
|
||||
LvalueContext::Validate => {
|
||||
PlaceContext::Inspect |
|
||||
PlaceContext::Copy |
|
||||
PlaceContext::Move |
|
||||
PlaceContext::Validate => {
|
||||
if self.mode.include_regular_use {
|
||||
self.defs_uses.add_use(local);
|
||||
}
|
||||
@ -289,7 +289,7 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
|
||||
// uses in drop are special because `#[may_dangle]`
|
||||
// attributes can affect whether lifetimes must be live.
|
||||
|
||||
LvalueContext::Drop => {
|
||||
PlaceContext::Drop => {
|
||||
if self.mode.include_drops {
|
||||
self.defs_uses.add_use(local);
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ impl<'tcx> MirPatch<'tcx> {
|
||||
self.new_statements.push((loc, stmt));
|
||||
}
|
||||
|
||||
pub fn add_assign(&mut self, loc: Location, lv: Lvalue<'tcx>, rv: Rvalue<'tcx>) {
|
||||
pub fn add_assign(&mut self, loc: Location, lv: Place<'tcx>, rv: Rvalue<'tcx>) {
|
||||
self.add_statement(loc, StatementKind::Assign(lv, rv));
|
||||
}
|
||||
|
||||
|
@ -389,7 +389,7 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write)
|
||||
if i != 0 {
|
||||
write!(w, ", ")?;
|
||||
}
|
||||
write!(w, "{:?}: {}", Lvalue::Local(arg), mir.local_decls[arg].ty)?;
|
||||
write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].ty)?;
|
||||
}
|
||||
|
||||
write!(w, ") -> {}", mir.return_ty())
|
||||
|
@ -15,7 +15,7 @@
|
||||
use rustc_const_math::{ConstUsize};
|
||||
use rustc::mir::{AggregateKind, AssertMessage, BasicBlock, BasicBlockData};
|
||||
use rustc::mir::{Constant, Literal, Location, Local, LocalDecl};
|
||||
use rustc::mir::{Lvalue, LvalueElem, LvalueProjection};
|
||||
use rustc::mir::{Place, PlaceElem, PlaceProjection};
|
||||
use rustc::mir::{Mir, Operand, ProjectionElem};
|
||||
use rustc::mir::{Rvalue, SourceInfo, Statement, StatementKind};
|
||||
use rustc::mir::{Terminator, TerminatorKind, VisibilityScope, VisibilityScopeData};
|
||||
@ -189,38 +189,38 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_lvalue(&mut self,
|
||||
lvalue: &Lvalue<'tcx>,
|
||||
context: mir_visit::LvalueContext<'tcx>,
|
||||
lvalue: &Place<'tcx>,
|
||||
context: mir_visit::PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
self.record("Lvalue", lvalue);
|
||||
self.record("Place", lvalue);
|
||||
self.record(match *lvalue {
|
||||
Lvalue::Local(..) => "Lvalue::Local",
|
||||
Lvalue::Static(..) => "Lvalue::Static",
|
||||
Lvalue::Projection(..) => "Lvalue::Projection",
|
||||
Place::Local(..) => "Place::Local",
|
||||
Place::Static(..) => "Place::Static",
|
||||
Place::Projection(..) => "Place::Projection",
|
||||
}, lvalue);
|
||||
self.super_lvalue(lvalue, context, location);
|
||||
}
|
||||
|
||||
fn visit_projection(&mut self,
|
||||
lvalue: &LvalueProjection<'tcx>,
|
||||
context: mir_visit::LvalueContext<'tcx>,
|
||||
lvalue: &PlaceProjection<'tcx>,
|
||||
context: mir_visit::PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
self.record("LvalueProjection", lvalue);
|
||||
self.record("PlaceProjection", lvalue);
|
||||
self.super_projection(lvalue, context, location);
|
||||
}
|
||||
|
||||
fn visit_projection_elem(&mut self,
|
||||
lvalue: &LvalueElem<'tcx>,
|
||||
context: mir_visit::LvalueContext<'tcx>,
|
||||
lvalue: &PlaceElem<'tcx>,
|
||||
context: mir_visit::PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
self.record("LvalueElem", lvalue);
|
||||
self.record("PlaceElem", lvalue);
|
||||
self.record(match *lvalue {
|
||||
ProjectionElem::Deref => "LvalueElem::Deref",
|
||||
ProjectionElem::Subslice { .. } => "LvalueElem::Subslice",
|
||||
ProjectionElem::Field(..) => "LvalueElem::Field",
|
||||
ProjectionElem::Index(..) => "LvalueElem::Index",
|
||||
ProjectionElem::ConstantIndex { .. } => "LvalueElem::ConstantIndex",
|
||||
ProjectionElem::Downcast(..) => "LvalueElem::Downcast",
|
||||
ProjectionElem::Deref => "PlaceElem::Deref",
|
||||
ProjectionElem::Subslice { .. } => "PlaceElem::Subslice",
|
||||
ProjectionElem::Field(..) => "PlaceElem::Field",
|
||||
ProjectionElem::Index(..) => "PlaceElem::Index",
|
||||
ProjectionElem::ConstantIndex { .. } => "PlaceElem::ConstantIndex",
|
||||
ProjectionElem::Downcast(..) => "PlaceElem::Downcast",
|
||||
}, lvalue);
|
||||
self.super_projection_elem(lvalue, context, location);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ use cabi_sparc64;
|
||||
use cabi_nvptx;
|
||||
use cabi_nvptx64;
|
||||
use cabi_hexagon;
|
||||
use mir::lvalue::{Alignment, LvalueRef};
|
||||
use mir::lvalue::{Alignment, PlaceRef};
|
||||
use mir::operand::OperandValue;
|
||||
use type_::Type;
|
||||
use type_of::{LayoutLlvmExt, PointerKind};
|
||||
@ -555,7 +555,7 @@ impl<'a, 'tcx> ArgType<'tcx> {
|
||||
/// lvalue for the original Rust type of this argument/return.
|
||||
/// Can be used for both storing formal arguments into Rust variables
|
||||
/// or results of call/invoke instructions into their destinations.
|
||||
pub fn store(&self, bcx: &Builder<'a, 'tcx>, val: ValueRef, dst: LvalueRef<'tcx>) {
|
||||
pub fn store(&self, bcx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) {
|
||||
if self.is_ignore() {
|
||||
return;
|
||||
}
|
||||
@ -606,7 +606,7 @@ impl<'a, 'tcx> ArgType<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn store_fn_arg(&self, bcx: &Builder<'a, 'tcx>, idx: &mut usize, dst: LvalueRef<'tcx>) {
|
||||
pub fn store_fn_arg(&self, bcx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) {
|
||||
if self.pad.is_some() {
|
||||
*idx += 1;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use builder::Builder;
|
||||
|
||||
use rustc::hir;
|
||||
|
||||
use mir::lvalue::LvalueRef;
|
||||
use mir::lvalue::PlaceRef;
|
||||
use mir::operand::OperandValue;
|
||||
|
||||
use std::ffi::CString;
|
||||
@ -29,7 +29,7 @@ use libc::{c_uint, c_char};
|
||||
pub fn trans_inline_asm<'a, 'tcx>(
|
||||
bcx: &Builder<'a, 'tcx>,
|
||||
ia: &hir::InlineAsm,
|
||||
outputs: Vec<LvalueRef<'tcx>>,
|
||||
outputs: Vec<PlaceRef<'tcx>>,
|
||||
mut inputs: Vec<ValueRef>
|
||||
) {
|
||||
let mut ext_constraints = vec![];
|
||||
|
@ -50,7 +50,7 @@ use rustc::session::config::{self, NoDebugInfo};
|
||||
use rustc::session::Session;
|
||||
use rustc_incremental;
|
||||
use allocator;
|
||||
use mir::lvalue::LvalueRef;
|
||||
use mir::lvalue::PlaceRef;
|
||||
use attributes;
|
||||
use builder::Builder;
|
||||
use callee;
|
||||
@ -272,8 +272,8 @@ pub fn unsize_thin_ptr<'a, 'tcx>(
|
||||
/// Coerce `src`, which is a reference to a value of type `src_ty`,
|
||||
/// to a value of type `dst_ty` and store the result in `dst`
|
||||
pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
src: LvalueRef<'tcx>,
|
||||
dst: LvalueRef<'tcx>) {
|
||||
src: PlaceRef<'tcx>,
|
||||
dst: PlaceRef<'tcx>) {
|
||||
let src_ty = src.layout.ty;
|
||||
let dst_ty = dst.layout.ty;
|
||||
let coerce_ptr = || {
|
||||
|
@ -14,7 +14,7 @@ use intrinsics::{self, Intrinsic};
|
||||
use llvm;
|
||||
use llvm::{ValueRef};
|
||||
use abi::{Abi, FnType, PassMode};
|
||||
use mir::lvalue::{LvalueRef, Alignment};
|
||||
use mir::lvalue::{PlaceRef, Alignment};
|
||||
use mir::operand::{OperandRef, OperandValue};
|
||||
use base::*;
|
||||
use common::*;
|
||||
@ -106,7 +106,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
let name = &*tcx.item_name(def_id);
|
||||
|
||||
let llret_ty = ccx.layout_of(ret_ty).llvm_type(ccx);
|
||||
let result = LvalueRef::new_sized(llresult, fn_ty.ret.layout, Alignment::AbiAligned);
|
||||
let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, Alignment::AbiAligned);
|
||||
|
||||
let simple = get_simple_intrinsic(ccx, name);
|
||||
let llval = match name {
|
||||
@ -625,7 +625,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
OperandValue::Ref(ptr, align) => (ptr, align),
|
||||
_ => bug!()
|
||||
};
|
||||
let arg = LvalueRef::new_sized(ptr, arg.layout, align);
|
||||
let arg = PlaceRef::new_sized(ptr, arg.layout, align);
|
||||
(0..contents.len()).map(|i| {
|
||||
arg.project_field(bcx, i).load(bcx).immediate()
|
||||
}).collect()
|
||||
|
@ -15,7 +15,7 @@ use rustc_data_structures::bitvec::BitVector;
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::{self, Location, TerminatorKind, Literal};
|
||||
use rustc::mir::visit::{Visitor, LvalueContext};
|
||||
use rustc::mir::visit::{Visitor, PlaceContext};
|
||||
use rustc::mir::traversal;
|
||||
use rustc::ty;
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
@ -88,18 +88,18 @@ impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> {
|
||||
impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
|
||||
fn visit_assign(&mut self,
|
||||
block: mir::BasicBlock,
|
||||
lvalue: &mir::Lvalue<'tcx>,
|
||||
lvalue: &mir::Place<'tcx>,
|
||||
rvalue: &mir::Rvalue<'tcx>,
|
||||
location: Location) {
|
||||
debug!("visit_assign(block={:?}, lvalue={:?}, rvalue={:?})", block, lvalue, rvalue);
|
||||
|
||||
if let mir::Lvalue::Local(index) = *lvalue {
|
||||
if let mir::Place::Local(index) = *lvalue {
|
||||
self.mark_assigned(index);
|
||||
if !self.cx.rvalue_creates_operand(rvalue) {
|
||||
self.mark_as_lvalue(index);
|
||||
}
|
||||
} else {
|
||||
self.visit_lvalue(lvalue, LvalueContext::Store, location);
|
||||
self.visit_lvalue(lvalue, PlaceContext::Store, location);
|
||||
}
|
||||
|
||||
self.visit_rvalue(rvalue, location);
|
||||
@ -122,7 +122,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
|
||||
// is not guaranteed to be statically dominated by the
|
||||
// definition of x, so x must always be in an alloca.
|
||||
if let mir::Operand::Move(ref lvalue) = args[0] {
|
||||
self.visit_lvalue(lvalue, LvalueContext::Drop, location);
|
||||
self.visit_lvalue(lvalue, PlaceContext::Drop, location);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -132,16 +132,16 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_lvalue(&mut self,
|
||||
lvalue: &mir::Lvalue<'tcx>,
|
||||
context: LvalueContext<'tcx>,
|
||||
lvalue: &mir::Place<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
debug!("visit_lvalue(lvalue={:?}, context={:?})", lvalue, context);
|
||||
let ccx = self.cx.ccx;
|
||||
|
||||
if let mir::Lvalue::Projection(ref proj) = *lvalue {
|
||||
if let mir::Place::Projection(ref proj) = *lvalue {
|
||||
// Allow uses of projections that are ZSTs or from scalar fields.
|
||||
let is_consume = match context {
|
||||
LvalueContext::Copy | LvalueContext::Move => true,
|
||||
PlaceContext::Copy | PlaceContext::Move => true,
|
||||
_ => false
|
||||
};
|
||||
if is_consume {
|
||||
@ -169,7 +169,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
|
||||
|
||||
// A deref projection only reads the pointer, never needs the lvalue.
|
||||
if let mir::ProjectionElem::Deref = proj.elem {
|
||||
return self.visit_lvalue(&proj.base, LvalueContext::Copy, location);
|
||||
return self.visit_lvalue(&proj.base, PlaceContext::Copy, location);
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,28 +178,28 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
|
||||
|
||||
fn visit_local(&mut self,
|
||||
&index: &mir::Local,
|
||||
context: LvalueContext<'tcx>,
|
||||
context: PlaceContext<'tcx>,
|
||||
_: Location) {
|
||||
match context {
|
||||
LvalueContext::Call => {
|
||||
PlaceContext::Call => {
|
||||
self.mark_assigned(index);
|
||||
}
|
||||
|
||||
LvalueContext::StorageLive |
|
||||
LvalueContext::StorageDead |
|
||||
LvalueContext::Validate |
|
||||
LvalueContext::Copy |
|
||||
LvalueContext::Move => {}
|
||||
PlaceContext::StorageLive |
|
||||
PlaceContext::StorageDead |
|
||||
PlaceContext::Validate |
|
||||
PlaceContext::Copy |
|
||||
PlaceContext::Move => {}
|
||||
|
||||
LvalueContext::Inspect |
|
||||
LvalueContext::Store |
|
||||
LvalueContext::Borrow { .. } |
|
||||
LvalueContext::Projection(..) => {
|
||||
PlaceContext::Inspect |
|
||||
PlaceContext::Store |
|
||||
PlaceContext::Borrow { .. } |
|
||||
PlaceContext::Projection(..) => {
|
||||
self.mark_as_lvalue(index);
|
||||
}
|
||||
|
||||
LvalueContext::Drop => {
|
||||
let ty = mir::Lvalue::Local(index).ty(self.cx.mir, self.cx.ccx.tcx());
|
||||
PlaceContext::Drop => {
|
||||
let ty = mir::Place::Local(index).ty(self.cx.mir, self.cx.ccx.tcx());
|
||||
let ty = self.cx.monomorphize(&ty.to_ty(self.cx.ccx.tcx()));
|
||||
|
||||
// Only need the lvalue if we're actually dropping it.
|
||||
|
@ -31,7 +31,7 @@ use syntax_pos::Pos;
|
||||
|
||||
use super::{MirContext, LocalRef};
|
||||
use super::constant::Const;
|
||||
use super::lvalue::{Alignment, LvalueRef};
|
||||
use super::lvalue::{Alignment, PlaceRef};
|
||||
use super::operand::OperandRef;
|
||||
use super::operand::OperandValue::{Pair, Ref, Immediate};
|
||||
|
||||
@ -214,7 +214,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
PassMode::Direct(_) | PassMode::Pair(..) => {
|
||||
let op = self.trans_consume(&bcx, &mir::Lvalue::Local(mir::RETURN_POINTER));
|
||||
let op = self.trans_consume(&bcx, &mir::Place::Local(mir::RETURN_POINTER));
|
||||
if let Ref(llval, align) = op.val {
|
||||
bcx.load(llval, align.non_abi())
|
||||
} else {
|
||||
@ -226,7 +226,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
let op = match self.locals[mir::RETURN_POINTER] {
|
||||
LocalRef::Operand(Some(op)) => op,
|
||||
LocalRef::Operand(None) => bug!("use of return before def"),
|
||||
LocalRef::Lvalue(tr_lvalue) => {
|
||||
LocalRef::Place(tr_lvalue) => {
|
||||
OperandRef {
|
||||
val: Ref(tr_lvalue.llval, tr_lvalue.alignment),
|
||||
layout: tr_lvalue.layout
|
||||
@ -235,7 +235,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
};
|
||||
let llslot = match op.val {
|
||||
Immediate(_) | Pair(..) => {
|
||||
let scratch = LvalueRef::alloca(&bcx, self.fn_ty.ret.layout, "ret");
|
||||
let scratch = PlaceRef::alloca(&bcx, self.fn_ty.ret.layout, "ret");
|
||||
op.val.store(&bcx, scratch);
|
||||
scratch.llval
|
||||
}
|
||||
@ -577,7 +577,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
match (arg, op.val) {
|
||||
(&mir::Operand::Copy(_), Ref(..)) |
|
||||
(&mir::Operand::Constant(_), Ref(..)) => {
|
||||
let tmp = LvalueRef::alloca(&bcx, op.layout, "const");
|
||||
let tmp = PlaceRef::alloca(&bcx, op.layout, "const");
|
||||
op.val.store(&bcx, tmp);
|
||||
op.val = Ref(tmp.llval, tmp.alignment);
|
||||
}
|
||||
@ -637,7 +637,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
Immediate(_) | Pair(..) => {
|
||||
match arg.mode {
|
||||
PassMode::Indirect(_) | PassMode::Cast(_) => {
|
||||
let scratch = LvalueRef::alloca(bcx, arg.layout, "arg");
|
||||
let scratch = PlaceRef::alloca(bcx, arg.layout, "arg");
|
||||
op.val.store(bcx, scratch);
|
||||
(scratch.llval, Alignment::AbiAligned, true)
|
||||
}
|
||||
@ -651,7 +651,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
// think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't
|
||||
// have scary latent bugs around.
|
||||
|
||||
let scratch = LvalueRef::alloca(bcx, arg.layout, "arg");
|
||||
let scratch = PlaceRef::alloca(bcx, arg.layout, "arg");
|
||||
base::memcpy_ty(bcx, scratch.llval, llval, op.layout, align.non_abi());
|
||||
(scratch.llval, Alignment::AbiAligned, true)
|
||||
}
|
||||
@ -665,7 +665,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
(align | Alignment::Packed(arg.layout.align))
|
||||
.non_abi());
|
||||
} else {
|
||||
// We can't use `LvalueRef::load` here because the argument
|
||||
// We can't use `PlaceRef::load` here because the argument
|
||||
// may have a type we don't treat as immediate, but the ABI
|
||||
// used for this call is passing it by-value. In that case,
|
||||
// the load would just produce `OperandValue::Ref` instead
|
||||
@ -693,7 +693,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
|
||||
// Handle both by-ref and immediate tuples.
|
||||
if let Ref(llval, align) = tuple.val {
|
||||
let tuple_ptr = LvalueRef::new_sized(llval, tuple.layout, align);
|
||||
let tuple_ptr = PlaceRef::new_sized(llval, tuple.layout, align);
|
||||
for i in 0..tuple.layout.fields.count() {
|
||||
let field_ptr = tuple_ptr.project_field(bcx, i);
|
||||
self.trans_argument(bcx, field_ptr.load(bcx), llargs, &args[i]);
|
||||
@ -707,7 +707,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_personality_slot(&mut self, bcx: &Builder<'a, 'tcx>) -> LvalueRef<'tcx> {
|
||||
fn get_personality_slot(&mut self, bcx: &Builder<'a, 'tcx>) -> PlaceRef<'tcx> {
|
||||
let ccx = bcx.ccx;
|
||||
if let Some(slot) = self.personality_slot {
|
||||
slot
|
||||
@ -716,7 +716,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
ccx.tcx().mk_mut_ptr(ccx.tcx().types.u8),
|
||||
ccx.tcx().types.i32
|
||||
], false));
|
||||
let slot = LvalueRef::alloca(bcx, layout, "personalityslot");
|
||||
let slot = PlaceRef::alloca(bcx, layout, "personalityslot");
|
||||
self.personality_slot = Some(slot);
|
||||
slot
|
||||
}
|
||||
@ -781,23 +781,23 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn make_return_dest(&mut self, bcx: &Builder<'a, 'tcx>,
|
||||
dest: &mir::Lvalue<'tcx>, fn_ret: &ArgType<'tcx>,
|
||||
dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx>,
|
||||
llargs: &mut Vec<ValueRef>, is_intrinsic: bool)
|
||||
-> ReturnDest<'tcx> {
|
||||
// If the return is ignored, we can just return a do-nothing ReturnDest
|
||||
if fn_ret.is_ignore() {
|
||||
return ReturnDest::Nothing;
|
||||
}
|
||||
let dest = if let mir::Lvalue::Local(index) = *dest {
|
||||
let dest = if let mir::Place::Local(index) = *dest {
|
||||
match self.locals[index] {
|
||||
LocalRef::Lvalue(dest) => dest,
|
||||
LocalRef::Place(dest) => dest,
|
||||
LocalRef::Operand(None) => {
|
||||
// Handle temporary lvalues, specifically Operand ones, as
|
||||
// they don't have allocas
|
||||
return if fn_ret.is_indirect() {
|
||||
// Odd, but possible, case, we have an operand temporary,
|
||||
// but the calling convention has an indirect return.
|
||||
let tmp = LvalueRef::alloca(bcx, fn_ret.layout, "tmp_ret");
|
||||
let tmp = PlaceRef::alloca(bcx, fn_ret.layout, "tmp_ret");
|
||||
tmp.storage_live(bcx);
|
||||
llargs.push(tmp.llval);
|
||||
ReturnDest::IndirectOperand(tmp, index)
|
||||
@ -805,7 +805,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
// Currently, intrinsics always need a location to store
|
||||
// the result. so we create a temporary alloca for the
|
||||
// result
|
||||
let tmp = LvalueRef::alloca(bcx, fn_ret.layout, "tmp_ret");
|
||||
let tmp = PlaceRef::alloca(bcx, fn_ret.layout, "tmp_ret");
|
||||
tmp.storage_live(bcx);
|
||||
ReturnDest::IndirectOperand(tmp, index)
|
||||
} else {
|
||||
@ -842,14 +842,14 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
|
||||
fn trans_transmute(&mut self, bcx: &Builder<'a, 'tcx>,
|
||||
src: &mir::Operand<'tcx>,
|
||||
dst: &mir::Lvalue<'tcx>) {
|
||||
if let mir::Lvalue::Local(index) = *dst {
|
||||
dst: &mir::Place<'tcx>) {
|
||||
if let mir::Place::Local(index) = *dst {
|
||||
match self.locals[index] {
|
||||
LocalRef::Lvalue(lvalue) => self.trans_transmute_into(bcx, src, lvalue),
|
||||
LocalRef::Place(lvalue) => self.trans_transmute_into(bcx, src, lvalue),
|
||||
LocalRef::Operand(None) => {
|
||||
let dst_layout = bcx.ccx.layout_of(self.monomorphized_lvalue_ty(dst));
|
||||
assert!(!dst_layout.ty.has_erasable_regions());
|
||||
let lvalue = LvalueRef::alloca(bcx, dst_layout, "transmute_temp");
|
||||
let lvalue = PlaceRef::alloca(bcx, dst_layout, "transmute_temp");
|
||||
lvalue.storage_live(bcx);
|
||||
self.trans_transmute_into(bcx, src, lvalue);
|
||||
let op = lvalue.load(bcx);
|
||||
@ -869,13 +869,13 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
|
||||
fn trans_transmute_into(&mut self, bcx: &Builder<'a, 'tcx>,
|
||||
src: &mir::Operand<'tcx>,
|
||||
dst: LvalueRef<'tcx>) {
|
||||
dst: PlaceRef<'tcx>) {
|
||||
let src = self.trans_operand(bcx, src);
|
||||
let llty = src.layout.llvm_type(bcx.ccx);
|
||||
let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to());
|
||||
let align = src.layout.align.min(dst.layout.align);
|
||||
src.val.store(bcx,
|
||||
LvalueRef::new_sized(cast_ptr, src.layout, Alignment::Packed(align)));
|
||||
PlaceRef::new_sized(cast_ptr, src.layout, Alignment::Packed(align)));
|
||||
}
|
||||
|
||||
|
||||
@ -898,7 +898,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
DirectOperand(index) => {
|
||||
// If there is a cast, we have to store and reload.
|
||||
let op = if let PassMode::Cast(_) = ret_ty.mode {
|
||||
let tmp = LvalueRef::alloca(bcx, ret_ty.layout, "tmp_ret");
|
||||
let tmp = PlaceRef::alloca(bcx, ret_ty.layout, "tmp_ret");
|
||||
tmp.storage_live(bcx);
|
||||
ret_ty.store(bcx, llval, tmp);
|
||||
let op = tmp.load(bcx);
|
||||
@ -917,9 +917,9 @@ enum ReturnDest<'tcx> {
|
||||
// Do nothing, the return value is indirect or ignored
|
||||
Nothing,
|
||||
// Store the return value to the pointer
|
||||
Store(LvalueRef<'tcx>),
|
||||
Store(PlaceRef<'tcx>),
|
||||
// Stores an indirect return value to an operand local lvalue
|
||||
IndirectOperand(LvalueRef<'tcx>, mir::Local),
|
||||
IndirectOperand(PlaceRef<'tcx>, mir::Local),
|
||||
// Stores a direct return value to an operand local lvalue
|
||||
DirectOperand(mir::Local)
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::TransNormalize;
|
||||
use rustc::traits;
|
||||
use rustc::mir;
|
||||
use rustc::mir::tcx::LvalueTy;
|
||||
use rustc::mir::tcx::PlaceTy;
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::layout::{self, LayoutOf, Size};
|
||||
use rustc::ty::cast::{CastTy, IntTy};
|
||||
@ -156,8 +156,8 @@ impl<'a, 'tcx> Const<'tcx> {
|
||||
self.get_pair(ccx)
|
||||
}
|
||||
|
||||
fn as_lvalue(&self) -> ConstLvalue<'tcx> {
|
||||
ConstLvalue {
|
||||
fn as_lvalue(&self) -> ConstPlace<'tcx> {
|
||||
ConstPlace {
|
||||
base: Base::Value(self.llval),
|
||||
llextra: ptr::null_mut(),
|
||||
ty: self.ty
|
||||
@ -212,13 +212,13 @@ enum Base {
|
||||
|
||||
/// An lvalue as seen from a constant.
|
||||
#[derive(Copy, Clone)]
|
||||
struct ConstLvalue<'tcx> {
|
||||
struct ConstPlace<'tcx> {
|
||||
base: Base,
|
||||
llextra: ValueRef,
|
||||
ty: Ty<'tcx>
|
||||
}
|
||||
|
||||
impl<'tcx> ConstLvalue<'tcx> {
|
||||
impl<'tcx> ConstPlace<'tcx> {
|
||||
fn to_const(&self, span: Span) -> Const<'tcx> {
|
||||
match self.base {
|
||||
Base::Value(val) => Const::new(val, self.ty),
|
||||
@ -242,7 +242,7 @@ impl<'tcx> ConstLvalue<'tcx> {
|
||||
assert!(self.llextra != ptr::null_mut());
|
||||
self.llextra
|
||||
}
|
||||
_ => bug!("unexpected type `{}` in ConstLvalue::len", self.ty)
|
||||
_ => bug!("unexpected type `{}` in ConstPlace::len", self.ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -427,38 +427,38 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn store(&mut self,
|
||||
dest: &mir::Lvalue<'tcx>,
|
||||
dest: &mir::Place<'tcx>,
|
||||
value: Result<Const<'tcx>, ConstEvalErr<'tcx>>,
|
||||
span: Span) {
|
||||
if let mir::Lvalue::Local(index) = *dest {
|
||||
if let mir::Place::Local(index) = *dest {
|
||||
self.locals[index] = Some(value);
|
||||
} else {
|
||||
span_bug!(span, "assignment to {:?} in constant", dest);
|
||||
}
|
||||
}
|
||||
|
||||
fn const_lvalue(&self, lvalue: &mir::Lvalue<'tcx>, span: Span)
|
||||
-> Result<ConstLvalue<'tcx>, ConstEvalErr<'tcx>> {
|
||||
fn const_lvalue(&self, lvalue: &mir::Place<'tcx>, span: Span)
|
||||
-> Result<ConstPlace<'tcx>, ConstEvalErr<'tcx>> {
|
||||
let tcx = self.ccx.tcx();
|
||||
|
||||
if let mir::Lvalue::Local(index) = *lvalue {
|
||||
if let mir::Place::Local(index) = *lvalue {
|
||||
return self.locals[index].clone().unwrap_or_else(|| {
|
||||
span_bug!(span, "{:?} not initialized", lvalue)
|
||||
}).map(|v| v.as_lvalue());
|
||||
}
|
||||
|
||||
let lvalue = match *lvalue {
|
||||
mir::Lvalue::Local(_) => bug!(), // handled above
|
||||
mir::Lvalue::Static(box mir::Static { def_id, ty }) => {
|
||||
ConstLvalue {
|
||||
mir::Place::Local(_) => bug!(), // handled above
|
||||
mir::Place::Static(box mir::Static { def_id, ty }) => {
|
||||
ConstPlace {
|
||||
base: Base::Static(consts::get_static(self.ccx, def_id)),
|
||||
llextra: ptr::null_mut(),
|
||||
ty: self.monomorphize(&ty),
|
||||
}
|
||||
}
|
||||
mir::Lvalue::Projection(ref projection) => {
|
||||
mir::Place::Projection(ref projection) => {
|
||||
let tr_base = self.const_lvalue(&projection.base, span)?;
|
||||
let projected_ty = LvalueTy::Ty { ty: tr_base.ty }
|
||||
let projected_ty = PlaceTy::Ty { ty: tr_base.ty }
|
||||
.projection_ty(tcx, &projection.elem);
|
||||
let base = tr_base.to_const(span);
|
||||
let projected_ty = self.monomorphize(&projected_ty).to_ty(tcx);
|
||||
@ -505,7 +505,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
(Base::Value(llprojected), llextra)
|
||||
}
|
||||
mir::ProjectionElem::Index(index) => {
|
||||
let index = &mir::Operand::Copy(mir::Lvalue::Local(index));
|
||||
let index = &mir::Operand::Copy(mir::Place::Local(index));
|
||||
let llindex = self.const_operand(index, span)?.llval;
|
||||
|
||||
let iv = if let Some(iv) = common::const_to_opt_u128(llindex, false) {
|
||||
@ -526,7 +526,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
}
|
||||
_ => span_bug!(span, "{:?} in constant", projection.elem)
|
||||
};
|
||||
ConstLvalue {
|
||||
ConstPlace {
|
||||
base: projected,
|
||||
llextra,
|
||||
ty: projected_ty
|
||||
|
@ -12,7 +12,7 @@ use llvm::{self, ValueRef};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::{self, Align, TyLayout, LayoutOf};
|
||||
use rustc::mir;
|
||||
use rustc::mir::tcx::LvalueTy;
|
||||
use rustc::mir::tcx::PlaceTy;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use base;
|
||||
use builder::Builder;
|
||||
@ -73,7 +73,7 @@ impl Alignment {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct LvalueRef<'tcx> {
|
||||
pub struct PlaceRef<'tcx> {
|
||||
/// Pointer to the contents of the lvalue
|
||||
pub llval: ValueRef,
|
||||
|
||||
@ -87,12 +87,12 @@ pub struct LvalueRef<'tcx> {
|
||||
pub alignment: Alignment,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
pub fn new_sized(llval: ValueRef,
|
||||
layout: TyLayout<'tcx>,
|
||||
alignment: Alignment)
|
||||
-> LvalueRef<'tcx> {
|
||||
LvalueRef {
|
||||
-> PlaceRef<'tcx> {
|
||||
PlaceRef {
|
||||
llval,
|
||||
llextra: ptr::null_mut(),
|
||||
layout,
|
||||
@ -101,7 +101,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
}
|
||||
|
||||
pub fn alloca(bcx: &Builder<'a, 'tcx>, layout: TyLayout<'tcx>, name: &str)
|
||||
-> LvalueRef<'tcx> {
|
||||
-> PlaceRef<'tcx> {
|
||||
debug!("alloca({:?}: {:?})", name, layout);
|
||||
let tmp = bcx.alloca(layout.llvm_type(bcx.ccx), name, layout.align);
|
||||
Self::new_sized(tmp, layout, Alignment::AbiAligned)
|
||||
@ -117,7 +117,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
C_usize(ccx, count)
|
||||
}
|
||||
} else {
|
||||
bug!("unexpected layout `{:#?}` in LvalueRef::len", self.layout)
|
||||
bug!("unexpected layout `{:#?}` in PlaceRef::len", self.layout)
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
}
|
||||
|
||||
pub fn load(&self, bcx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> {
|
||||
debug!("LvalueRef::load: {:?}", self);
|
||||
debug!("PlaceRef::load: {:?}", self);
|
||||
|
||||
assert!(!self.has_extra());
|
||||
|
||||
@ -202,7 +202,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
}
|
||||
|
||||
/// Access a field, at a point when the value's case is known.
|
||||
pub fn project_field(self, bcx: &Builder<'a, 'tcx>, ix: usize) -> LvalueRef<'tcx> {
|
||||
pub fn project_field(self, bcx: &Builder<'a, 'tcx>, ix: usize) -> PlaceRef<'tcx> {
|
||||
let ccx = bcx.ccx;
|
||||
let field = self.layout.field(ccx, ix);
|
||||
let offset = self.layout.fields.offset(ix);
|
||||
@ -219,7 +219,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
} else {
|
||||
bcx.struct_gep(self.llval, self.layout.llvm_field_index(ix))
|
||||
};
|
||||
LvalueRef {
|
||||
PlaceRef {
|
||||
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
|
||||
llval: bcx.pointercast(llval, field.llvm_type(ccx).ptr_to()),
|
||||
llextra: if ccx.shared().type_has_metadata(field.ty) {
|
||||
@ -295,7 +295,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
let ll_fty = field.llvm_type(ccx);
|
||||
debug!("struct_field_ptr: Field type is {:?}", ll_fty);
|
||||
|
||||
LvalueRef {
|
||||
PlaceRef {
|
||||
llval: bcx.pointercast(byte_ptr, ll_fty.ptr_to()),
|
||||
llextra: self.llextra,
|
||||
layout: field,
|
||||
@ -413,8 +413,8 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
}
|
||||
|
||||
pub fn project_index(&self, bcx: &Builder<'a, 'tcx>, llindex: ValueRef)
|
||||
-> LvalueRef<'tcx> {
|
||||
LvalueRef {
|
||||
-> PlaceRef<'tcx> {
|
||||
PlaceRef {
|
||||
llval: bcx.inbounds_gep(self.llval, &[C_usize(bcx.ccx, 0), llindex]),
|
||||
llextra: ptr::null_mut(),
|
||||
layout: self.layout.field(bcx.ccx, 0),
|
||||
@ -423,7 +423,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
}
|
||||
|
||||
pub fn project_downcast(&self, bcx: &Builder<'a, 'tcx>, variant_index: usize)
|
||||
-> LvalueRef<'tcx> {
|
||||
-> PlaceRef<'tcx> {
|
||||
let mut downcast = *self;
|
||||
downcast.layout = self.layout.for_variant(bcx.ccx, variant_index);
|
||||
|
||||
@ -446,16 +446,16 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
pub fn trans_lvalue(&mut self,
|
||||
bcx: &Builder<'a, 'tcx>,
|
||||
lvalue: &mir::Lvalue<'tcx>)
|
||||
-> LvalueRef<'tcx> {
|
||||
lvalue: &mir::Place<'tcx>)
|
||||
-> PlaceRef<'tcx> {
|
||||
debug!("trans_lvalue(lvalue={:?})", lvalue);
|
||||
|
||||
let ccx = bcx.ccx;
|
||||
let tcx = ccx.tcx();
|
||||
|
||||
if let mir::Lvalue::Local(index) = *lvalue {
|
||||
if let mir::Place::Local(index) = *lvalue {
|
||||
match self.locals[index] {
|
||||
LocalRef::Lvalue(lvalue) => {
|
||||
LocalRef::Place(lvalue) => {
|
||||
return lvalue;
|
||||
}
|
||||
LocalRef::Operand(..) => {
|
||||
@ -465,20 +465,20 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
let result = match *lvalue {
|
||||
mir::Lvalue::Local(_) => bug!(), // handled above
|
||||
mir::Lvalue::Static(box mir::Static { def_id, ty }) => {
|
||||
LvalueRef::new_sized(consts::get_static(ccx, def_id),
|
||||
mir::Place::Local(_) => bug!(), // handled above
|
||||
mir::Place::Static(box mir::Static { def_id, ty }) => {
|
||||
PlaceRef::new_sized(consts::get_static(ccx, def_id),
|
||||
ccx.layout_of(self.monomorphize(&ty)),
|
||||
Alignment::AbiAligned)
|
||||
},
|
||||
mir::Lvalue::Projection(box mir::Projection {
|
||||
mir::Place::Projection(box mir::Projection {
|
||||
ref base,
|
||||
elem: mir::ProjectionElem::Deref
|
||||
}) => {
|
||||
// Load the pointer from its location.
|
||||
self.trans_consume(bcx, base).deref(bcx.ccx)
|
||||
}
|
||||
mir::Lvalue::Projection(ref projection) => {
|
||||
mir::Place::Projection(ref projection) => {
|
||||
let tr_base = self.trans_lvalue(bcx, &projection.base);
|
||||
|
||||
match projection.elem {
|
||||
@ -487,7 +487,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
tr_base.project_field(bcx, field.index())
|
||||
}
|
||||
mir::ProjectionElem::Index(index) => {
|
||||
let index = &mir::Operand::Copy(mir::Lvalue::Local(index));
|
||||
let index = &mir::Operand::Copy(mir::Place::Local(index));
|
||||
let index = self.trans_operand(bcx, index);
|
||||
let llindex = index.immediate();
|
||||
tr_base.project_index(bcx, llindex)
|
||||
@ -509,7 +509,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
mir::ProjectionElem::Subslice { from, to } => {
|
||||
let mut subslice = tr_base.project_index(bcx,
|
||||
C_usize(bcx.ccx, from as u64));
|
||||
let projected_ty = LvalueTy::Ty { ty: tr_base.layout.ty }
|
||||
let projected_ty = PlaceTy::Ty { ty: tr_base.layout.ty }
|
||||
.projection_ty(tcx, &projection.elem).to_ty(bcx.tcx());
|
||||
subslice.layout = bcx.ccx.layout_of(self.monomorphize(&projected_ty));
|
||||
|
||||
@ -536,7 +536,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn monomorphized_lvalue_ty(&self, lvalue: &mir::Lvalue<'tcx>) -> Ty<'tcx> {
|
||||
pub fn monomorphized_lvalue_ty(&self, lvalue: &mir::Place<'tcx>) -> Ty<'tcx> {
|
||||
let tcx = self.ccx.tcx();
|
||||
let lvalue_ty = lvalue.ty(self.mir, tcx);
|
||||
self.monomorphize(&lvalue_ty.to_ty(tcx))
|
||||
|
@ -35,7 +35,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
pub use self::constant::trans_static_initializer;
|
||||
|
||||
use self::analyze::CleanupKind;
|
||||
use self::lvalue::{Alignment, LvalueRef};
|
||||
use self::lvalue::{Alignment, PlaceRef};
|
||||
use rustc::mir::traversal;
|
||||
|
||||
use self::operand::{OperandRef, OperandValue};
|
||||
@ -59,7 +59,7 @@ pub struct MirContext<'a, 'tcx:'a> {
|
||||
/// don't really care about it very much. Anyway, this value
|
||||
/// contains an alloca into which the personality is stored and
|
||||
/// then later loaded when generating the DIVERGE_BLOCK.
|
||||
personality_slot: Option<LvalueRef<'tcx>>,
|
||||
personality_slot: Option<PlaceRef<'tcx>>,
|
||||
|
||||
/// A `Block` for each MIR `BasicBlock`
|
||||
blocks: IndexVec<mir::BasicBlock, BasicBlockRef>,
|
||||
@ -79,7 +79,7 @@ pub struct MirContext<'a, 'tcx:'a> {
|
||||
unreachable_block: Option<BasicBlockRef>,
|
||||
|
||||
/// The location where each MIR arg/var/tmp/ret is stored. This is
|
||||
/// usually an `LvalueRef` representing an alloca, but not always:
|
||||
/// usually an `PlaceRef` representing an alloca, but not always:
|
||||
/// sometimes we can skip the alloca and just store the value
|
||||
/// directly using an `OperandRef`, which makes for tighter LLVM
|
||||
/// IR. The conditions for using an `OperandRef` are as follows:
|
||||
@ -171,7 +171,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
enum LocalRef<'tcx> {
|
||||
Lvalue(LvalueRef<'tcx>),
|
||||
Place(PlaceRef<'tcx>),
|
||||
Operand(Option<OperandRef<'tcx>>),
|
||||
}
|
||||
|
||||
@ -266,25 +266,25 @@ pub fn trans_mir<'a, 'tcx: 'a>(
|
||||
}
|
||||
|
||||
debug!("alloc: {:?} ({}) -> lvalue", local, name);
|
||||
let lvalue = LvalueRef::alloca(&bcx, layout, &name.as_str());
|
||||
let lvalue = PlaceRef::alloca(&bcx, layout, &name.as_str());
|
||||
if dbg {
|
||||
let (scope, span) = mircx.debug_loc(decl.source_info);
|
||||
declare_local(&bcx, &mircx.debug_context, name, layout.ty, scope,
|
||||
VariableAccess::DirectVariable { alloca: lvalue.llval },
|
||||
VariableKind::LocalVariable, span);
|
||||
}
|
||||
LocalRef::Lvalue(lvalue)
|
||||
LocalRef::Place(lvalue)
|
||||
} else {
|
||||
// Temporary or return pointer
|
||||
if local == mir::RETURN_POINTER && mircx.fn_ty.ret.is_indirect() {
|
||||
debug!("alloc: {:?} (return pointer) -> lvalue", local);
|
||||
let llretptr = llvm::get_param(llfn, 0);
|
||||
LocalRef::Lvalue(LvalueRef::new_sized(llretptr,
|
||||
LocalRef::Place(PlaceRef::new_sized(llretptr,
|
||||
layout,
|
||||
Alignment::AbiAligned))
|
||||
} else if lvalue_locals.contains(local.index()) {
|
||||
debug!("alloc: {:?} -> lvalue", local);
|
||||
LocalRef::Lvalue(LvalueRef::alloca(&bcx, layout, &format!("{:?}", local)))
|
||||
LocalRef::Place(PlaceRef::alloca(&bcx, layout, &format!("{:?}", local)))
|
||||
} else {
|
||||
// If this is an immediate local, we do not create an
|
||||
// alloca in advance. Instead we wait until we see the
|
||||
@ -400,7 +400,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
_ => bug!("spread argument isn't a tuple?!")
|
||||
};
|
||||
|
||||
let lvalue = LvalueRef::alloca(bcx, bcx.ccx.layout_of(arg_ty), &name);
|
||||
let lvalue = PlaceRef::alloca(bcx, bcx.ccx.layout_of(arg_ty), &name);
|
||||
for i in 0..tupled_arg_tys.len() {
|
||||
let arg = &mircx.fn_ty.args[idx];
|
||||
idx += 1;
|
||||
@ -424,7 +424,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
);
|
||||
});
|
||||
|
||||
return LocalRef::Lvalue(lvalue);
|
||||
return LocalRef::Place(lvalue);
|
||||
}
|
||||
|
||||
let arg = &mircx.fn_ty.args[idx];
|
||||
@ -474,9 +474,9 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
let llarg = llvm::get_param(bcx.llfn(), llarg_idx as c_uint);
|
||||
bcx.set_value_name(llarg, &name);
|
||||
llarg_idx += 1;
|
||||
LvalueRef::new_sized(llarg, arg.layout, Alignment::AbiAligned)
|
||||
PlaceRef::new_sized(llarg, arg.layout, Alignment::AbiAligned)
|
||||
} else {
|
||||
let tmp = LvalueRef::alloca(bcx, arg.layout, &name);
|
||||
let tmp = PlaceRef::alloca(bcx, arg.layout, &name);
|
||||
arg.store_fn_arg(bcx, &mut llarg_idx, tmp);
|
||||
tmp
|
||||
};
|
||||
@ -532,7 +532,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
// doesn't actually strip the offset when splitting the closure
|
||||
// environment into its components so it ends up out of bounds.
|
||||
let env_ptr = if !env_ref {
|
||||
let alloc = LvalueRef::alloca(bcx,
|
||||
let alloc = PlaceRef::alloca(bcx,
|
||||
bcx.ccx.layout_of(tcx.mk_mut_ptr(arg.layout.ty)),
|
||||
"__debuginfo_env_ptr");
|
||||
bcx.store(lvalue.llval, alloc.llval, None);
|
||||
@ -580,7 +580,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
);
|
||||
}
|
||||
});
|
||||
LocalRef::Lvalue(lvalue)
|
||||
LocalRef::Place(lvalue)
|
||||
}).collect()
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ use std::fmt;
|
||||
use std::ptr;
|
||||
|
||||
use super::{MirContext, LocalRef};
|
||||
use super::lvalue::{Alignment, LvalueRef};
|
||||
use super::lvalue::{Alignment, PlaceRef};
|
||||
|
||||
/// The representation of a Rust value. The enum variant is in fact
|
||||
/// uniquely determined by the value's type, but is kept as a
|
||||
@ -99,7 +99,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deref(self, ccx: &CrateContext<'a, 'tcx>) -> LvalueRef<'tcx> {
|
||||
pub fn deref(self, ccx: &CrateContext<'a, 'tcx>) -> PlaceRef<'tcx> {
|
||||
let projected_ty = self.layout.ty.builtin_deref(true, ty::NoPreference)
|
||||
.unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)).ty;
|
||||
let (llptr, llextra) = match self.val {
|
||||
@ -107,7 +107,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||
OperandValue::Pair(llptr, llextra) => (llptr, llextra),
|
||||
OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self)
|
||||
};
|
||||
LvalueRef {
|
||||
PlaceRef {
|
||||
llval: llptr,
|
||||
llextra,
|
||||
layout: ccx.layout_of(projected_ty),
|
||||
@ -212,7 +212,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> OperandValue {
|
||||
pub fn store(self, bcx: &Builder<'a, 'tcx>, dest: LvalueRef<'tcx>) {
|
||||
pub fn store(self, bcx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
|
||||
debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest);
|
||||
// Avoid generating stores of zero-sized values, because the only way to have a zero-sized
|
||||
// value is through `undef`, and store itself is useless.
|
||||
@ -243,14 +243,14 @@ impl<'a, 'tcx> OperandValue {
|
||||
impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
fn maybe_trans_consume_direct(&mut self,
|
||||
bcx: &Builder<'a, 'tcx>,
|
||||
lvalue: &mir::Lvalue<'tcx>)
|
||||
lvalue: &mir::Place<'tcx>)
|
||||
-> Option<OperandRef<'tcx>>
|
||||
{
|
||||
debug!("maybe_trans_consume_direct(lvalue={:?})", lvalue);
|
||||
|
||||
// watch out for locals that do not have an
|
||||
// alloca; they are handled somewhat differently
|
||||
if let mir::Lvalue::Local(index) = *lvalue {
|
||||
if let mir::Place::Local(index) = *lvalue {
|
||||
match self.locals[index] {
|
||||
LocalRef::Operand(Some(o)) => {
|
||||
return Some(o);
|
||||
@ -258,14 +258,14 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
LocalRef::Operand(None) => {
|
||||
bug!("use of {:?} before def", lvalue);
|
||||
}
|
||||
LocalRef::Lvalue(..) => {
|
||||
LocalRef::Place(..) => {
|
||||
// use path below
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Moves out of scalar and scalar pair fields are trivial.
|
||||
if let &mir::Lvalue::Projection(ref proj) = lvalue {
|
||||
if let &mir::Place::Projection(ref proj) = lvalue {
|
||||
if let mir::ProjectionElem::Field(ref f, _) = proj.elem {
|
||||
if let Some(o) = self.maybe_trans_consume_direct(bcx, &proj.base) {
|
||||
return Some(o.extract_field(bcx, f.index()));
|
||||
@ -278,7 +278,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
|
||||
pub fn trans_consume(&mut self,
|
||||
bcx: &Builder<'a, 'tcx>,
|
||||
lvalue: &mir::Lvalue<'tcx>)
|
||||
lvalue: &mir::Place<'tcx>)
|
||||
-> OperandRef<'tcx>
|
||||
{
|
||||
debug!("trans_consume(lvalue={:?})", lvalue);
|
||||
@ -318,7 +318,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
let operand = val.to_operand(bcx.ccx);
|
||||
if let OperandValue::Ref(ptr, align) = operand.val {
|
||||
// If this is a OperandValue::Ref to an immediate constant, load it.
|
||||
LvalueRef::new_sized(ptr, operand.layout, align).load(bcx)
|
||||
PlaceRef::new_sized(ptr, operand.layout, align).load(bcx)
|
||||
} else {
|
||||
operand
|
||||
}
|
||||
|
@ -32,12 +32,12 @@ use value::Value;
|
||||
use super::{MirContext, LocalRef};
|
||||
use super::constant::const_scalar_checked_binop;
|
||||
use super::operand::{OperandRef, OperandValue};
|
||||
use super::lvalue::LvalueRef;
|
||||
use super::lvalue::PlaceRef;
|
||||
|
||||
impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
pub fn trans_rvalue(&mut self,
|
||||
bcx: Builder<'a, 'tcx>,
|
||||
dest: LvalueRef<'tcx>,
|
||||
dest: PlaceRef<'tcx>,
|
||||
rvalue: &mir::Rvalue<'tcx>)
|
||||
-> Builder<'a, 'tcx>
|
||||
{
|
||||
@ -79,14 +79,14 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
// index into the struct, and this case isn't
|
||||
// important enough for it.
|
||||
debug!("trans_rvalue: creating ugly alloca");
|
||||
let scratch = LvalueRef::alloca(&bcx, operand.layout, "__unsize_temp");
|
||||
let scratch = PlaceRef::alloca(&bcx, operand.layout, "__unsize_temp");
|
||||
scratch.storage_live(&bcx);
|
||||
operand.val.store(&bcx, scratch);
|
||||
base::coerce_unsized_into(&bcx, scratch, dest);
|
||||
scratch.storage_dead(&bcx);
|
||||
}
|
||||
OperandValue::Ref(llref, align) => {
|
||||
let source = LvalueRef::new_sized(llref, operand.layout, align);
|
||||
let source = PlaceRef::new_sized(llref, operand.layout, align);
|
||||
base::coerce_unsized_into(&bcx, source, dest);
|
||||
}
|
||||
}
|
||||
@ -139,7 +139,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
header_bcx.cond_br(keep_going, body_bcx.llbb(), next_bcx.llbb());
|
||||
|
||||
tr_elem.val.store(&body_bcx,
|
||||
LvalueRef::new_sized(current, tr_elem.layout, dest.alignment));
|
||||
PlaceRef::new_sized(current, tr_elem.layout, dest.alignment));
|
||||
|
||||
let next = body_bcx.inbounds_gep(current, &[C_usize(bcx.ccx, 1)]);
|
||||
body_bcx.br(header_bcx.llbb());
|
||||
@ -486,11 +486,11 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
|
||||
fn evaluate_array_len(&mut self,
|
||||
bcx: &Builder<'a, 'tcx>,
|
||||
lvalue: &mir::Lvalue<'tcx>) -> ValueRef
|
||||
lvalue: &mir::Place<'tcx>) -> ValueRef
|
||||
{
|
||||
// ZST are passed as operands and require special handling
|
||||
// because trans_lvalue() panics if Local is operand.
|
||||
if let mir::Lvalue::Local(index) = *lvalue {
|
||||
if let mir::Place::Local(index) = *lvalue {
|
||||
if let LocalRef::Operand(Some(op)) = self.locals[index] {
|
||||
if let ty::TyArray(_, n) = op.layout.ty.sty {
|
||||
let n = n.val.to_const_int().unwrap().to_u64().unwrap();
|
||||
|
@ -26,9 +26,9 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
self.set_debug_loc(&bcx, statement.source_info);
|
||||
match statement.kind {
|
||||
mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
|
||||
if let mir::Lvalue::Local(index) = *lvalue {
|
||||
if let mir::Place::Local(index) = *lvalue {
|
||||
match self.locals[index] {
|
||||
LocalRef::Lvalue(tr_dest) => {
|
||||
LocalRef::Place(tr_dest) => {
|
||||
self.trans_rvalue(bcx, tr_dest, rvalue)
|
||||
}
|
||||
LocalRef::Operand(None) => {
|
||||
@ -59,13 +59,13 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
bcx
|
||||
}
|
||||
mir::StatementKind::StorageLive(local) => {
|
||||
if let LocalRef::Lvalue(tr_lval) = self.locals[local] {
|
||||
if let LocalRef::Place(tr_lval) = self.locals[local] {
|
||||
tr_lval.storage_live(&bcx);
|
||||
}
|
||||
bcx
|
||||
}
|
||||
mir::StatementKind::StorageDead(local) => {
|
||||
if let LocalRef::Lvalue(tr_lval) = self.locals[local] {
|
||||
if let LocalRef::Place(tr_lval) = self.locals[local] {
|
||||
tr_lval.storage_dead(&bcx);
|
||||
}
|
||||
bcx
|
||||
|
@ -227,7 +227,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
||||
}
|
||||
|
||||
/// Get the LLVM type corresponding to a Rust type, i.e. `rustc::ty::Ty`.
|
||||
/// The pointee type of the pointer in `LvalueRef` is always this type.
|
||||
/// The pointee type of the pointer in `PlaceRef` is always this type.
|
||||
/// For sized types, it is also the right LLVM type for an `alloca`
|
||||
/// containing a value of that type, and most immediates (except `bool`).
|
||||
/// Unsized types, however, are represented by a "minimal unit", e.g.
|
||||
|
@ -639,7 +639,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||
|
||||
fn visit_static(&mut self,
|
||||
static_: &mir::Static<'tcx>,
|
||||
context: mir::visit::LvalueContext<'tcx>,
|
||||
context: mir::visit::PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
debug!("visiting static {:?} @ {:?}", static_.def_id, location);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user