1
Fork 0

Put Local, Static and Promoted as one Base variant of Place

This commit is contained in:
Santiago Pastorino 2019-02-22 05:24:03 +01:00
parent 1999a22881
commit 0f993d5a7a
63 changed files with 441 additions and 352 deletions

View file

@ -209,13 +209,13 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Place<'gcx> {
hasher: &mut StableHasher<W>) { hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher); mem::discriminant(self).hash_stable(hcx, hasher);
match *self { match *self {
mir::Place::Local(ref local) => { mir::Place::Base(mir::PlaceBase::Local(ref local)) => {
local.hash_stable(hcx, hasher); local.hash_stable(hcx, hasher);
} }
mir::Place::Static(ref statik) => { mir::Place::Base(mir::PlaceBase::Static(ref statik)) => {
statik.hash_stable(hcx, hasher); statik.hash_stable(hcx, hasher);
} }
mir::Place::Promoted(ref promoted) => { mir::Place::Base(mir::PlaceBase::Promoted(ref promoted)) => {
promoted.hash_stable(hcx, hasher); promoted.hash_stable(hcx, hasher);
} }
mir::Place::Projection(ref place_projection) => { mir::Place::Projection(ref place_projection) => {

View file

@ -1896,6 +1896,14 @@ impl<'tcx> Debug for Statement<'tcx> {
/// changing or disturbing program state. /// changing or disturbing program state.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub enum Place<'tcx> { pub enum Place<'tcx> {
Base(PlaceBase<'tcx>),
/// projection out of a place (access a field, deref a pointer, etc)
Projection(Box<PlaceProjection<'tcx>>),
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub enum PlaceBase<'tcx> {
/// local variable /// local variable
Local(Local), Local(Local),
@ -1904,9 +1912,6 @@ pub enum Place<'tcx> {
/// Constant code promoted to an injected static /// Constant code promoted to an injected static
Promoted(Box<(Promoted, Ty<'tcx>)>), Promoted(Box<(Promoted, Ty<'tcx>)>),
/// projection out of a place (access a field, deref a pointer, etc)
Projection(Box<PlaceProjection<'tcx>>),
} }
/// The `DefId` of a static, along with its normalized type (which is /// The `DefId` of a static, along with its normalized type (which is
@ -1994,6 +1999,8 @@ newtype_index! {
} }
impl<'tcx> Place<'tcx> { impl<'tcx> Place<'tcx> {
pub const RETURN_PLACE: Place<'tcx> = Place::Base(PlaceBase::Local(RETURN_PLACE));
pub fn field(self, f: Field, ty: Ty<'tcx>) -> Place<'tcx> { pub fn field(self, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
self.elem(ProjectionElem::Field(f, ty)) self.elem(ProjectionElem::Field(f, ty))
} }
@ -2020,9 +2027,9 @@ impl<'tcx> Place<'tcx> {
// FIXME: can we safely swap the semantics of `fn base_local` below in here instead? // FIXME: can we safely swap the semantics of `fn base_local` below in here instead?
pub fn local(&self) -> Option<Local> { pub fn local(&self) -> Option<Local> {
match self { match self {
Place::Local(local) | Place::Base(PlaceBase::Local(local)) |
Place::Projection(box Projection { Place::Projection(box Projection {
base: Place::Local(local), base: Place::Base(PlaceBase::Local(local)),
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
}) => Some(*local), }) => Some(*local),
_ => None, _ => None,
@ -2032,9 +2039,9 @@ impl<'tcx> Place<'tcx> {
/// Finds the innermost `Local` from this `Place`. /// Finds the innermost `Local` from this `Place`.
pub fn base_local(&self) -> Option<Local> { pub fn base_local(&self) -> Option<Local> {
match self { match self {
Place::Local(local) => Some(*local), Place::Base(PlaceBase::Local(local)) => Some(*local),
Place::Projection(box Projection { base, elem: _ }) => base.base_local(), Place::Projection(box Projection { base, elem: _ }) => base.base_local(),
Place::Promoted(..) | Place::Static(..) => None, Place::Base(PlaceBase::Promoted(..)) | Place::Base(PlaceBase::Static(..)) => None,
} }
} }
} }
@ -2044,14 +2051,19 @@ impl<'tcx> Debug for Place<'tcx> {
use self::Place::*; use self::Place::*;
match *self { match *self {
Local(id) => write!(fmt, "{:?}", id), Base(PlaceBase::Local(id)) => write!(fmt, "{:?}", id),
Static(box self::Static { def_id, ty }) => write!( Base(PlaceBase::Static(box self::Static { def_id, ty })) => write!(
fmt, fmt,
"({}: {:?})", "({}: {:?})",
ty::tls::with(|tcx| tcx.item_path_str(def_id)), ty::tls::with(|tcx| tcx.item_path_str(def_id)),
ty ty
), ),
Promoted(ref promoted) => write!(fmt, "({:?}: {:?})", promoted.0, promoted.1), Base(PlaceBase::Promoted(ref promoted)) => write!(
fmt,
"({:?}: {:?})",
promoted.0,
promoted.1
),
Projection(ref data) => match data.elem { Projection(ref data) => match data.elem {
ProjectionElem::Downcast(ref adt_def, index) => { ProjectionElem::Downcast(ref adt_def, index) => {
write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].ident) write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].ident)

View file

@ -158,10 +158,10 @@ impl<'tcx> Place<'tcx> {
where D: HasLocalDecls<'tcx> where D: HasLocalDecls<'tcx>
{ {
match *self { match *self {
Place::Local(index) => Place::Base(PlaceBase::Local(index)) =>
PlaceTy::Ty { ty: local_decls.local_decls()[index].ty }, PlaceTy::Ty { ty: local_decls.local_decls()[index].ty },
Place::Promoted(ref data) => PlaceTy::Ty { ty: data.1 }, Place::Base(PlaceBase::Promoted(ref data)) => PlaceTy::Ty { ty: data.1 },
Place::Static(ref data) => Place::Base(PlaceBase::Static(ref data)) =>
PlaceTy::Ty { ty: data.ty }, PlaceTy::Ty { ty: data.ty },
Place::Projection(ref proj) => Place::Projection(ref proj) =>
proj.base.ty(local_decls, tcx).projection_ty(tcx, &proj.elem), proj.base.ty(local_decls, tcx).projection_ty(tcx, &proj.elem),

View file

@ -733,13 +733,13 @@ macro_rules! make_mir_visitor {
context: PlaceContext<'tcx>, context: PlaceContext<'tcx>,
location: Location) { location: Location) {
match place { match place {
Place::Local(local) => { Place::Base(PlaceBase::Local(local)) => {
self.visit_local(local, context, location); self.visit_local(local, context, location);
} }
Place::Static(static_) => { Place::Base(PlaceBase::Static(static_)) => {
self.visit_static(static_, context, location); self.visit_static(static_, context, location);
} }
Place::Promoted(promoted) => { Place::Base(PlaceBase::Promoted(promoted)) => {
self.visit_ty(& $($mutability)? promoted.1, TyContext::Location(location)); self.visit_ty(& $($mutability)? promoted.1, TyContext::Location(location));
}, },
Place::Projection(proj) => { Place::Projection(proj) => {

View file

@ -103,7 +103,7 @@ impl<'mir, 'a: 'mir, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
location: Location) { location: Location) {
debug!("visit_assign(block={:?}, place={:?}, rvalue={:?})", block, place, rvalue); debug!("visit_assign(block={:?}, place={:?}, rvalue={:?})", block, place, rvalue);
if let mir::Place::Local(index) = *place { if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place {
self.assign(index, location); self.assign(index, location);
if !self.fx.rvalue_creates_operand(rvalue) { if !self.fx.rvalue_creates_operand(rvalue) {
self.not_ssa(index); self.not_ssa(index);
@ -245,7 +245,8 @@ impl<'mir, 'a: 'mir, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
} }
PlaceContext::MutatingUse(MutatingUseContext::Drop) => { PlaceContext::MutatingUse(MutatingUseContext::Drop) => {
let ty = mir::Place::Local(local).ty(self.fx.mir, self.fx.cx.tcx()); let ty = mir::Place::Base(mir::PlaceBase::Local(local)).ty(self.fx.mir,
self.fx.cx.tcx());
let ty = self.fx.monomorphize(&ty.to_ty(self.fx.cx.tcx())); let ty = self.fx.monomorphize(&ty.to_ty(self.fx.cx.tcx()));
// Only need the place if we're actually dropping it. // Only need the place if we're actually dropping it.

View file

@ -249,7 +249,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
PassMode::Direct(_) | PassMode::Pair(..) => { PassMode::Direct(_) | PassMode::Pair(..) => {
let op = let op =
self.codegen_consume(&mut bx, &mir::Place::Local(mir::RETURN_PLACE)); self.codegen_consume(&mut bx, &mir::Place::RETURN_PLACE);
if let Ref(llval, _, align) = op.val { if let Ref(llval, _, align) = op.val {
bx.load(llval, align) bx.load(llval, align)
} else { } else {
@ -615,8 +615,12 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// The shuffle array argument is usually not an explicit constant, // The shuffle array argument is usually not an explicit constant,
// but specified directly in the code. This means it gets promoted // but specified directly in the code. This means it gets promoted
// and we can then extract the value by evaluating the promoted. // and we can then extract the value by evaluating the promoted.
mir::Operand::Copy(mir::Place::Promoted(box(index, ty))) | mir::Operand::Copy(
mir::Operand::Move(mir::Place::Promoted(box(index, ty))) => { mir::Place::Base(mir::PlaceBase::Promoted(box(index, ty)))
) |
mir::Operand::Move(
mir::Place::Base(mir::PlaceBase::Promoted(box(index, ty)))
) => {
let param_env = ty::ParamEnv::reveal_all(); let param_env = ty::ParamEnv::reveal_all();
let cid = mir::interpret::GlobalId { let cid = mir::interpret::GlobalId {
instance: self.instance, instance: self.instance,
@ -1106,7 +1110,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if fn_ret.is_ignore() { if fn_ret.is_ignore() {
return ReturnDest::Nothing; return ReturnDest::Nothing;
} }
let dest = if let mir::Place::Local(index) = *dest { let dest = if let mir::Place::Base(mir::PlaceBase::Local(index)) = *dest {
match self.locals[index] { match self.locals[index] {
LocalRef::Place(dest) => dest, LocalRef::Place(dest) => dest,
LocalRef::UnsizedPlace(_) => bug!("return type must be sized"), LocalRef::UnsizedPlace(_) => bug!("return type must be sized"),
@ -1161,7 +1165,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
src: &mir::Operand<'tcx>, src: &mir::Operand<'tcx>,
dst: &mir::Place<'tcx> dst: &mir::Place<'tcx>
) { ) {
if let mir::Place::Local(index) = *dst { if let mir::Place::Base(mir::PlaceBase::Local(index)) = *dst {
match self.locals[index] { match self.locals[index] {
LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place), LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"), LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"),

View file

@ -378,7 +378,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// watch out for locals that do not have an // watch out for locals that do not have an
// alloca; they are handled somewhat differently // alloca; they are handled somewhat differently
if let mir::Place::Local(index) = *place { if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place {
match self.locals[index] { match self.locals[index] {
LocalRef::Operand(Some(o)) => { LocalRef::Operand(Some(o)) => {
return Some(o); return Some(o);

View file

@ -392,7 +392,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let cx = self.cx; let cx = self.cx;
let tcx = self.cx.tcx(); let tcx = self.cx.tcx();
if let mir::Place::Local(index) = *place { if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place {
match self.locals[index] { match self.locals[index] {
LocalRef::Place(place) => { LocalRef::Place(place) => {
return place; return place;
@ -407,8 +407,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
let result = match *place { let result = match *place {
mir::Place::Local(_) => bug!(), // handled above mir::Place::Base(mir::PlaceBase::Local(_)) => bug!(), // handled above
mir::Place::Promoted(box (index, ty)) => { mir::Place::Base(mir::PlaceBase::Promoted(box (index, ty))) => {
let param_env = ty::ParamEnv::reveal_all(); let param_env = ty::ParamEnv::reveal_all();
let cid = mir::interpret::GlobalId { let cid = mir::interpret::GlobalId {
instance: self.instance, instance: self.instance,
@ -435,7 +435,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
} }
} }
mir::Place::Static(box mir::Static { def_id, ty }) => { mir::Place::Base(mir::PlaceBase::Static(box mir::Static { def_id, ty })) => {
// NB: The layout of a static may be unsized as is the case when working // NB: The layout of a static may be unsized as is the case when working
// with a static that is an extern_type. // with a static that is an extern_type.
let layout = cx.layout_of(self.monomorphize(&ty)); let layout = cx.layout_of(self.monomorphize(&ty));
@ -457,7 +457,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
cg_base.project_field(bx, field.index()) cg_base.project_field(bx, field.index())
} }
mir::ProjectionElem::Index(index) => { mir::ProjectionElem::Index(index) => {
let index = &mir::Operand::Copy(mir::Place::Local(index)); let index = &mir::Operand::Copy(
mir::Place::Base(mir::PlaceBase::Local(index))
);
let index = self.codegen_operand(bx, index); let index = self.codegen_operand(bx, index);
let llindex = index.immediate(); let llindex = index.immediate();
cg_base.project_index(bx, llindex) cg_base.project_index(bx, llindex)

View file

@ -534,7 +534,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
) -> Bx::Value { ) -> Bx::Value {
// ZST are passed as operands and require special handling // ZST are passed as operands and require special handling
// because codegen_place() panics if Local is operand. // because codegen_place() panics if Local is operand.
if let mir::Place::Local(index) = *place { if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place {
if let LocalRef::Operand(Some(op)) = self.locals[index] { if let LocalRef::Operand(Some(op)) = self.locals[index] {
if let ty::Array(_, n) = op.layout.ty.sty { if let ty::Array(_, n) = op.layout.ty.sty {
let n = n.unwrap_usize(bx.cx().tcx()); let n = n.unwrap_usize(bx.cx().tcx());

View file

@ -17,7 +17,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.set_debug_loc(&mut bx, statement.source_info); self.set_debug_loc(&mut bx, statement.source_info);
match statement.kind { match statement.kind {
mir::StatementKind::Assign(ref place, ref rvalue) => { mir::StatementKind::Assign(ref place, ref rvalue) => {
if let mir::Place::Local(index) = *place { if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place {
match self.locals[index] { match self.locals[index] {
LocalRef::Place(cg_dest) => { LocalRef::Place(cg_dest) => {
self.codegen_rvalue(bx, cg_dest, rvalue) self.codegen_rvalue(bx, cg_dest, rvalue)

View file

@ -333,7 +333,7 @@ impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
// TEMP = &foo // TEMP = &foo
// //
// so extract `temp`. // so extract `temp`.
let temp = if let &mir::Place::Local(temp) = assigned_place { let temp = if let &mir::Place::Base(mir::PlaceBase::Local(temp)) = assigned_place {
temp temp
} else { } else {
span_bug!( span_bug!(

View file

@ -8,7 +8,7 @@ use rustc::middle::region::ScopeTree;
use rustc::mir::{ use rustc::mir::{
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, Constant, self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, Constant,
ConstraintCategory, Field, Local, LocalDecl, LocalKind, Location, Operand, ConstraintCategory, Field, Local, LocalDecl, LocalKind, Location, Operand,
Place, PlaceProjection, ProjectionElem, Rvalue, Statement, StatementKind, Place, PlaceBase, PlaceProjection, ProjectionElem, Rvalue, Statement, StatementKind,
TerminatorKind, VarBindingForm, TerminatorKind, VarBindingForm,
}; };
use rustc::ty::{self, DefIdTree}; use rustc::ty::{self, DefIdTree};
@ -220,7 +220,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
); );
} }
} }
if let Place::Local(local) = place { if let Place::Base(PlaceBase::Local(local)) = place {
let decl = &self.mir.local_decls[*local]; let decl = &self.mir.local_decls[*local];
err.span_label( err.span_label(
decl.source_info.span, decl.source_info.span,
@ -679,7 +679,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
let borrow_span = borrow_spans.var_or_use(); let borrow_span = borrow_spans.var_or_use();
let proper_span = match *root_place { let proper_span = match *root_place {
Place::Local(local) => self.mir.local_decls[local].source_info.span, Place::Base(PlaceBase::Local(local)) => self.mir.local_decls[local].source_info.span,
_ => drop_span, _ => drop_span,
}; };
@ -1061,7 +1061,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
let (place_desc, note) = if let Some(place_desc) = opt_place_desc { let (place_desc, note) = if let Some(place_desc) = opt_place_desc {
let local_kind = match borrow.borrowed_place { let local_kind = match borrow.borrowed_place {
Place::Local(local) => { Place::Base(PlaceBase::Local(local)) => {
match self.mir.local_kind(local) { match self.mir.local_kind(local) {
LocalKind::ReturnPointer LocalKind::ReturnPointer
| LocalKind::Temp => bug!("temporary or return pointer with a name"), | LocalKind::Temp => bug!("temporary or return pointer with a name"),
@ -1086,7 +1086,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All) let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All)
.last() .last()
.unwrap(); .unwrap();
let local = if let Place::Local(local) = *root_place { let local = if let Place::Base(PlaceBase::Local(local)) = *root_place {
local local
} else { } else {
bug!("report_cannot_return_reference_to_local: not a local") bug!("report_cannot_return_reference_to_local: not a local")
@ -1385,7 +1385,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
assigned_span: Span, assigned_span: Span,
err_place: &Place<'tcx>, err_place: &Place<'tcx>,
) { ) {
let (from_arg, local_decl) = if let Place::Local(local) = *err_place { let (from_arg, local_decl) = if let Place::Base(PlaceBase::Local(local)) = *err_place {
if let LocalKind::Arg = self.mir.local_kind(local) { if let LocalKind::Arg = self.mir.local_kind(local) {
(true, Some(&self.mir.local_decls[local])) (true, Some(&self.mir.local_decls[local]))
} else { } else {
@ -1600,13 +1600,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
including_downcast: &IncludingDowncast, including_downcast: &IncludingDowncast,
) -> Result<(), ()> { ) -> Result<(), ()> {
match *place { match *place {
Place::Promoted(_) => { Place::Base(PlaceBase::Promoted(_)) => {
buf.push_str("promoted"); buf.push_str("promoted");
} }
Place::Local(local) => { Place::Base(PlaceBase::Local(local)) => {
self.append_local_to_string(local, buf)?; self.append_local_to_string(local, buf)?;
} }
Place::Static(ref static_) => { Place::Base(PlaceBase::Static(ref static_)) => {
buf.push_str(&self.infcx.tcx.item_name(static_.def_id).to_string()); buf.push_str(&self.infcx.tcx.item_name(static_.def_id).to_string());
} }
Place::Projection(ref proj) => { Place::Projection(ref proj) => {
@ -1630,7 +1630,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
autoderef, autoderef,
&including_downcast, &including_downcast,
)?; )?;
} else if let Place::Local(local) = proj.base { } else if let Place::Base(PlaceBase::Local(local)) = proj.base {
if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) = if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) =
self.mir.local_decls[local].is_user_variable self.mir.local_decls[local].is_user_variable
{ {
@ -1742,12 +1742,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
/// End-user visible description of the `field`nth field of `base` /// End-user visible description of the `field`nth field of `base`
fn describe_field(&self, base: &Place<'_>, field: Field) -> String { fn describe_field(&self, base: &Place<'_>, field: Field) -> String {
match *base { match *base {
Place::Local(local) => { Place::Base(PlaceBase::Local(local)) => {
let local = &self.mir.local_decls[local]; let local = &self.mir.local_decls[local];
self.describe_field_from_ty(&local.ty, field) self.describe_field_from_ty(&local.ty, field)
} }
Place::Promoted(ref prom) => self.describe_field_from_ty(&prom.1, field), Place::Base(PlaceBase::Promoted(ref prom)) =>
Place::Static(ref static_) => self.describe_field_from_ty(&static_.ty, field), self.describe_field_from_ty(&prom.1, field),
Place::Base(PlaceBase::Static(ref static_)) =>
self.describe_field_from_ty(&static_.ty, field),
Place::Projection(ref proj) => match proj.elem { Place::Projection(ref proj) => match proj.elem {
ProjectionElem::Deref => self.describe_field(&proj.base, field), ProjectionElem::Deref => self.describe_field(&proj.base, field),
ProjectionElem::Downcast(def, variant_index) => ProjectionElem::Downcast(def, variant_index) =>
@ -1809,7 +1811,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
/// Checks if a place is a thread-local static. /// Checks if a place is a thread-local static.
pub fn is_place_thread_local(&self, place: &Place<'tcx>) -> bool { pub fn is_place_thread_local(&self, place: &Place<'tcx>) -> bool {
if let Place::Static(statik) = place { if let Place::Base(PlaceBase::Static(statik)) = place {
let attrs = self.infcx.tcx.get_attrs(statik.def_id); let attrs = self.infcx.tcx.get_attrs(statik.def_id);
let is_thread_local = attrs.iter().any(|attr| attr.check_name("thread_local")); let is_thread_local = attrs.iter().any(|attr| attr.check_name("thread_local"));
@ -1827,7 +1829,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
fn classify_drop_access_kind(&self, place: &Place<'tcx>) -> StorageDeadOrDrop<'tcx> { fn classify_drop_access_kind(&self, place: &Place<'tcx>) -> StorageDeadOrDrop<'tcx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
match place { match place {
Place::Local(_) | Place::Static(_) | Place::Promoted(_) => { Place::Base(PlaceBase::Local(_)) |
Place::Base(PlaceBase::Static(_)) |
Place::Base(PlaceBase::Promoted(_)) => {
StorageDeadOrDrop::LocalStorageDead StorageDeadOrDrop::LocalStorageDead
} }
Place::Projection(box PlaceProjection { base, elem }) => { Place::Projection(box PlaceProjection { base, elem }) => {
@ -1912,7 +1916,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
); );
// Check that the initial assignment of the reserve location is into a temporary. // Check that the initial assignment of the reserve location is into a temporary.
let mut target = *match reservation { let mut target = *match reservation {
Place::Local(local) if self.mir.local_kind(*local) == LocalKind::Temp => local, Place::Base(PlaceBase::Local(local))
if self.mir.local_kind(*local) == LocalKind::Temp => local,
_ => return None, _ => return None,
}; };
@ -1924,8 +1929,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
"annotate_argument_and_return_for_borrow: target={:?} stmt={:?}", "annotate_argument_and_return_for_borrow: target={:?} stmt={:?}",
target, stmt target, stmt
); );
if let StatementKind::Assign(Place::Local(assigned_to), box rvalue) = &stmt.kind if let StatementKind::Assign(
{ Place::Base(PlaceBase::Local(assigned_to)),
box rvalue
) = &stmt.kind {
debug!( debug!(
"annotate_argument_and_return_for_borrow: assigned_to={:?} \ "annotate_argument_and_return_for_borrow: assigned_to={:?} \
rvalue={:?}", rvalue={:?}",
@ -2048,7 +2055,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
target, terminator target, terminator
); );
if let TerminatorKind::Call { if let TerminatorKind::Call {
destination: Some((Place::Local(assigned_to), _)), destination: Some((Place::Base(PlaceBase::Local(assigned_to)), _)),
args, args,
.. ..
} = &terminator.kind } = &terminator.kind
@ -2496,7 +2503,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
.get(location.statement_index) .get(location.statement_index)
{ {
Some(&Statement { Some(&Statement {
kind: StatementKind::Assign(Place::Local(local), _), kind: StatementKind::Assign(Place::Base(PlaceBase::Local(local)), _),
.. ..
}) => local, }) => local,
_ => return OtherUse(use_span), _ => return OtherUse(use_span),
@ -2522,7 +2529,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
def_id, is_generator, places def_id, is_generator, places
); );
if let Some((args_span, var_span)) = self.closure_span( if let Some((args_span, var_span)) = self.closure_span(
*def_id, &Place::Local(target), places *def_id, &Place::Base(PlaceBase::Local(target)), places
) { ) {
return ClosureUse { return ClosureUse {
is_generator, is_generator,

View file

@ -8,7 +8,7 @@ use rustc::infer::InferCtxt;
use rustc::lint::builtin::UNUSED_MUT; use rustc::lint::builtin::UNUSED_MUT;
use rustc::middle::borrowck::SignalledError; use rustc::middle::borrowck::SignalledError;
use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place}; use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place, PlaceBase};
use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind}; use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind};
use rustc::mir::{Terminator, TerminatorKind}; use rustc::mir::{Terminator, TerminatorKind};
use rustc::ty::query::Providers; use rustc::ty::query::Providers;
@ -588,7 +588,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
StatementKind::StorageDead(local) => { StatementKind::StorageDead(local) => {
self.access_place( self.access_place(
ContextKind::StorageDead.new(location), ContextKind::StorageDead.new(location),
(&Place::Local(local), span), (&Place::Base(PlaceBase::Local(local)), span),
(Shallow(None), Write(WriteKind::StorageDeadOrDrop)), (Shallow(None), Write(WriteKind::StorageDeadOrDrop)),
LocalMutationIsAllowed::Yes, LocalMutationIsAllowed::Yes,
flow_state, flow_state,
@ -1104,7 +1104,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// Special case: you can assign a immutable local variable // Special case: you can assign a immutable local variable
// (e.g., `x = ...`) so long as it has never been initialized // (e.g., `x = ...`) so long as it has never been initialized
// before (at this point in the flow). // before (at this point in the flow).
if let &Place::Local(local) = place_span.0 { if let &Place::Base(PlaceBase::Local(local)) = place_span.0 {
if let Mutability::Not = self.mir.local_decls[local].mutability { if let Mutability::Not = self.mir.local_decls[local].mutability {
// check for reassignments to immutable local variables // check for reassignments to immutable local variables
self.check_if_reassignment_to_immutable_state( self.check_if_reassignment_to_immutable_state(
@ -1231,8 +1231,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// captures of a closure are copied/moved directly // captures of a closure are copied/moved directly
// when generating MIR. // when generating MIR.
match operands[field.index()] { match operands[field.index()] {
Operand::Move(Place::Local(local)) Operand::Move(Place::Base(PlaceBase::Local(local)))
| Operand::Copy(Place::Local(local)) => { | Operand::Copy(Place::Base(PlaceBase::Local(local))) => {
self.used_mut.insert(local); self.used_mut.insert(local);
} }
Operand::Move(ref place @ Place::Projection(_)) Operand::Move(ref place @ Place::Projection(_))
@ -1242,10 +1242,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
self.used_mut_upvars.push(field); self.used_mut_upvars.push(field);
} }
} }
Operand::Move(Place::Static(..)) Operand::Move(Place::Base(PlaceBase::Static(..)))
| Operand::Copy(Place::Static(..)) | Operand::Copy(Place::Base(PlaceBase::Static(..)))
| Operand::Move(Place::Promoted(..)) | Operand::Move(Place::Base(PlaceBase::Promoted(..)))
| Operand::Copy(Place::Promoted(..)) | Operand::Copy(Place::Base(PlaceBase::Promoted(..)))
| Operand::Constant(..) => {} | Operand::Constant(..) => {}
} }
} }
@ -1328,14 +1328,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// //
// FIXME: allow thread-locals to borrow other thread locals? // FIXME: allow thread-locals to borrow other thread locals?
let (might_be_alive, will_be_dropped) = match root_place { let (might_be_alive, will_be_dropped) = match root_place {
Place::Promoted(_) => (true, false), Place::Base(PlaceBase::Promoted(_)) => (true, false),
Place::Static(_) => { Place::Base(PlaceBase::Static(_)) => {
// Thread-locals might be dropped after the function exits, but // Thread-locals might be dropped after the function exits, but
// "true" statics will never be. // "true" statics will never be.
let is_thread_local = self.is_place_thread_local(&root_place); let is_thread_local = self.is_place_thread_local(&root_place);
(true, is_thread_local) (true, is_thread_local)
} }
Place::Local(_) => { Place::Base(PlaceBase::Local(_)) => {
// Locals are always dropped at function exit, and if they // Locals are always dropped at function exit, and if they
// have a destructor it would've been called already. // have a destructor it would've been called already.
(false, self.locals_are_invalidated_at_exit) (false, self.locals_are_invalidated_at_exit)
@ -1594,10 +1594,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
last_prefix = prefix; last_prefix = prefix;
} }
match *last_prefix { match *last_prefix {
Place::Local(_) => panic!("should have move path for every Local"), Place::Base(PlaceBase::Local(_)) => panic!("should have move path for every Local"),
Place::Projection(_) => panic!("PrefixSet::All meant don't stop for Projection"), Place::Projection(_) => panic!("PrefixSet::All meant don't stop for Projection"),
Place::Promoted(_) | Place::Base(PlaceBase::Promoted(_)) |
Place::Static(_) => Err(NoMovePathFound::ReachedStatic), Place::Base(PlaceBase::Static(_)) => Err(NoMovePathFound::ReachedStatic),
} }
} }
@ -1623,8 +1623,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
let mut place = place; let mut place = place;
loop { loop {
match *place { match *place {
Place::Promoted(_) | Place::Base(PlaceBase::Promoted(_)) |
Place::Local(_) | Place::Static(_) => { Place::Base(PlaceBase::Local(_)) | Place::Base(PlaceBase::Static(_)) => {
// assigning to `x` does not require `x` be initialized. // assigning to `x` does not require `x` be initialized.
break; break;
} }
@ -1947,7 +1947,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
) { ) {
match root_place { match root_place {
RootPlace { RootPlace {
place: Place::Local(local), place: Place::Base(PlaceBase::Local(local)),
is_local_mutation_allowed, is_local_mutation_allowed,
} => { } => {
// If the local may have been initialized, and it is now currently being // If the local may have been initialized, and it is now currently being
@ -1972,11 +1972,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
} }
} }
RootPlace { RootPlace {
place: Place::Promoted(..), place: Place::Base(PlaceBase::Promoted(..)),
is_local_mutation_allowed: _, is_local_mutation_allowed: _,
} => {} } => {}
RootPlace { RootPlace {
place: Place::Static(..), place: Place::Base(PlaceBase::Static(..)),
is_local_mutation_allowed: _, is_local_mutation_allowed: _,
} => {} } => {}
} }
@ -1990,7 +1990,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
is_local_mutation_allowed: LocalMutationIsAllowed, is_local_mutation_allowed: LocalMutationIsAllowed,
) -> Result<RootPlace<'d, 'tcx>, &'d Place<'tcx>> { ) -> Result<RootPlace<'d, 'tcx>, &'d Place<'tcx>> {
match *place { match *place {
Place::Local(local) => { Place::Base(PlaceBase::Local(local)) => {
let local = &self.mir.local_decls[local]; let local = &self.mir.local_decls[local];
match local.mutability { match local.mutability {
Mutability::Not => match is_local_mutation_allowed { Mutability::Not => match is_local_mutation_allowed {
@ -2012,11 +2012,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
} }
// The rules for promotion are made by `qualify_consts`, there wouldn't even be a // The rules for promotion are made by `qualify_consts`, there wouldn't even be a
// `Place::Promoted` if the promotion weren't 100% legal. So we just forward this // `Place::Promoted` if the promotion weren't 100% legal. So we just forward this
Place::Promoted(_) => Ok(RootPlace { Place::Base(PlaceBase::Promoted(_)) => Ok(RootPlace {
place, place,
is_local_mutation_allowed, is_local_mutation_allowed,
}), }),
Place::Static(ref static_) => { Place::Base(PlaceBase::Static(ref static_)) => {
if self.infcx.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) { if self.infcx.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) {
Err(place) Err(place)
} else { } else {

View file

@ -111,7 +111,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
// If that ever stops being the case, then the ever initialized // If that ever stops being the case, then the ever initialized
// flow could be used. // flow could be used.
if let Some(StatementKind::Assign( if let Some(StatementKind::Assign(
Place::Local(local), Place::Base(PlaceBase::Local(local)),
box Rvalue::Use(Operand::Move(move_from)), box Rvalue::Use(Operand::Move(move_from)),
)) = self.mir.basic_blocks()[location.block] )) = self.mir.basic_blocks()[location.block]
.statements .statements

View file

@ -1,8 +1,8 @@
use rustc::hir; use rustc::hir;
use rustc::hir::Node; use rustc::hir::Node;
use rustc::mir::{self, BindingForm, Constant, ClearCrossCrate, Local, Location, Mir}; use rustc::mir::{self, BindingForm, Constant, ClearCrossCrate, Local, Location, Mir};
use rustc::mir::{Mutability, Operand, Place, Projection, ProjectionElem, Static, Terminator}; use rustc::mir::{Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static};
use rustc::mir::TerminatorKind; use rustc::mir::{Terminator, TerminatorKind};
use rustc::ty::{self, Const, DefIdTree, TyS, TyKind, TyCtxt}; use rustc::ty::{self, Const, DefIdTree, TyS, TyKind, TyCtxt};
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;
use syntax_pos::Span; use syntax_pos::Span;
@ -45,9 +45,9 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
debug!("report_mutability_error: access_place_desc={:?}", access_place_desc); debug!("report_mutability_error: access_place_desc={:?}", access_place_desc);
match the_place_err { match the_place_err {
Place::Local(local) => { Place::Base(PlaceBase::Local(local)) => {
item_msg = format!("`{}`", access_place_desc.unwrap()); item_msg = format!("`{}`", access_place_desc.unwrap());
if let Place::Local(_) = access_place { if let Place::Base(PlaceBase::Local(_)) = access_place {
reason = ", as it is not declared as mutable".to_string(); reason = ", as it is not declared as mutable".to_string();
} else { } else {
let name = self.mir.local_decls[*local] let name = self.mir.local_decls[*local]
@ -78,7 +78,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
base, base,
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
}) => { }) => {
if *base == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty() { if *base == Place::Base(PlaceBase::Local(Local::new(1))) &&
!self.mir.upvar_decls.is_empty() {
item_msg = format!("`{}`", access_place_desc.unwrap()); item_msg = format!("`{}`", access_place_desc.unwrap());
debug_assert!(self.mir.local_decls[Local::new(1)].ty.is_region_ptr()); debug_assert!(self.mir.local_decls[Local::new(1)].ty.is_region_ptr());
debug_assert!(is_closure_or_generator( debug_assert!(is_closure_or_generator(
@ -92,7 +93,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
", as `Fn` closures cannot mutate their captured variables".to_string() ", as `Fn` closures cannot mutate their captured variables".to_string()
} }
} else if { } else if {
if let Place::Local(local) = *base { if let Place::Base(PlaceBase::Local(local)) = *base {
if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard))
= self.mir.local_decls[local].is_user_variable { = self.mir.local_decls[local].is_user_variable {
true true
@ -128,10 +129,10 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
} }
} }
Place::Promoted(_) => unreachable!(), Place::Base(PlaceBase::Promoted(_)) => unreachable!(),
Place::Static(box Static { def_id, ty: _ }) => { Place::Base(PlaceBase::Static(box Static { def_id, ty: _ })) => {
if let Place::Static(_) = access_place { if let Place::Base(PlaceBase::Static(_)) = access_place {
item_msg = format!("immutable static item `{}`", access_place_desc.unwrap()); item_msg = format!("immutable static item `{}`", access_place_desc.unwrap());
reason = String::new(); reason = String::new();
} else { } else {
@ -241,7 +242,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
}, },
// Suggest removing a `&mut` from the use of a mutable reference. // Suggest removing a `&mut` from the use of a mutable reference.
Place::Local(local) Place::Base(PlaceBase::Local(local))
if { if {
self.mir.local_decls.get(*local).map(|local_decl| { self.mir.local_decls.get(*local).map(|local_decl| {
if let ClearCrossCrate::Set( if let ClearCrossCrate::Set(
@ -276,7 +277,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
// We want to suggest users use `let mut` for local (user // We want to suggest users use `let mut` for local (user
// variable) mutations... // variable) mutations...
Place::Local(local) if self.mir.local_decls[*local].can_be_made_mutable() => { Place::Base(PlaceBase::Local(local))
if self.mir.local_decls[*local].can_be_made_mutable() => {
// ... but it doesn't make sense to suggest it on // ... but it doesn't make sense to suggest it on
// variables that are `ref x`, `ref mut x`, `&self`, // variables that are `ref x`, `ref mut x`, `&self`,
// or `&mut self` (such variables are simply not // or `&mut self` (such variables are simply not
@ -330,7 +332,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
// complete hack to approximate old AST-borrowck // complete hack to approximate old AST-borrowck
// diagnostic: if the span starts with a mutable borrow of // diagnostic: if the span starts with a mutable borrow of
// a local variable, then just suggest the user remove it. // a local variable, then just suggest the user remove it.
Place::Local(_) Place::Base(PlaceBase::Local(_))
if { if {
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
snippet.starts_with("&mut ") snippet.starts_with("&mut ")
@ -344,7 +346,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
} }
Place::Projection(box Projection { Place::Projection(box Projection {
base: Place::Local(local), base: Place::Base(PlaceBase::Local(local)),
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
}) if { }) if {
if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) = if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) =
@ -368,7 +370,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
// FIXME: can this case be generalized to work for an // FIXME: can this case be generalized to work for an
// arbitrary base for the projection? // arbitrary base for the projection?
Place::Projection(box Projection { Place::Projection(box Projection {
base: Place::Local(local), base: Place::Base(PlaceBase::Local(local)),
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
}) if self.mir.local_decls[*local].is_user_variable.is_some() => }) if self.mir.local_decls[*local].is_user_variable.is_some() =>
{ {
@ -447,7 +449,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
Place::Projection(box Projection { Place::Projection(box Projection {
base, base,
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
}) if *base == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty() => }) if *base == Place::Base(PlaceBase::Local(Local::new(1))) &&
!self.mir.upvar_decls.is_empty() =>
{ {
err.span_label(span, format!("cannot {ACT}", ACT = act)); err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_help( err.span_help(
@ -457,7 +460,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
} }
Place::Projection(box Projection { Place::Projection(box Projection {
base: Place::Local(local), base: Place::Base(PlaceBase::Local(local)),
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
}) if error_access == AccessKind::MutableBorrow => { }) if error_access == AccessKind::MutableBorrow => {
err.span_label(span, format!("cannot {ACT}", ACT = act)); err.span_label(span, format!("cannot {ACT}", ACT = act));

View file

@ -6,7 +6,7 @@ use crate::borrow_check::nll::region_infer::values::LivenessValues;
use rustc::infer::InferCtxt; use rustc::infer::InferCtxt;
use rustc::mir::visit::TyContext; use rustc::mir::visit::TyContext;
use rustc::mir::visit::Visitor; use rustc::mir::visit::Visitor;
use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, Rvalue}; use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, PlaceBase, Rvalue};
use rustc::mir::{SourceInfo, Statement, Terminator}; use rustc::mir::{SourceInfo, Statement, Terminator};
use rustc::mir::UserTypeProjection; use rustc::mir::UserTypeProjection;
use rustc::ty::fold::TypeFoldable; use rustc::ty::fold::TypeFoldable;
@ -130,7 +130,7 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
// When we see `X = ...`, then kill borrows of // When we see `X = ...`, then kill borrows of
// `(*X).foo` and so forth. // `(*X).foo` and so forth.
if let Some(all_facts) = self.all_facts { if let Some(all_facts) = self.all_facts {
if let Place::Local(temp) = place { if let Place::Base(PlaceBase::Local(temp)) = place {
if let Some(borrow_indices) = self.borrow_set.local_map.get(temp) { if let Some(borrow_indices) = self.borrow_set.local_map.get(temp) {
all_facts.killed.reserve(borrow_indices.len()); all_facts.killed.reserve(borrow_indices.len());
for &borrow_index in borrow_indices { for &borrow_index in borrow_indices {

View file

@ -6,8 +6,8 @@ use crate::borrow_check::nll::region_infer::{Cause, RegionName};
use crate::borrow_check::nll::ConstraintDescription; use crate::borrow_check::nll::ConstraintDescription;
use crate::borrow_check::{Context, MirBorrowckCtxt, WriteKind}; use crate::borrow_check::{Context, MirBorrowckCtxt, WriteKind};
use rustc::mir::{ use rustc::mir::{
CastKind, ConstraintCategory, FakeReadCause, Local, Location, Mir, Operand, Place, Projection, CastKind, ConstraintCategory, FakeReadCause, Local, Location, Mir, Operand, Place, PlaceBase,
ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, Projection, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind,
}; };
use rustc::ty::{self, TyCtxt}; use rustc::ty::{self, TyCtxt};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
@ -245,7 +245,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
Some(Cause::LiveVar(local, location)) => { Some(Cause::LiveVar(local, location)) => {
let span = mir.source_info(location).span; let span = mir.source_info(location).span;
let spans = self let spans = self
.move_spans(&Place::Local(local), location) .move_spans(&Place::Base(PlaceBase::Local(local)), location)
.or_else(|| self.borrow_spans(span, location)); .or_else(|| self.borrow_spans(span, location));
let borrow_location = context.loc; let borrow_location = context.loc;
@ -265,7 +265,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
let mut should_note_order = false; let mut should_note_order = false;
if mir.local_decls[local].name.is_some() { if mir.local_decls[local].name.is_some() {
if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place { if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place {
if let Place::Local(borrowed_local) = place { if let Place::Base(PlaceBase::Local(borrowed_local)) = place {
let dropped_local_scope = mir.local_decls[local].visibility_scope; let dropped_local_scope = mir.local_decls[local].visibility_scope;
let borrowed_local_scope = let borrowed_local_scope =
mir.local_decls[*borrowed_local].visibility_scope; mir.local_decls[*borrowed_local].visibility_scope;
@ -481,7 +481,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// Just point to the function, to reduce the chance of overlapping spans. // Just point to the function, to reduce the chance of overlapping spans.
let function_span = match func { let function_span = match func {
Operand::Constant(c) => c.span, Operand::Constant(c) => c.span,
Operand::Copy(Place::Local(l)) | Operand::Move(Place::Local(l)) => { Operand::Copy(Place::Base(PlaceBase::Local(l))) |
Operand::Move(Place::Base(PlaceBase::Local(l))) => {
let local_decl = &self.mir.local_decls[*l]; let local_decl = &self.mir.local_decls[*l];
if local_decl.name.is_none() { if local_decl.name.is_none() {
local_decl.source_info.span local_decl.source_info.span
@ -522,7 +523,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// it which simplifies the termination logic. // it which simplifies the termination logic.
let mut queue = vec![location]; let mut queue = vec![location];
let mut target = if let Some(&Statement { let mut target = if let Some(&Statement {
kind: StatementKind::Assign(Place::Local(local), _), kind: StatementKind::Assign(Place::Base(PlaceBase::Local(local)), _),
.. ..
}) = stmt }) = stmt
{ {
@ -547,9 +548,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// The only kind of statement that we care about is assignments... // The only kind of statement that we care about is assignments...
if let StatementKind::Assign(place, box rvalue) = &stmt.kind { if let StatementKind::Assign(place, box rvalue) = &stmt.kind {
let into = match place { let into = match place {
Place::Local(into) => into, Place::Base(PlaceBase::Local(into)) => into,
Place::Projection(box Projection { Place::Projection(box Projection {
base: Place::Local(into), base: Place::Base(PlaceBase::Local(into)),
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
}) => into, }) => into,
_ => { _ => {
@ -563,8 +564,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// If we see a use, we should check whether it is our data, and if so // If we see a use, we should check whether it is our data, and if so
// update the place that we're looking for to that new place. // update the place that we're looking for to that new place.
Rvalue::Use(operand) => match operand { Rvalue::Use(operand) => match operand {
Operand::Copy(Place::Local(from)) Operand::Copy(Place::Base(PlaceBase::Local(from)))
| Operand::Move(Place::Local(from)) | Operand::Move(Place::Base(PlaceBase::Local(from)))
if *from == target => if *from == target =>
{ {
target = *into; target = *into;
@ -574,8 +575,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// If we see a unsized cast, then if it is our data we should check // If we see a unsized cast, then if it is our data we should check
// whether it is being cast to a trait object. // whether it is being cast to a trait object.
Rvalue::Cast(CastKind::Unsize, operand, ty) => match operand { Rvalue::Cast(CastKind::Unsize, operand, ty) => match operand {
Operand::Copy(Place::Local(from)) Operand::Copy(Place::Base(PlaceBase::Local(from)))
| Operand::Move(Place::Local(from)) | Operand::Move(Place::Base(PlaceBase::Local(from)))
if *from == target => if *from == target =>
{ {
debug!("was_captured_by_trait_object: ty={:?}", ty); debug!("was_captured_by_trait_object: ty={:?}", ty);
@ -605,7 +606,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
debug!("was_captured_by_trait_object: terminator={:?}", terminator); debug!("was_captured_by_trait_object: terminator={:?}", terminator);
if let TerminatorKind::Call { if let TerminatorKind::Call {
destination: Some((Place::Local(dest), block)), destination: Some((Place::Base(PlaceBase::Local(dest)), block)),
args, args,
.. ..
} = &terminator.kind } = &terminator.kind
@ -616,7 +617,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
); );
// Check if one of the arguments to this function is the target place. // Check if one of the arguments to this function is the target place.
let found_target = args.iter().any(|arg| { let found_target = args.iter().any(|arg| {
if let Operand::Move(Place::Local(potential)) = arg { if let Operand::Move(Place::Base(PlaceBase::Local(potential))) = arg {
*potential == target *potential == target
} else { } else {
false false

View file

@ -12,7 +12,7 @@ use crate::borrow_check::path_utils::*;
use crate::dataflow::move_paths::indexes::BorrowIndex; use crate::dataflow::move_paths::indexes::BorrowIndex;
use rustc::ty::TyCtxt; use rustc::ty::TyCtxt;
use rustc::mir::visit::Visitor; use rustc::mir::visit::Visitor;
use rustc::mir::{BasicBlock, Location, Mir, Place, Rvalue}; use rustc::mir::{BasicBlock, Location, Mir, Place, PlaceBase, Rvalue};
use rustc::mir::{Statement, StatementKind}; use rustc::mir::{Statement, StatementKind};
use rustc::mir::{Terminator, TerminatorKind}; use rustc::mir::{Terminator, TerminatorKind};
use rustc::mir::{Operand, BorrowKind}; use rustc::mir::{Operand, BorrowKind};
@ -131,7 +131,7 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
StatementKind::StorageDead(local) => { StatementKind::StorageDead(local) => {
self.access_place( self.access_place(
ContextKind::StorageDead.new(location), ContextKind::StorageDead.new(location),
&Place::Local(local), &Place::Base(PlaceBase::Local(local)),
(Shallow(None), Write(WriteKind::StorageDeadOrDrop)), (Shallow(None), Write(WriteKind::StorageDeadOrDrop)),
LocalMutationIsAllowed::Yes, LocalMutationIsAllowed::Yes,
); );

View file

@ -451,10 +451,10 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
) -> PlaceTy<'tcx> { ) -> PlaceTy<'tcx> {
debug!("sanitize_place: {:?}", place); debug!("sanitize_place: {:?}", place);
let place_ty = match *place { let place_ty = match *place {
Place::Local(index) => PlaceTy::Ty { Place::Base(PlaceBase::Local(index)) => PlaceTy::Ty {
ty: self.mir.local_decls[index].ty, ty: self.mir.local_decls[index].ty,
}, },
Place::Promoted(box (_index, sty)) => { Place::Base(PlaceBase::Promoted(box (_index, sty))) => {
let sty = self.sanitize_type(place, sty); let sty = self.sanitize_type(place, sty);
// FIXME -- promoted MIR return types reference // FIXME -- promoted MIR return types reference
// various "free regions" (e.g., scopes and things) // various "free regions" (e.g., scopes and things)
@ -469,7 +469,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
// promoted_mir.return_ty() // promoted_mir.return_ty()
PlaceTy::Ty { ty: sty } PlaceTy::Ty { ty: sty }
} }
Place::Static(box Static { def_id, ty: sty }) => { Place::Base(PlaceBase::Static(box Static { def_id, ty: sty })) => {
let sty = self.sanitize_type(place, sty); let sty = self.sanitize_type(place, sty);
let ty = self.tcx().type_of(def_id); let ty = self.tcx().type_of(def_id);
let ty = self.cx.normalize(ty, location); let ty = self.cx.normalize(ty, location);
@ -553,7 +553,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
} }
} }
ProjectionElem::Index(i) => { ProjectionElem::Index(i) => {
let index_ty = Place::Local(i).ty(self.mir, tcx).to_ty(tcx); let index_ty = Place::Base(PlaceBase::Local(i)).ty(self.mir, tcx).to_ty(tcx);
if index_ty != tcx.types.usize { if index_ty != tcx.types.usize {
PlaceTy::Ty { PlaceTy::Ty {
ty: span_mirbug_and_err!(self, i, "index by non-usize {:?}", i), ty: span_mirbug_and_err!(self, i, "index by non-usize {:?}", i),
@ -1234,7 +1234,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
// of lowering. Assignments to other sorts of places *are* interesting // of lowering. Assignments to other sorts of places *are* interesting
// though. // though.
let category = match *place { let category = match *place {
Place::Local(RETURN_PLACE) => if let Some(BorrowCheckContext { Place::Base(PlaceBase::Local(RETURN_PLACE)) => if let Some(BorrowCheckContext {
universal_regions: universal_regions:
UniversalRegions { UniversalRegions {
defining_ty: DefiningTy::Const(def_id, _), defining_ty: DefiningTy::Const(def_id, _),
@ -1251,7 +1251,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
} else { } else {
ConstraintCategory::Return ConstraintCategory::Return
}, },
Place::Local(l) if !mir.local_decls[l].is_user_variable.is_some() => { Place::Base(PlaceBase::Local(l))
if !mir.local_decls[l].is_user_variable.is_some() => {
ConstraintCategory::Boring ConstraintCategory::Boring
} }
_ => ConstraintCategory::Assignment, _ => ConstraintCategory::Assignment,
@ -1537,7 +1538,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
Some((ref dest, _target_block)) => { Some((ref dest, _target_block)) => {
let dest_ty = dest.ty(mir, tcx).to_ty(tcx); let dest_ty = dest.ty(mir, tcx).to_ty(tcx);
let category = match *dest { let category = match *dest {
Place::Local(RETURN_PLACE) => { Place::Base(PlaceBase::Local(RETURN_PLACE)) => {
if let Some(BorrowCheckContext { if let Some(BorrowCheckContext {
universal_regions: universal_regions:
UniversalRegions { UniversalRegions {
@ -1556,7 +1557,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
ConstraintCategory::Return ConstraintCategory::Return
} }
} }
Place::Local(l) if !mir.local_decls[l].is_user_variable.is_some() => { Place::Base(PlaceBase::Local(l))
if !mir.local_decls[l].is_user_variable.is_some() => {
ConstraintCategory::Boring ConstraintCategory::Boring
} }
_ => ConstraintCategory::Assignment, _ => ConstraintCategory::Assignment,

View file

@ -3,7 +3,7 @@ use crate::borrow_check::places_conflict;
use crate::borrow_check::Context; use crate::borrow_check::Context;
use crate::borrow_check::AccessDepth; use crate::borrow_check::AccessDepth;
use crate::dataflow::indexes::BorrowIndex; use crate::dataflow::indexes::BorrowIndex;
use rustc::mir::{BasicBlock, Location, Mir, Place}; use rustc::mir::{BasicBlock, Location, Mir, Place, PlaceBase};
use rustc::mir::{ProjectionElem, BorrowKind}; use rustc::mir::{ProjectionElem, BorrowKind};
use rustc::ty::TyCtxt; use rustc::ty::TyCtxt;
use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::graph::dominators::Dominators;
@ -138,9 +138,9 @@ pub(super) fn is_active<'tcx>(
/// This is called for all Yield statements on movable generators /// This is called for all Yield statements on movable generators
pub(super) fn borrow_of_local_data<'tcx>(place: &Place<'tcx>) -> bool { pub(super) fn borrow_of_local_data<'tcx>(place: &Place<'tcx>) -> bool {
match place { match place {
Place::Promoted(_) | Place::Base(PlaceBase::Promoted(_)) |
Place::Static(..) => false, Place::Base(PlaceBase::Static(..)) => false,
Place::Local(..) => true, Place::Base(PlaceBase::Local(..)) => true,
Place::Projection(box proj) => { Place::Projection(box proj) => {
match proj.elem { match proj.elem {
// Reborrow of already borrowed data is ignored // Reborrow of already borrowed data is ignored

View file

@ -1,6 +1,6 @@
use rustc::hir; use rustc::hir;
use rustc::mir::ProjectionElem; use rustc::mir::ProjectionElem;
use rustc::mir::{Local, Mir, Place, Mutability}; use rustc::mir::{Local, Mir, Place, PlaceBase, Mutability};
use rustc::ty::{self, TyCtxt}; use rustc::ty::{self, TyCtxt};
use crate::borrow_check::borrow_set::LocalsStateAtExit; use crate::borrow_check::borrow_set::LocalsStateAtExit;
@ -30,7 +30,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
locals_state_at_exit: &LocalsStateAtExit, locals_state_at_exit: &LocalsStateAtExit,
) -> bool { ) -> bool {
match self { match self {
Place::Promoted(_) => false, Place::Base(PlaceBase::Promoted(_)) => false,
// If a local variable is immutable, then we only need to track borrows to guard // If a local variable is immutable, then we only need to track borrows to guard
// against two kinds of errors: // against two kinds of errors:
@ -40,7 +40,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
// //
// In particular, the variable cannot be mutated -- the "access checks" will fail -- // In particular, the variable cannot be mutated -- the "access checks" will fail --
// so we don't have to worry about mutation while borrowed. // so we don't have to worry about mutation while borrowed.
Place::Local(index) => { Place::Base(PlaceBase::Local(index)) => {
match locals_state_at_exit { match locals_state_at_exit {
LocalsStateAtExit::AllAreInvalidated => false, LocalsStateAtExit::AllAreInvalidated => false,
LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => { LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
@ -51,7 +51,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
} }
} }
} }
Place::Static(static_) => { Place::Base(PlaceBase::Static(static_)) => {
tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable) tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable)
} }
Place::Projection(proj) => match proj.elem { Place::Projection(proj) => match proj.elem {
@ -88,9 +88,9 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
loop { loop {
match p { match p {
Place::Projection(pi) => p = &pi.base, Place::Projection(pi) => p = &pi.base,
Place::Promoted(_) | Place::Base(PlaceBase::Promoted(_)) |
Place::Static(_) => return None, Place::Base(PlaceBase::Static(_)) => return None,
Place::Local(l) => return Some(*l), Place::Base(PlaceBase::Local(l)) => return Some(*l),
} }
} }
} }

View file

@ -2,8 +2,7 @@ use crate::borrow_check::ArtificialField;
use crate::borrow_check::Overlap; use crate::borrow_check::Overlap;
use crate::borrow_check::{Deep, Shallow, AccessDepth}; use crate::borrow_check::{Deep, Shallow, AccessDepth};
use rustc::hir; use rustc::hir;
use rustc::mir::{BorrowKind, Mir, Place}; use rustc::mir::{BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem};
use rustc::mir::{Projection, ProjectionElem};
use rustc::ty::{self, TyCtxt}; use rustc::ty::{self, TyCtxt};
use std::cmp::max; use std::cmp::max;
@ -60,8 +59,8 @@ pub(super) fn borrow_conflicts_with_place<'gcx, 'tcx>(
// This Local/Local case is handled by the more general code below, but // This Local/Local case is handled by the more general code below, but
// it's so common that it's a speed win to check for it first. // it's so common that it's a speed win to check for it first.
if let Place::Local(l1) = borrow_place { if let Place::Base(PlaceBase::Local(l1)) = borrow_place {
if let Place::Local(l2) = access_place { if let Place::Base(PlaceBase::Local(l2)) = access_place {
return l1 == l2; return l1 == l2;
} }
} }
@ -339,8 +338,8 @@ fn unroll_place<'tcx, R>(
op, op,
), ),
Place::Promoted(_) | Place::Base(PlaceBase::Promoted(_)) |
Place::Local(_) | Place::Static(_) => { Place::Base(PlaceBase::Local(_)) | Place::Base(PlaceBase::Static(_)) => {
let list = PlaceComponents { let list = PlaceComponents {
component: place, component: place,
next, next,
@ -361,7 +360,7 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>(
bias: PlaceConflictBias, bias: PlaceConflictBias,
) -> Overlap { ) -> Overlap {
match (elem1, elem2) { match (elem1, elem2) {
(Place::Local(l1), Place::Local(l2)) => { (Place::Base(PlaceBase::Local(l1)), Place::Base(PlaceBase::Local(l2))) => {
if l1 == l2 { if l1 == l2 {
// the same local - base case, equal // the same local - base case, equal
debug!("place_element_conflict: DISJOINT-OR-EQ-LOCAL"); debug!("place_element_conflict: DISJOINT-OR-EQ-LOCAL");
@ -372,7 +371,7 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>(
Overlap::Disjoint Overlap::Disjoint
} }
} }
(Place::Static(static1), Place::Static(static2)) => { (Place::Base(PlaceBase::Static(static1)), Place::Base(PlaceBase::Static(static2))) => {
if static1.def_id != static2.def_id { if static1.def_id != static2.def_id {
debug!("place_element_conflict: DISJOINT-STATIC"); debug!("place_element_conflict: DISJOINT-STATIC");
Overlap::Disjoint Overlap::Disjoint
@ -385,7 +384,7 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>(
Overlap::EqualOrDisjoint Overlap::EqualOrDisjoint
} }
} }
(Place::Promoted(p1), Place::Promoted(p2)) => { (Place::Base(PlaceBase::Promoted(p1)), Place::Base(PlaceBase::Promoted(p2))) => {
if p1.0 == p2.0 { if p1.0 == p2.0 {
if let ty::Array(_, size) = p1.1.sty { if let ty::Array(_, size) = p1.1.sty {
if size.unwrap_usize(tcx) == 0 { if size.unwrap_usize(tcx) == 0 {
@ -403,9 +402,12 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>(
Overlap::Disjoint Overlap::Disjoint
} }
} }
(Place::Local(_), Place::Promoted(_)) | (Place::Promoted(_), Place::Local(_)) | (Place::Base(PlaceBase::Local(_)), Place::Base(PlaceBase::Promoted(_))) |
(Place::Promoted(_), Place::Static(_)) | (Place::Static(_), Place::Promoted(_)) | (Place::Base(PlaceBase::Promoted(_)), Place::Base(PlaceBase::Local(_))) |
(Place::Local(_), Place::Static(_)) | (Place::Static(_), Place::Local(_)) => { (Place::Base(PlaceBase::Promoted(_)), Place::Base(PlaceBase::Static(_))) |
(Place::Base(PlaceBase::Static(_)), Place::Base(PlaceBase::Promoted(_))) |
(Place::Base(PlaceBase::Local(_)), Place::Base(PlaceBase::Static(_))) |
(Place::Base(PlaceBase::Static(_)), Place::Base(PlaceBase::Local(_))) => {
debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED"); debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED");
Overlap::Disjoint Overlap::Disjoint
} }

View file

@ -11,7 +11,7 @@ use super::MirBorrowckCtxt;
use rustc::hir; use rustc::hir;
use rustc::ty::{self, TyCtxt}; use rustc::ty::{self, TyCtxt};
use rustc::mir::{Mir, Place, ProjectionElem}; use rustc::mir::{Mir, Place, PlaceBase, ProjectionElem};
pub trait IsPrefixOf<'tcx> { pub trait IsPrefixOf<'tcx> {
fn is_prefix_of(&self, other: &Place<'tcx>) -> bool; fn is_prefix_of(&self, other: &Place<'tcx>) -> bool;
@ -26,8 +26,9 @@ impl<'tcx> IsPrefixOf<'tcx> for Place<'tcx> {
} }
match *cursor { match *cursor {
Place::Promoted(_) | Place::Base(PlaceBase::Promoted(_)) |
Place::Local(_) | Place::Static(_) => return false, Place::Base(PlaceBase::Local(_)) |
Place::Base(PlaceBase::Static(_)) => return false,
Place::Projection(ref proj) => { Place::Projection(ref proj) => {
cursor = &proj.base; cursor = &proj.base;
} }
@ -86,9 +87,9 @@ impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> {
'cursor: loop { 'cursor: loop {
let proj = match *cursor { let proj = match *cursor {
Place::Promoted(_) | Place::Base(PlaceBase::Promoted(_)) |
Place::Local(_) | // search yielded this leaf Place::Base(PlaceBase::Local(_)) | // search yielded this leaf
Place::Static(_) => { Place::Base(PlaceBase::Static(_)) => {
self.next = None; self.next = None;
return Some(cursor); return Some(cursor);
} }

View file

@ -1,5 +1,7 @@
use rustc::mir::visit::{PlaceContext, Visitor}; use rustc::mir::visit::{PlaceContext, Visitor};
use rustc::mir::{BasicBlock, Local, Location, Place, Statement, StatementKind, TerminatorKind}; use rustc::mir::{
BasicBlock, Local, Location, Place, PlaceBase, Statement, StatementKind, TerminatorKind
};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
@ -114,7 +116,7 @@ impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'c
"assignment of {:?} to {:?}, adding {:?} to used mutable set", "assignment of {:?} to {:?}, adding {:?} to used mutable set",
path.place, local, path.place path.place, local, path.place
); );
if let Place::Local(user_local) = path.place { if let Place::Base(PlaceBase::Local(user_local)) = path.place {
self.mbcx.used_mut.insert(user_local); self.mbcx.used_mut.insert(user_local);
} }
} }

View file

@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
} }
Category::Place | Category::Rvalue(..) => { Category::Place | Category::Rvalue(..) => {
let operand = unpack!(block = this.as_temp(block, scope, expr, Mutability::Mut)); let operand = unpack!(block = this.as_temp(block, scope, expr, Mutability::Mut));
block.and(Operand::Move(Place::Local(operand))) block.and(Operand::Move(Place::Base(PlaceBase::Local(operand))))
} }
} }
} }

View file

@ -98,19 +98,19 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
&lt, &lt,
Rvalue::BinaryOp( Rvalue::BinaryOp(
BinOp::Lt, BinOp::Lt,
Operand::Copy(Place::Local(idx)), Operand::Copy(Place::Base(PlaceBase::Local(idx))),
Operand::Copy(len.clone()), Operand::Copy(len.clone()),
), ),
); );
let msg = BoundsCheck { let msg = BoundsCheck {
len: Operand::Move(len), len: Operand::Move(len),
index: Operand::Copy(Place::Local(idx)), index: Operand::Copy(Place::Base(PlaceBase::Local(idx))),
}; };
let success = this.assert(block, Operand::Move(lt), true, msg, expr_span); let success = this.assert(block, Operand::Move(lt), true, msg, expr_span);
success.and(slice.index(idx)) success.and(slice.index(idx))
} }
ExprKind::SelfRef => block.and(Place::Local(Local::new(1))), ExprKind::SelfRef => block.and(Place::Base(PlaceBase::Local(Local::new(1)))),
ExprKind::VarRef { id } => { ExprKind::VarRef { id } => {
let place = if this.is_bound_var_in_guard(id) && this let place = if this.is_bound_var_in_guard(id) && this
.hir .hir
@ -118,17 +118,17 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
.all_pat_vars_are_implicit_refs_within_guards() .all_pat_vars_are_implicit_refs_within_guards()
{ {
let index = this.var_local_id(id, RefWithinGuard); let index = this.var_local_id(id, RefWithinGuard);
Place::Local(index).deref() Place::Base(PlaceBase::Local(index)).deref()
} else { } else {
let index = this.var_local_id(id, OutsideGuard); let index = this.var_local_id(id, OutsideGuard);
Place::Local(index) Place::Base(PlaceBase::Local(index))
}; };
block.and(place) block.and(place)
} }
ExprKind::StaticRef { id } => block.and(Place::Static(Box::new(Static { ExprKind::StaticRef { id } => block.and(Place::Base(PlaceBase::Static(Box::new(Static {
def_id: id, def_id: id,
ty: expr.ty, ty: expr.ty,
}))), })))),
ExprKind::PlaceTypeAscription { source, user_ty } => { ExprKind::PlaceTypeAscription { source, user_ty } => {
let place = unpack!(block = this.as_place(block, source)); let place = unpack!(block = this.as_place(block, source));
@ -172,14 +172,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
Statement { Statement {
source_info, source_info,
kind: StatementKind::AscribeUserType( kind: StatementKind::AscribeUserType(
Place::Local(temp.clone()), Place::Base(PlaceBase::Local(temp.clone())),
Variance::Invariant, Variance::Invariant,
box UserTypeProjection { base: annotation_index, projs: vec![], }, box UserTypeProjection { base: annotation_index, projs: vec![], },
), ),
}, },
); );
} }
block.and(Place::Local(temp)) block.and(Place::Base(PlaceBase::Local(temp)))
} }
ExprKind::Array { .. } ExprKind::Array { .. }
@ -219,7 +219,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}); });
let temp = let temp =
unpack!(block = this.as_temp(block, expr.temp_lifetime, expr, mutability)); unpack!(block = this.as_temp(block, expr.temp_lifetime, expr, mutability));
block.and(Place::Local(temp)) block.and(Place::Base(PlaceBase::Local(temp)))
} }
} }
} }

View file

@ -127,7 +127,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
this.schedule_drop_storage_and_value( this.schedule_drop_storage_and_value(
expr_span, expr_span,
scope, scope,
&Place::Local(result), &Place::Base(PlaceBase::Local(result)),
value.ty, value.ty,
); );
} }
@ -135,11 +135,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// malloc some memory of suitable type (thus far, uninitialized): // malloc some memory of suitable type (thus far, uninitialized):
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty); let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
this.cfg this.cfg
.push_assign(block, source_info, &Place::Local(result), box_); .push_assign(block, source_info, &Place::Base(PlaceBase::Local(result)), box_);
// initialize the box contents: // initialize the box contents:
unpack!(block = this.into(&Place::Local(result).deref(), block, value)); unpack!(
block.and(Rvalue::Use(Operand::Move(Place::Local(result)))) block = this.into(
&Place::Base(PlaceBase::Local(result)).deref(),
block, value
)
);
block.and(Rvalue::Use(Operand::Move(Place::Base(PlaceBase::Local(result)))))
} }
ExprKind::Cast { source } => { ExprKind::Cast { source } => {
let source = this.hir.mirror(source); let source = this.hir.mirror(source);
@ -522,9 +527,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let arg_place = unpack!(block = this.as_place(block, arg)); let arg_place = unpack!(block = this.as_place(block, arg));
let mutability = match arg_place { let mutability = match arg_place {
Place::Local(local) => this.local_decls[local].mutability, Place::Base(PlaceBase::Local(local)) => this.local_decls[local].mutability,
Place::Projection(box Projection { Place::Projection(box Projection {
base: Place::Local(local), base: Place::Base(PlaceBase::Local(local)),
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
}) => { }) => {
debug_assert!( debug_assert!(
@ -554,11 +559,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// Not projected from the implicit `self` in a closure. // Not projected from the implicit `self` in a closure.
debug_assert!( debug_assert!(
match *base { match *base {
Place::Local(local) => local == Local::new(1), Place::Base(PlaceBase::Local(local)) => local == Local::new(1),
Place::Projection(box Projection { Place::Projection(box Projection {
ref base, ref base,
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
}) => *base == Place::Local(Local::new(1)), }) => *base == Place::Base(PlaceBase::Local(Local::new(1))),
_ => false, _ => false,
}, },
"Unexpected capture place" "Unexpected capture place"
@ -583,7 +588,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
this.cfg.push_assign( this.cfg.push_assign(
block, block,
source_info, source_info,
&Place::Local(temp), &Place::Base(PlaceBase::Local(temp)),
Rvalue::Ref(this.hir.tcx().types.re_erased, borrow_kind, arg_place), Rvalue::Ref(this.hir.tcx().types.re_erased, borrow_kind, arg_place),
); );
@ -594,12 +599,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
this.schedule_drop_storage_and_value( this.schedule_drop_storage_and_value(
upvar_span, upvar_span,
temp_lifetime, temp_lifetime,
&Place::Local(temp), &Place::Base(PlaceBase::Local(temp)),
upvar_ty, upvar_ty,
); );
} }
block.and(Operand::Move(Place::Local(temp))) block.and(Operand::Move(Place::Base(PlaceBase::Local(temp))))
} }
// Helper to get a `-1` value of the appropriate type // Helper to get a `-1` value of the appropriate type

View file

@ -73,7 +73,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
); );
} }
unpack!(block = this.into(&Place::Local(temp), block, expr)); unpack!(block = this.into(&Place::Base(PlaceBase::Local(temp)), block, expr));
// In constants, temp_lifetime is None for temporaries that live for the // In constants, temp_lifetime is None for temporaries that live for the
// 'static lifetime. Thus we do not drop these temporaries and simply leak them. // 'static lifetime. Thus we do not drop these temporaries and simply leak them.
@ -88,7 +88,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
this.schedule_drop_storage_and_value( this.schedule_drop_storage_and_value(
expr_span, expr_span,
temp_lifetime, temp_lifetime,
&Place::Local(temp), &Place::Base(PlaceBase::Local(temp)),
expr_ty, expr_ty,
); );
} }

View file

@ -295,7 +295,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
is_user_variable: None, is_user_variable: None,
is_block_tail: None, is_block_tail: None,
}); });
let ptr_temp = Place::Local(ptr_temp); let ptr_temp = Place::Base(PlaceBase::Local(ptr_temp));
let block = unpack!(this.into(&ptr_temp, block, ptr)); let block = unpack!(this.into(&ptr_temp, block, ptr));
this.into(&ptr_temp.deref(), block, val) this.into(&ptr_temp.deref(), block, val)
} else { } else {

View file

@ -139,13 +139,22 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
Some(value) => { Some(value) => {
debug!("stmt_expr Return val block_context.push(SubExpr) : {:?}", expr2); debug!("stmt_expr Return val block_context.push(SubExpr) : {:?}", expr2);
this.block_context.push(BlockFrame::SubExpr); this.block_context.push(BlockFrame::SubExpr);
let result = unpack!(this.into(&Place::Local(RETURN_PLACE), block, value)); let result = unpack!(
this.into(
&Place::RETURN_PLACE,
block,
value
)
);
this.block_context.pop(); this.block_context.pop();
result result
} }
None => { None => {
this.cfg this.cfg.push_assign_unit(
.push_assign_unit(block, source_info, &Place::Local(RETURN_PLACE)); block,
source_info,
&Place::RETURN_PLACE,
);
block block
} }
}; };
@ -226,7 +235,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
} }
} }
let temp = this.local_decls.push(local_decl); let temp = this.local_decls.push(local_decl);
let place = Place::Local(temp); let place = Place::Base(PlaceBase::Local(temp));
debug!("created temp {:?} for expr {:?} in block_context: {:?}", debug!("created temp {:?} for expr {:?} in block_context: {:?}",
temp, expr, this.block_context); temp, expr, this.block_context);
place place

View file

@ -543,7 +543,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
kind: StatementKind::StorageLive(local_id), kind: StatementKind::StorageLive(local_id),
}, },
); );
let place = Place::Local(local_id); let place = Place::Base(PlaceBase::Local(local_id));
let var_ty = self.local_decls[local_id].ty; let var_ty = self.local_decls[local_id].ty;
let hir_id = self.hir.tcx().hir().node_to_hir_id(var); 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); let region_scope = self.hir.region_scope_tree.var_scope(hir_id.local_id);
@ -559,7 +559,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
self.schedule_drop( self.schedule_drop(
span, span,
region_scope, region_scope,
&Place::Local(local_id), &Place::Base(PlaceBase::Local(local_id)),
var_ty, var_ty,
DropKind::Value { DropKind::Value {
cached_block: CachedBlock::default(), cached_block: CachedBlock::default(),
@ -1452,7 +1452,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
self.cfg.push_assign( self.cfg.push_assign(
block, block,
scrutinee_source_info, scrutinee_source_info,
&Place::Local(temp), &Place::Base(PlaceBase::Local(temp)),
borrow, borrow,
); );
} }
@ -1478,7 +1478,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
source_info: guard_end, source_info: guard_end,
kind: StatementKind::FakeRead( kind: StatementKind::FakeRead(
FakeReadCause::ForMatchGuard, FakeReadCause::ForMatchGuard,
Place::Local(temp), Place::Base(PlaceBase::Local(temp)),
), ),
}); });
} }
@ -1529,7 +1529,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// place they refer to can't be modified by the guard. // place they refer to can't be modified by the guard.
for binding in by_value_bindings.clone() { for binding in by_value_bindings.clone() {
let local_id = self.var_local_id(binding.var_id, RefWithinGuard); let local_id = self.var_local_id(binding.var_id, RefWithinGuard);
let place = Place::Local(local_id); let place = Place::Base(PlaceBase::Local(local_id));
self.cfg.push( self.cfg.push(
block, block,
Statement { Statement {

View file

@ -16,7 +16,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// call `schedule_drop` once the temporary is initialized. /// call `schedule_drop` once the temporary is initialized.
pub fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'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 temp = self.local_decls.push(LocalDecl::new_temp(ty, span));
let place = Place::Local(temp); let place = Place::Base(PlaceBase::Local(temp));
debug!("temp: created temp {:?} with type {:?}", debug!("temp: created temp {:?} with type {:?}",
place, self.local_decls[temp].ty); place, self.local_decls[temp].ty);
place place

View file

@ -741,7 +741,7 @@ fn construct_const<'a, 'gcx, 'tcx>(
let mut block = START_BLOCK; let mut block = START_BLOCK;
let expr = builder.hir.mirror(ast_expr); let expr = builder.hir.mirror(ast_expr);
unpack!(block = builder.into_expr(&Place::Local(RETURN_PLACE), block, expr)); unpack!(block = builder.into_expr(&Place::RETURN_PLACE, block, expr));
let source_info = builder.source_info(span); let source_info = builder.source_info(span);
builder.cfg.terminate(block, source_info, TerminatorKind::Return); builder.cfg.terminate(block, source_info, TerminatorKind::Return);
@ -887,7 +887,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
for (index, arg_info) in arguments.iter().enumerate() { for (index, arg_info) in arguments.iter().enumerate() {
// Function arguments always get the first Local indices after the return place // Function arguments always get the first Local indices after the return place
let local = Local::new(index + 1); let local = Local::new(index + 1);
let place = Place::Local(local); let place = Place::Base(PlaceBase::Local(local));
let &ArgInfo(ty, opt_ty_info, pattern, ref self_binding) = arg_info; let &ArgInfo(ty, opt_ty_info, pattern, ref self_binding) = arg_info;
// Make sure we drop (parts of) the argument even when not matched on. // Make sure we drop (parts of) the argument even when not matched on.
@ -936,7 +936,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
} }
let body = self.hir.mirror(ast_body); let body = self.hir.mirror(ast_body);
self.into(&Place::Local(RETURN_PLACE), block, body) self.into(&Place::RETURN_PLACE, block, body)
} }
fn get_unit_temp(&mut self) -> Place<'tcx> { fn get_unit_temp(&mut self) -> Place<'tcx> {

View file

@ -662,7 +662,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
DropKind::Value { .. } => if !needs_drop { return }, DropKind::Value { .. } => if !needs_drop { return },
DropKind::Storage => { DropKind::Storage => {
match *place { match *place {
Place::Local(index) => if index.index() <= self.arg_count { Place::Base(PlaceBase::Local(index)) => if index.index() <= self.arg_count {
span_bug!( span_bug!(
span, "`schedule_drop` called with index {} and arg_count {}", span, "`schedule_drop` called with index {} and arg_count {}",
index.index(), index.index(),
@ -936,7 +936,7 @@ fn build_scope_drops<'tcx>(
// Drop the storage for both value and storage drops. // Drop the storage for both value and storage drops.
// Only temps and vars need their storage dead. // Only temps and vars need their storage dead.
match drop_data.location { match drop_data.location {
Place::Local(index) if index.index() > arg_count => { Place::Base(PlaceBase::Local(index)) if index.index() > arg_count => {
cfg.push(block, Statement { cfg.push(block, Statement {
source_info, source_info,
kind: StatementKind::StorageDead(index) kind: StatementKind::StorageDead(index)

View file

@ -163,7 +163,7 @@ pub(crate) fn drop_flag_effects_for_function_entry<'a, 'gcx, 'tcx, F>(
{ {
let move_data = &ctxt.move_data; let move_data = &ctxt.move_data;
for arg in mir.args_iter() { for arg in mir.args_iter() {
let place = mir::Place::Local(arg); let place = mir::Place::Base(mir::PlaceBase::Local(arg));
let lookup_result = move_data.rev_lookup.find(&place); let lookup_result = move_data.rev_lookup.find(&place);
on_lookup_result_bits(tcx, mir, move_data, on_lookup_result_bits(tcx, mir, move_data,
lookup_result, lookup_result,

View file

@ -92,9 +92,9 @@ struct BorrowedLocalsVisitor<'b, 'c: 'b> {
fn find_local<'tcx>(place: &Place<'tcx>) -> Option<Local> { fn find_local<'tcx>(place: &Place<'tcx>) -> Option<Local> {
match *place { match *place {
Place::Local(l) => Some(l), Place::Base(PlaceBase::Local(l)) => Some(l),
Place::Promoted(_) | Place::Base(PlaceBase::Promoted(_)) |
Place::Static(..) => None, Place::Base(PlaceBase::Static(..)) => None,
Place::Projection(ref proj) => { Place::Projection(ref proj) => {
match proj.elem { match proj.elem {
ProjectionElem::Deref => None, ProjectionElem::Deref => None,

View file

@ -1,7 +1,7 @@
use crate::borrow_check::borrow_set::{BorrowSet, BorrowData}; use crate::borrow_check::borrow_set::{BorrowSet, BorrowData};
use crate::borrow_check::place_ext::PlaceExt; use crate::borrow_check::place_ext::PlaceExt;
use rustc::mir::{self, Location, Place, Mir}; use rustc::mir::{self, Location, Place, PlaceBase, Mir};
use rustc::ty::TyCtxt; use rustc::ty::TyCtxt;
use rustc::ty::RegionVid; use rustc::ty::RegionVid;
@ -189,7 +189,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
) { ) {
debug!("kill_borrows_on_place: place={:?}", place); debug!("kill_borrows_on_place: place={:?}", place);
// Handle the `Place::Local(..)` case first and exit early. // Handle the `Place::Local(..)` case first and exit early.
if let Place::Local(local) = place { if let Place::Base(PlaceBase::Local(local)) = place {
if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) { if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
debug!("kill_borrows_on_place: borrow_indices={:?}", borrow_indices); debug!("kill_borrows_on_place: borrow_indices={:?}", borrow_indices);
sets.kill_all(borrow_indices); sets.kill_all(borrow_indices);
@ -285,7 +285,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'gcx, 'tcx> {
mir::StatementKind::StorageDead(local) => { mir::StatementKind::StorageDead(local) => {
// Make sure there are no remaining borrows for locals that // Make sure there are no remaining borrows for locals that
// are gone out of scope. // are gone out of scope.
self.kill_borrows_on_place(sets, &Place::Local(local)); self.kill_borrows_on_place(sets, &Place::Base(PlaceBase::Local(local)));
} }
mir::StatementKind::InlineAsm { ref outputs, ref asm, .. } => { mir::StatementKind::InlineAsm { ref outputs, ref asm, .. } => {

View file

@ -493,7 +493,8 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'gcx, 'tc
// storagedeads after everything ends, so if we don't regard the // storagedeads after everything ends, so if we don't regard the
// storagelive as killing storage, we would have a multiple assignment // storagelive as killing storage, we would have a multiple assignment
// to immutable data error. // to immutable data error.
if let LookupResult::Exact(mpi) = rev_lookup.find(&mir::Place::Local(local)) { if let LookupResult::Exact(mpi) =
rev_lookup.find(&mir::Place::Base(mir::PlaceBase::Local(local))) {
debug!("stmt {:?} at loc {:?} clears the ever initialized status of {:?}", debug!("stmt {:?} at loc {:?} clears the ever initialized status of {:?}",
stmt, location, &init_path_map[mpi]); stmt, location, &init_path_map[mpi]);
sets.kill_all(&init_path_map[mpi]); sets.kill_all(&init_path_map[mpi]);

View file

@ -33,13 +33,13 @@ impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
moves: IndexVec::new(), moves: IndexVec::new(),
loc_map: LocationMap::new(mir), loc_map: LocationMap::new(mir),
rev_lookup: MovePathLookup { rev_lookup: MovePathLookup {
locals: mir.local_decls.indices().map(Place::Local).map(|v| { locals: mir.local_decls.indices().map(PlaceBase::Local).map(|v| {
Self::new_move_path( Self::new_move_path(
&mut move_paths, &mut move_paths,
&mut path_map, &mut path_map,
&mut init_path_map, &mut init_path_map,
None, None,
v, Place::Base(v),
) )
}).collect(), }).collect(),
projections: Default::default(), projections: Default::default(),
@ -96,9 +96,9 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
{ {
debug!("lookup({:?})", place); debug!("lookup({:?})", place);
match *place { match *place {
Place::Local(local) => Ok(self.builder.data.rev_lookup.locals[local]), Place::Base(PlaceBase::Local(local)) => Ok(self.builder.data.rev_lookup.locals[local]),
Place::Promoted(..) | Place::Base(PlaceBase::Promoted(..)) |
Place::Static(..) => { Place::Base(PlaceBase::Static(..)) => {
Err(MoveError::cannot_move_out_of(self.loc, Static)) Err(MoveError::cannot_move_out_of(self.loc, Static))
} }
Place::Projection(ref proj) => { Place::Projection(ref proj) => {
@ -285,7 +285,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
} }
StatementKind::StorageLive(_) => {} StatementKind::StorageLive(_) => {}
StatementKind::StorageDead(local) => { StatementKind::StorageDead(local) => {
self.gather_move(&Place::Local(local)); self.gather_move(&Place::Base(PlaceBase::Local(local)));
} }
StatementKind::SetDiscriminant{ .. } => { StatementKind::SetDiscriminant{ .. } => {
span_bug!(stmt.source_info.span, span_bug!(stmt.source_info.span,
@ -345,7 +345,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
TerminatorKind::Unreachable => { } TerminatorKind::Unreachable => { }
TerminatorKind::Return => { TerminatorKind::Return => {
self.gather_move(&Place::Local(RETURN_PLACE)); self.gather_move(&Place::RETURN_PLACE);
} }
TerminatorKind::Assert { ref cond, .. } => { TerminatorKind::Assert { ref cond, .. } => {

View file

@ -273,9 +273,9 @@ impl<'tcx> MovePathLookup<'tcx> {
// parent. // parent.
pub fn find(&self, place: &Place<'tcx>) -> LookupResult { pub fn find(&self, place: &Place<'tcx>) -> LookupResult {
match *place { match *place {
Place::Local(local) => LookupResult::Exact(self.locals[local]), Place::Base(PlaceBase::Local(local)) => LookupResult::Exact(self.locals[local]),
Place::Promoted(_) | Place::Base(PlaceBase::Promoted(_)) |
Place::Static(..) => LookupResult::Parent(None), Place::Base(PlaceBase::Static(..)) => LookupResult::Parent(None),
Place::Projection(ref proj) => { Place::Projection(ref proj) => {
match self.find(&proj.base) { match self.find(&proj.base) {
LookupResult::Exact(base_path) => { LookupResult::Exact(base_path) => {
@ -347,7 +347,7 @@ impl<'a, 'gcx, 'tcx> MoveData<'tcx> {
pub fn base_local(&self, mut mpi: MovePathIndex) -> Option<Local> { pub fn base_local(&self, mut mpi: MovePathIndex) -> Option<Local> {
loop { loop {
let path = &self.move_paths[mpi]; let path = &self.move_paths[mpi];
if let Place::Local(l) = path.place { return Some(l); } if let Place::Base(PlaceBase::Local(l)) = path.place { return Some(l); }
if let Some(parent) = path.parent { mpi = parent; continue } else { return None } if let Some(parent) = path.parent { mpi = parent; continue } else { return None }
} }
} }

View file

@ -515,9 +515,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
layout: Option<TyLayout<'tcx>>, layout: Option<TyLayout<'tcx>>,
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
use rustc::mir::Place::*; use rustc::mir::Place::*;
use rustc::mir::PlaceBase;
let op = match *mir_place { let op = match *mir_place {
Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer), Base(PlaceBase::Local(mir::RETURN_PLACE)) => return err!(ReadFromReturnPointer),
Local(local) => self.access_local(self.frame(), local, layout)?, Base(PlaceBase::Local(local)) => self.access_local(self.frame(), local, layout)?,
Projection(ref proj) => { Projection(ref proj) => {
let op = self.eval_place_to_op(&proj.base, None)?; let op = self.eval_place_to_op(&proj.base, None)?;

View file

@ -581,8 +581,9 @@ where
mir_place: &mir::Place<'tcx> mir_place: &mir::Place<'tcx>
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
use rustc::mir::Place::*; use rustc::mir::Place::*;
use rustc::mir::PlaceBase;
Ok(match *mir_place { Ok(match *mir_place {
Promoted(ref promoted) => { Base(PlaceBase::Promoted(ref promoted)) => {
let instance = self.frame().instance; let instance = self.frame().instance;
self.const_eval_raw(GlobalId { self.const_eval_raw(GlobalId {
instance, instance,
@ -590,7 +591,7 @@ where
})? })?
} }
Static(ref static_) => { Base(PlaceBase::Static(ref static_)) => {
assert!(!static_.ty.needs_subst()); assert!(!static_.ty.needs_subst());
let layout = self.layout_of(static_.ty)?; let layout = self.layout_of(static_.ty)?;
let instance = ty::Instance::mono(*self.tcx, static_.def_id); let instance = ty::Instance::mono(*self.tcx, static_.def_id);
@ -624,8 +625,9 @@ where
mir_place: &mir::Place<'tcx> mir_place: &mir::Place<'tcx>
) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> { ) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
use rustc::mir::Place::*; use rustc::mir::Place::*;
use rustc::mir::PlaceBase;
let place = match *mir_place { let place = match *mir_place {
Local(mir::RETURN_PLACE) => match self.frame().return_place { Base(PlaceBase::Local(mir::RETURN_PLACE)) => match self.frame().return_place {
Some(return_place) => Some(return_place) =>
// We use our layout to verify our assumption; caller will validate // We use our layout to verify our assumption; caller will validate
// their layout on return. // their layout on return.
@ -635,7 +637,7 @@ where
}, },
None => return err!(InvalidNullPointerUsage), None => return err!(InvalidNullPointerUsage),
}, },
Local(local) => PlaceTy { Base(PlaceBase::Local(local)) => PlaceTy {
place: Place::Local { place: Place::Local {
frame: self.cur_frame(), frame: self.cur_frame(),
local, local,

View file

@ -352,7 +352,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
// not advance `caller_iter` for ZSTs. // not advance `caller_iter` for ZSTs.
let mut locals_iter = mir.args_iter(); let mut locals_iter = mir.args_iter();
while let Some(local) = locals_iter.next() { while let Some(local) = locals_iter.next() {
let dest = self.eval_place(&mir::Place::Local(local))?; let dest = self.eval_place(
&mir::Place::Base(mir::PlaceBase::Local(local))
)?;
if Some(local) == mir.spread_arg { if Some(local) == mir.spread_arg {
// Must be a tuple // Must be a tuple
for i in 0..dest.layout.fields.count() { for i in 0..dest.layout.fields.count() {
@ -371,7 +373,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
} }
// Don't forget to check the return type! // Don't forget to check the return type!
if let Some(caller_ret) = dest { if let Some(caller_ret) = dest {
let callee_ret = self.eval_place(&mir::Place::Local(mir::RETURN_PLACE))?; let callee_ret = self.eval_place(
&mir::Place::RETURN_PLACE
)?;
if !Self::check_argument_compat( if !Self::check_argument_compat(
rust_abi, rust_abi,
caller_ret.layout, caller_ret.layout,

View file

@ -221,7 +221,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if let Some(..) = ty { if let Some(..) = ty {
// The first argument (index 0), but add 1 for the return value. // The first argument (index 0), but add 1 for the return value.
let dropee_ptr = Place::Local(Local::new(1+0)); let dropee_ptr = Place::Base(PlaceBase::Local(Local::new(1+0)));
if tcx.sess.opts.debugging_opts.mir_emit_retag { if tcx.sess.opts.debugging_opts.mir_emit_retag {
// Function arguments should be retagged, and we make this one raw. // Function arguments should be retagged, and we make this one raw.
mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement { mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
@ -317,8 +317,8 @@ fn build_clone_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty); let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
let is_copy = self_ty.is_copy_modulo_regions(tcx, tcx.param_env(def_id), builder.span); let is_copy = self_ty.is_copy_modulo_regions(tcx, tcx.param_env(def_id), builder.span);
let dest = Place::Local(RETURN_PLACE); let dest = Place::RETURN_PLACE;
let src = Place::Local(Local::new(1+0)).deref(); let src = Place::Base(PlaceBase::Local(Local::new(1+0))).deref();
match self_ty.sty { match self_ty.sty {
_ if is_copy => builder.copy_shim(), _ if is_copy => builder.copy_shim(),
@ -424,10 +424,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
} }
fn copy_shim(&mut self) { fn copy_shim(&mut self) {
let rcvr = Place::Local(Local::new(1+0)).deref(); let rcvr = Place::Base(PlaceBase::Local(Local::new(1+0))).deref();
let ret_statement = self.make_statement( let ret_statement = self.make_statement(
StatementKind::Assign( StatementKind::Assign(
Place::Local(RETURN_PLACE), Place::RETURN_PLACE,
box Rvalue::Use(Operand::Copy(rcvr)) box Rvalue::Use(Operand::Copy(rcvr))
) )
); );
@ -436,9 +436,9 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
fn make_place(&mut self, mutability: Mutability, ty: Ty<'tcx>) -> Place<'tcx> { fn make_place(&mut self, mutability: Mutability, ty: Ty<'tcx>) -> Place<'tcx> {
let span = self.span; let span = self.span;
Place::Local( Place::Base(PlaceBase::Local(
self.local_decls.push(temp_decl(mutability, ty, span)) self.local_decls.push(temp_decl(mutability, ty, span))
) ))
} }
fn make_clone_call( fn make_clone_call(
@ -546,7 +546,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
let inits = vec![ let inits = vec![
self.make_statement( self.make_statement(
StatementKind::Assign( StatementKind::Assign(
Place::Local(beg), Place::Base(PlaceBase::Local(beg)),
box Rvalue::Use(Operand::Constant(self.make_usize(0))) box Rvalue::Use(Operand::Constant(self.make_usize(0)))
) )
), ),
@ -564,7 +564,11 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
// BB #3; // BB #3;
// } // }
// BB #4; // BB #4;
self.loop_header(Place::Local(beg), end, BasicBlock::new(2), BasicBlock::new(4), false); self.loop_header(Place::Base(PlaceBase::Local(beg)),
end,
BasicBlock::new(2),
BasicBlock::new(4),
false);
// BB #2 // BB #2
// `dest[i] = Clone::clone(src[beg])`; // `dest[i] = Clone::clone(src[beg])`;
@ -580,10 +584,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
let statements = vec![ let statements = vec![
self.make_statement( self.make_statement(
StatementKind::Assign( StatementKind::Assign(
Place::Local(beg), Place::Base(PlaceBase::Local(beg)),
box Rvalue::BinaryOp( box Rvalue::BinaryOp(
BinOp::Add, BinOp::Add,
Operand::Copy(Place::Local(beg)), Operand::Copy(Place::Base(PlaceBase::Local(beg))),
Operand::Constant(self.make_usize(1)) Operand::Constant(self.make_usize(1))
) )
) )
@ -603,7 +607,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span)); let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
let init = self.make_statement( let init = self.make_statement(
StatementKind::Assign( StatementKind::Assign(
Place::Local(beg), Place::Base(PlaceBase::Local(beg)),
box Rvalue::Use(Operand::Constant(self.make_usize(0))) box Rvalue::Use(Operand::Constant(self.make_usize(0)))
) )
); );
@ -614,7 +618,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
// BB #8; // BB #8;
// } // }
// BB #9; // BB #9;
self.loop_header(Place::Local(beg), Place::Local(end), self.loop_header(Place::Base(PlaceBase::Local(beg)), Place::Base(PlaceBase::Local(end)),
BasicBlock::new(7), BasicBlock::new(9), true); BasicBlock::new(7), BasicBlock::new(9), true);
// BB #7 (cleanup) // BB #7 (cleanup)
@ -630,10 +634,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
// `goto #6;` // `goto #6;`
let statement = self.make_statement( let statement = self.make_statement(
StatementKind::Assign( StatementKind::Assign(
Place::Local(beg), Place::Base(PlaceBase::Local(beg)),
box Rvalue::BinaryOp( box Rvalue::BinaryOp(
BinOp::Add, BinOp::Add,
Operand::Copy(Place::Local(beg)), Operand::Copy(Place::Base(PlaceBase::Local(beg))),
Operand::Constant(self.make_usize(1)) Operand::Constant(self.make_usize(1))
) )
) )
@ -718,7 +722,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }; let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE };
let rcvr_arg = Local::new(1+0); let rcvr_arg = Local::new(1+0);
let rcvr_l = Place::Local(rcvr_arg); let rcvr_l = Place::Base(PlaceBase::Local(rcvr_arg));
let mut statements = vec![]; let mut statements = vec![];
let rcvr = match rcvr_adjustment { let rcvr = match rcvr_adjustment {
@ -748,11 +752,11 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
statements.push(Statement { statements.push(Statement {
source_info, source_info,
kind: StatementKind::Assign( kind: StatementKind::Assign(
Place::Local(ref_rcvr), Place::Base(PlaceBase::Local(ref_rcvr)),
box Rvalue::Ref(tcx.types.re_erased, borrow_kind, rcvr_l) box Rvalue::Ref(tcx.types.re_erased, borrow_kind, rcvr_l)
) )
}); });
Operand::Move(Place::Local(ref_rcvr)) Operand::Move(Place::Base(PlaceBase::Local(ref_rcvr)))
} }
}; };
@ -774,12 +778,12 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if let Some(untuple_args) = untuple_args { if let Some(untuple_args) = untuple_args {
args.extend(untuple_args.iter().enumerate().map(|(i, ity)| { args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
let arg_place = Place::Local(Local::new(1+1)); let arg_place = Place::Base(PlaceBase::Local(Local::new(1+1)));
Operand::Move(arg_place.field(Field::new(i), *ity)) Operand::Move(arg_place.field(Field::new(i), *ity))
})); }));
} else { } else {
args.extend((1..sig.inputs().len()).map(|i| { args.extend((1..sig.inputs().len()).map(|i| {
Operand::Move(Place::Local(Local::new(1+i))) Operand::Move(Place::Base(PlaceBase::Local(Local::new(1+i))))
})); }));
} }
@ -797,7 +801,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
block(&mut blocks, statements, TerminatorKind::Call { block(&mut blocks, statements, TerminatorKind::Call {
func: callee, func: callee,
args, args,
destination: Some((Place::Local(RETURN_PLACE), destination: Some((Place::RETURN_PLACE,
BasicBlock::new(1))), BasicBlock::new(1))),
cleanup: if let Adjustment::RefMut = rcvr_adjustment { cleanup: if let Adjustment::RefMut = rcvr_adjustment {
Some(BasicBlock::new(3)) Some(BasicBlock::new(3))
@ -810,7 +814,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if let Adjustment::RefMut = rcvr_adjustment { if let Adjustment::RefMut = rcvr_adjustment {
// BB #1 - drop for Self // BB #1 - drop for Self
block(&mut blocks, vec![], TerminatorKind::Drop { block(&mut blocks, vec![], TerminatorKind::Drop {
location: Place::Local(rcvr_arg), location: Place::Base(PlaceBase::Local(rcvr_arg)),
target: BasicBlock::new(2), target: BasicBlock::new(2),
unwind: None unwind: None
}, false); }, false);
@ -820,7 +824,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if let Adjustment::RefMut = rcvr_adjustment { if let Adjustment::RefMut = rcvr_adjustment {
// BB #3 - drop if closure panics // BB #3 - drop if closure panics
block(&mut blocks, vec![], TerminatorKind::Drop { block(&mut blocks, vec![], TerminatorKind::Drop {
location: Place::Local(rcvr_arg), location: Place::Base(PlaceBase::Local(rcvr_arg)),
target: BasicBlock::new(4), target: BasicBlock::new(4),
unwind: None unwind: None
}, true); }, true);
@ -892,11 +896,11 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
statements: vec![Statement { statements: vec![Statement {
source_info, source_info,
kind: StatementKind::Assign( kind: StatementKind::Assign(
Place::Local(RETURN_PLACE), Place::RETURN_PLACE,
box Rvalue::Aggregate( box Rvalue::Aggregate(
box AggregateKind::Adt(adt_def, variant_no, substs, None, None), box AggregateKind::Adt(adt_def, variant_no, substs, None, None),
(1..sig.inputs().len()+1).map(|i| { (1..sig.inputs().len()+1).map(|i| {
Operand::Move(Place::Local(Local::new(i))) Operand::Move(Place::Base(PlaceBase::Local(Local::new(i))))
}).collect() }).collect()
) )
) )

View file

@ -121,10 +121,10 @@ fn add_move_for_packed_drop<'a, 'tcx>(
patch.add_statement( patch.add_statement(
loc, StatementKind::StorageLive(temp)); loc, StatementKind::StorageLive(temp));
patch.add_assign(loc, Place::Local(temp), patch.add_assign(loc, Place::Base(PlaceBase::Local(temp)),
Rvalue::Use(Operand::Move(location.clone()))); Rvalue::Use(Operand::Move(location.clone())));
patch.patch_terminator(loc.block, TerminatorKind::Drop { patch.patch_terminator(loc.block, TerminatorKind::Drop {
location: Place::Local(temp), location: Place::Base(PlaceBase::Local(temp)),
target: storage_dead_block, target: storage_dead_block,
unwind unwind
}); });

View file

@ -21,9 +21,9 @@ fn is_stable<'tcx>(
match *place { match *place {
// Locals and statics have stable addresses, for sure // Locals and statics have stable addresses, for sure
Local { .. } | Base(PlaceBase::Local { .. }) |
Promoted { .. } | Base(PlaceBase::Promoted { .. }) |
Static { .. } => Base(PlaceBase::Static { .. }) =>
true, true,
// Recurse for projections // Recurse for projections
Projection(ref proj) => { Projection(ref proj) => {
@ -101,7 +101,7 @@ impl MirPass for AddRetag {
}; };
// Gather all arguments, skip return value. // Gather all arguments, skip return value.
let places = local_decls.iter_enumerated().skip(1).take(arg_count) let places = local_decls.iter_enumerated().skip(1).take(arg_count)
.map(|(local, _)| Place::Local(local)) .map(|(local, _)| Place::Base(PlaceBase::Local(local)))
.filter(needs_retag) .filter(needs_retag)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
// Emit their retags. // Emit their retags.

View file

@ -241,7 +241,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
); );
} }
let old_source_info = self.source_info; let old_source_info = self.source_info;
if let &Place::Local(local) = base { if let &Place::Base(PlaceBase::Local(local)) = base {
if self.mir.local_decls[local].internal { if self.mir.local_decls[local].internal {
// Internal locals are used in the `move_val_init` desugaring. // Internal locals are used in the `move_val_init` desugaring.
// We want to check unsafety against the source info of the // We want to check unsafety against the source info of the
@ -297,13 +297,13 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
} }
self.source_info = old_source_info; self.source_info = old_source_info;
} }
&Place::Local(..) => { &Place::Base(PlaceBase::Local(..)) => {
// locals are safe // locals are safe
} }
&Place::Promoted(_) => { &Place::Base(PlaceBase::Promoted(_)) => {
bug!("unsafety checking should happen before promotion") bug!("unsafety checking should happen before promotion")
} }
&Place::Static(box Static { def_id, ty: _ }) => { &Place::Base(PlaceBase::Static(box Static { def_id, ty: _ })) => {
if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) { if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) {
self.require_unsafe("use of mutable static", self.require_unsafe("use of mutable static",
"mutable statics can be mutated by multiple threads: aliasing violations \ "mutable statics can be mutated by multiple threads: aliasing violations \

View file

@ -3,7 +3,7 @@
use rustc::hir::def::Def; use rustc::hir::def::Def;
use rustc::mir::{Constant, Location, Place, Mir, Operand, Rvalue, Local}; use rustc::mir::{Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local};
use rustc::mir::{NullOp, UnOp, StatementKind, Statement, BasicBlock, LocalKind}; use rustc::mir::{NullOp, UnOp, StatementKind, Statement, BasicBlock, LocalKind};
use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem}; use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem};
use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext}; use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext};
@ -267,7 +267,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> { fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> {
match *place { match *place {
Place::Local(loc) => self.places[loc].clone(), Place::Base(PlaceBase::Local(loc)) => self.places[loc].clone(),
Place::Projection(ref proj) => match proj.elem { Place::Projection(ref proj) => match proj.elem {
ProjectionElem::Field(field, _) => { ProjectionElem::Field(field, _) => {
trace!("field proj on {:?}", proj.base); trace!("field proj on {:?}", proj.base);
@ -282,7 +282,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
// an `Index` projection would throw us off-track. // an `Index` projection would throw us off-track.
_ => None, _ => None,
}, },
Place::Promoted(ref promoted) => { Place::Base(PlaceBase::Promoted(ref promoted)) => {
let generics = self.tcx.generics_of(self.source.def_id()); let generics = self.tcx.generics_of(self.source.def_id());
if generics.requires_monomorphization(self.tcx) { if generics.requires_monomorphization(self.tcx) {
// FIXME: can't handle code with generics // FIXME: can't handle code with generics
@ -556,7 +556,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
.to_ty(self.tcx); .to_ty(self.tcx);
if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) { if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) {
if let Some(value) = self.const_prop(rval, place_layout, statement.source_info) { if let Some(value) = self.const_prop(rval, place_layout, statement.source_info) {
if let Place::Local(local) = *place { if let Place::Base(PlaceBase::Local(local)) = *place {
trace!("checking whether {:?} can be stored to {:?}", value, local); trace!("checking whether {:?} can be stored to {:?}", value, local);
if self.can_const_prop[local] { if self.can_const_prop[local] {
trace!("storing {:?} to {:?}", value, local); trace!("storing {:?} to {:?}", value, local);
@ -591,7 +591,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
while let Place::Projection(ref proj) = *place { while let Place::Projection(ref proj) = *place {
place = &proj.base; place = &proj.base;
} }
if let Place::Local(local) = *place { if let Place::Base(PlaceBase::Local(local)) = *place {
self.places[local] = None; self.places[local] = None;
} }
}, },

View file

@ -19,7 +19,9 @@
//! (non-mutating) use of `SRC`. These restrictions are conservative and may be relaxed in the //! (non-mutating) use of `SRC`. These restrictions are conservative and may be relaxed in the
//! future. //! future.
use rustc::mir::{Constant, Local, LocalKind, Location, Place, Mir, Operand, Rvalue, StatementKind}; use rustc::mir::{
Constant, Local, LocalKind, Location, Place, PlaceBase, Mir, Operand, Rvalue, StatementKind
};
use rustc::mir::visit::MutVisitor; use rustc::mir::visit::MutVisitor;
use rustc::ty::TyCtxt; use rustc::ty::TyCtxt;
use crate::transform::{MirPass, MirSource}; use crate::transform::{MirPass, MirSource};
@ -94,8 +96,10 @@ impl MirPass for CopyPropagation {
// That use of the source must be an assignment. // That use of the source must be an assignment.
match statement.kind { match statement.kind {
StatementKind::Assign(Place::Local(local), box Rvalue::Use(ref operand)) if StatementKind::Assign(
local == dest_local => { Place::Base(PlaceBase::Local(local)),
box Rvalue::Use(ref operand)
) if local == dest_local => {
let maybe_action = match *operand { let maybe_action = match *operand {
Operand::Copy(ref src_place) | Operand::Copy(ref src_place) |
Operand::Move(ref src_place) => { Operand::Move(ref src_place) => {
@ -144,12 +148,12 @@ fn eliminate_self_assignments<'tcx>(
if let Some(stmt) = mir[location.block].statements.get(location.statement_index) { if let Some(stmt) = mir[location.block].statements.get(location.statement_index) {
match stmt.kind { match stmt.kind {
StatementKind::Assign( StatementKind::Assign(
Place::Local(local), Place::Base(PlaceBase::Local(local)),
box Rvalue::Use(Operand::Copy(Place::Local(src_local))), box Rvalue::Use(Operand::Copy(Place::Base(PlaceBase::Local(src_local)))),
) | ) |
StatementKind::Assign( StatementKind::Assign(
Place::Local(local), Place::Base(PlaceBase::Local(local)),
box Rvalue::Use(Operand::Move(Place::Local(src_local))), box Rvalue::Use(Operand::Move(Place::Base(PlaceBase::Local(src_local)))),
) if local == dest_local && dest_local == src_local => {} ) if local == dest_local && dest_local == src_local => {}
_ => { _ => {
continue; continue;
@ -176,7 +180,7 @@ impl<'tcx> Action<'tcx> {
fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis<'_>, src_place: &Place<'tcx>) fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis<'_>, src_place: &Place<'tcx>)
-> Option<Action<'tcx>> { -> Option<Action<'tcx>> {
// The source must be a local. // The source must be a local.
let src_local = if let Place::Local(local) = *src_place { let src_local = if let Place::Base(PlaceBase::Local(local)) = *src_place {
local local
} else { } else {
debug!(" Can't copy-propagate local: source is not a local"); debug!(" Can't copy-propagate local: source is not a local");
@ -330,8 +334,8 @@ impl<'tcx> MutVisitor<'tcx> for ConstantPropagationVisitor<'tcx> {
self.super_operand(operand, location); self.super_operand(operand, location);
match *operand { match *operand {
Operand::Copy(Place::Local(local)) | Operand::Copy(Place::Base(PlaceBase::Local(local))) |
Operand::Move(Place::Local(local)) if local == self.dest_local => {} Operand::Move(Place::Base(PlaceBase::Local(local))) if local == self.dest_local => {}
_ => return, _ => return,
} }

View file

@ -330,7 +330,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
} }
fn drop_flag(&mut self, index: MovePathIndex) -> Option<Place<'tcx>> { fn drop_flag(&mut self, index: MovePathIndex) -> Option<Place<'tcx>> {
self.drop_flags.get(&index).map(|t| Place::Local(*t)) self.drop_flags.get(&index).map(|t| Place::Base(PlaceBase::Local(*t)))
} }
/// create a patch that elaborates all drops in the input /// create a patch that elaborates all drops in the input
@ -543,7 +543,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
if let Some(&flag) = self.drop_flags.get(&path) { if let Some(&flag) = self.drop_flags.get(&path) {
let span = self.patch.source_info_for_location(self.mir, loc).span; let span = self.patch.source_info_for_location(self.mir, loc).span;
let val = self.constant_bool(span, val.value()); let val = self.constant_bool(span, val.value());
self.patch.add_assign(loc, Place::Local(flag), val); self.patch.add_assign(loc, Place::Base(PlaceBase::Local(flag)), val);
} }
} }
@ -552,7 +552,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let span = self.patch.source_info_for_location(self.mir, loc).span; let span = self.patch.source_info_for_location(self.mir, loc).span;
let false_ = self.constant_bool(span, false); let false_ = self.constant_bool(span, false);
for flag in self.drop_flags.values() { for flag in self.drop_flags.values() {
self.patch.add_assign(loc, Place::Local(*flag), false_.clone()); self.patch.add_assign(loc, Place::Base(PlaceBase::Local(*flag)), false_.clone());
} }
} }

View file

@ -102,7 +102,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor {
place: &mut Place<'tcx>, place: &mut Place<'tcx>,
context: PlaceContext<'tcx>, context: PlaceContext<'tcx>,
location: Location) { location: Location) {
if *place == Place::Local(self_arg()) { if *place == Place::Base(PlaceBase::Local(self_arg())) {
*place = Place::Projection(Box::new(Projection { *place = Place::Projection(Box::new(Projection {
base: place.clone(), base: place.clone(),
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
@ -129,7 +129,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
place: &mut Place<'tcx>, place: &mut Place<'tcx>,
context: PlaceContext<'tcx>, context: PlaceContext<'tcx>,
location: Location) { location: Location) {
if *place == Place::Local(self_arg()) { if *place == Place::Base(PlaceBase::Local(self_arg())) {
*place = Place::Projection(Box::new(Projection { *place = Place::Projection(Box::new(Projection {
base: place.clone(), base: place.clone(),
elem: ProjectionElem::Field(Field::new(0), self.ref_gen_ty), elem: ProjectionElem::Field(Field::new(0), self.ref_gen_ty),
@ -183,7 +183,7 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
// Create a Place referencing a generator struct field // Create a Place referencing a generator struct field
fn make_field(&self, idx: usize, ty: Ty<'tcx>) -> Place<'tcx> { fn make_field(&self, idx: usize, ty: Ty<'tcx>) -> Place<'tcx> {
let base = Place::Local(self_arg()); let base = Place::Base(PlaceBase::Local(self_arg()));
let field = Projection { let field = Projection {
base: base, base: base,
elem: ProjectionElem::Field(Field::new(idx), ty), elem: ProjectionElem::Field(Field::new(idx), ty),
@ -223,7 +223,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
place: &mut Place<'tcx>, place: &mut Place<'tcx>,
context: PlaceContext<'tcx>, context: PlaceContext<'tcx>,
location: Location) { location: Location) {
if let Place::Local(l) = *place { if let Place::Base(PlaceBase::Local(l)) = *place {
// Replace an Local in the remap with a generator struct access // Replace an Local in the remap with a generator struct access
if let Some(&(ty, idx)) = self.remap.get(&l) { if let Some(&(ty, idx)) = self.remap.get(&l) {
*place = self.make_field(idx, ty); *place = self.make_field(idx, ty);
@ -249,7 +249,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
let ret_val = match data.terminator().kind { let ret_val = match data.terminator().kind {
TerminatorKind::Return => Some((VariantIdx::new(1), TerminatorKind::Return => Some((VariantIdx::new(1),
None, None,
Operand::Move(Place::Local(self.new_ret_local)), Operand::Move(Place::Base(PlaceBase::Local(self.new_ret_local))),
None)), None)),
TerminatorKind::Yield { ref value, resume, drop } => Some((VariantIdx::new(0), TerminatorKind::Yield { ref value, resume, drop } => Some((VariantIdx::new(0),
Some(resume), Some(resume),
@ -263,7 +263,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
// We must assign the value first in case it gets declared dead below // We must assign the value first in case it gets declared dead below
data.statements.push(Statement { data.statements.push(Statement {
source_info, source_info,
kind: StatementKind::Assign(Place::Local(RETURN_PLACE), kind: StatementKind::Assign(Place::RETURN_PLACE,
box self.make_state(state_idx, v)), box self.make_state(state_idx, v)),
}); });
let state = if let Some(resume) = resume { // Yield let state = if let Some(resume) = resume { // Yield
@ -597,7 +597,7 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
&Terminator { &Terminator {
source_info, source_info,
kind: TerminatorKind::Drop { kind: TerminatorKind::Drop {
location: Place::Local(local), location: Place::Base(PlaceBase::Local(local)),
target, target,
unwind unwind
} }
@ -619,7 +619,7 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
elaborate_drop( elaborate_drop(
&mut elaborator, &mut elaborator,
source_info, source_info,
&Place::Local(gen), &Place::Base(PlaceBase::Local(gen)),
(), (),
target, target,
unwind, unwind,
@ -693,7 +693,7 @@ fn create_generator_drop_shim<'a, 'tcx>(
// Alias tracking must know we changed the type // Alias tracking must know we changed the type
mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement { mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
source_info, source_info,
kind: StatementKind::Retag(RetagKind::Raw, Place::Local(self_arg())), kind: StatementKind::Retag(RetagKind::Raw, Place::Base(PlaceBase::Local(self_arg()))),
}) })
} }
@ -809,7 +809,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. // Create a block to destroy an unresumed generators. This can only destroy upvars.
let drop_clean = BasicBlock::new(mir.basic_blocks().len()); let drop_clean = BasicBlock::new(mir.basic_blocks().len());
let term = TerminatorKind::Drop { let term = TerminatorKind::Drop {
location: Place::Local(self_arg()), location: Place::Base(PlaceBase::Local(self_arg())),
target: return_block, target: return_block,
unwind: None, unwind: None,
}; };

View file

@ -449,7 +449,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
} }
// Static variables need a borrow because the callee // Static variables need a borrow because the callee
// might modify the same static. // might modify the same static.
Place::Static(_) => true, Place::Base(PlaceBase::Static(_)) => true,
_ => false _ => false
} }
} }
@ -466,7 +466,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
let temp = LocalDecl::new_temp(ty, callsite.location.span); let temp = LocalDecl::new_temp(ty, callsite.location.span);
let tmp = caller_mir.local_decls.push(temp); let tmp = caller_mir.local_decls.push(temp);
let tmp = Place::Local(tmp); let tmp = Place::Base(PlaceBase::Local(tmp));
let stmt = Statement { let stmt = Statement {
source_info: callsite.location, source_info: callsite.location,
@ -560,7 +560,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_mir); let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_mir);
assert!(args.next().is_none()); assert!(args.next().is_none());
let tuple = Place::Local(tuple); let tuple = Place::Base(PlaceBase::Local(tuple));
let tuple_tys = if let ty::Tuple(s) = tuple.ty(caller_mir, tcx).to_ty(tcx).sty { let tuple_tys = if let ty::Tuple(s) = tuple.ty(caller_mir, tcx).to_ty(tcx).sty {
s s
} else { } else {
@ -599,7 +599,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
// FIXME: Analysis of the usage of the arguments to avoid // FIXME: Analysis of the usage of the arguments to avoid
// unnecessary temporaries. // unnecessary temporaries.
if let Operand::Move(Place::Local(local)) = arg { if let Operand::Move(Place::Base(PlaceBase::Local(local))) = arg {
if caller_mir.local_kind(local) == LocalKind::Temp { if caller_mir.local_kind(local) == LocalKind::Temp {
// Reuse the operand if it's a temporary already // Reuse the operand if it's a temporary already
return local; return local;
@ -617,7 +617,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
let stmt = Statement { let stmt = Statement {
source_info: callsite.location, source_info: callsite.location,
kind: StatementKind::Assign(Place::Local(arg_tmp), box arg), kind: StatementKind::Assign(Place::Base(PlaceBase::Local(arg_tmp)), box arg),
}; };
caller_mir[callsite.bb].statements.push(stmt); caller_mir[callsite.bb].statements.push(stmt);
arg_tmp arg_tmp
@ -665,7 +665,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
_location: Location) { _location: Location) {
if *local == RETURN_PLACE { if *local == RETURN_PLACE {
match self.destination { match self.destination {
Place::Local(l) => { Place::Base(PlaceBase::Local(l)) => {
*local = l; *local = l;
return; return;
}, },
@ -686,11 +686,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
_location: Location) { _location: Location) {
match place { match place {
Place::Local(RETURN_PLACE) => { Place::Base(PlaceBase::Local(RETURN_PLACE)) => {
// Return pointer; update the place itself // Return pointer; update the place itself
*place = self.destination.clone(); *place = self.destination.clone();
}, },
Place::Promoted(ref mut promoted) => { Place::Base(PlaceBase::Promoted(ref mut promoted)) => {
if let Some(p) = self.promoted_map.get(promoted.0).cloned() { if let Some(p) = self.promoted_map.get(promoted.0).cloned() {
promoted.0 = p; promoted.0 = p;
} }

View file

@ -1,6 +1,6 @@
//! Performs various peephole optimizations. //! Performs various peephole optimizations.
use rustc::mir::{Constant, Location, Place, Mir, Operand, ProjectionElem, Rvalue, Local}; use rustc::mir::{Constant, Location, Place, PlaceBase, Mir, Operand, ProjectionElem, Rvalue, Local};
use rustc::mir::visit::{MutVisitor, Visitor}; use rustc::mir::visit::{MutVisitor, Visitor};
use rustc::ty::{TyCtxt, TyKind}; use rustc::ty::{TyCtxt, TyKind};
use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc::util::nodemap::{FxHashMap, FxHashSet};
@ -45,7 +45,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
let new_place = match *rvalue { let new_place = match *rvalue {
Rvalue::Ref(_, _, Place::Projection(ref mut projection)) => { Rvalue::Ref(_, _, Place::Projection(ref mut projection)) => {
// Replace with dummy // Replace with dummy
mem::replace(&mut projection.base, Place::Local(Local::new(0))) mem::replace(&mut projection.base, Place::Base(PlaceBase::Local(Local::new(0))))
} }
_ => bug!("Detected `&*` but didn't find `&*`!"), _ => bug!("Detected `&*` but didn't find `&*`!"),
}; };

View file

@ -86,13 +86,13 @@ impl Lower128Bit {
block.statements.push(Statement { block.statements.push(Statement {
source_info: source_info, source_info: source_info,
kind: StatementKind::Assign( kind: StatementKind::Assign(
Place::Local(local), Place::Base(PlaceBase::Local(local)),
box Rvalue::Cast( box Rvalue::Cast(
CastKind::Misc, CastKind::Misc,
rhs, rhs,
rhs_override_ty.unwrap())), rhs_override_ty.unwrap())),
}); });
rhs = Operand::Move(Place::Local(local)); rhs = Operand::Move(Place::Base(PlaceBase::Local(local)));
} }
let call_did = check_lang_item_type( let call_did = check_lang_item_type(

View file

@ -178,7 +178,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
span, span,
scope: OUTERMOST_SOURCE_SCOPE scope: OUTERMOST_SOURCE_SCOPE
}, },
kind: StatementKind::Assign(Place::Local(dest), box rvalue) kind: StatementKind::Assign(Place::Base(PlaceBase::Local(dest)), box rvalue)
}); });
} }
@ -268,7 +268,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
func, func,
args, args,
cleanup: None, cleanup: None,
destination: Some((Place::Local(new_temp), new_target)), destination: Some(
(Place::Base(PlaceBase::Local(new_temp)), new_target)
),
from_hir_call, from_hir_call,
}, },
..terminator ..terminator
@ -292,7 +294,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
promoted.span = span; promoted.span = span;
promoted.local_decls[RETURN_PLACE] = promoted.local_decls[RETURN_PLACE] =
LocalDecl::new_return_place(ty, span); LocalDecl::new_return_place(ty, span);
Place::Promoted(box (promoted_id, ty)) Place::Base(PlaceBase::Promoted(box (promoted_id, ty)))
}; };
let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut(); let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();
match candidate { match candidate {
@ -373,7 +375,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
match candidate { match candidate {
Candidate::Ref(Location { block, statement_index }) => { Candidate::Ref(Location { block, statement_index }) => {
match mir[block].statements[statement_index].kind { match mir[block].statements[statement_index].kind {
StatementKind::Assign(Place::Local(local), _) => { StatementKind::Assign(Place::Base(PlaceBase::Local(local)), _) => {
if temps[local] == TempState::PromotedOut { if temps[local] == TempState::PromotedOut {
// Already promoted. // Already promoted.
continue; continue;
@ -420,7 +422,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
for block in mir.basic_blocks_mut() { for block in mir.basic_blocks_mut() {
block.statements.retain(|statement| { block.statements.retain(|statement| {
match statement.kind { match statement.kind {
StatementKind::Assign(Place::Local(index), _) | StatementKind::Assign(Place::Base(PlaceBase::Local(index)), _) |
StatementKind::StorageLive(index) | StatementKind::StorageLive(index) |
StatementKind::StorageDead(index) => { StatementKind::StorageDead(index) => {
!promoted(index) !promoted(index)
@ -430,7 +432,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
}); });
let terminator = block.terminator_mut(); let terminator = block.terminator_mut();
match terminator.kind { match terminator.kind {
TerminatorKind::Drop { location: Place::Local(index), target, .. } => { TerminatorKind::Drop { location: Place::Base(PlaceBase::Local(index)), target, .. } => {
if promoted(index) { if promoted(index) {
terminator.kind = TerminatorKind::Goto { terminator.kind = TerminatorKind::Goto {
target, target,

View file

@ -186,9 +186,9 @@ trait Qualif {
fn in_place(cx: &ConstCx<'_, 'tcx>, place: &Place<'tcx>) -> bool { fn in_place(cx: &ConstCx<'_, 'tcx>, place: &Place<'tcx>) -> bool {
match *place { match *place {
Place::Local(local) => Self::in_local(cx, local), Place::Base(PlaceBase::Local(local)) => Self::in_local(cx, local),
Place::Promoted(_) => bug!("qualifying already promoted MIR"), Place::Base(PlaceBase::Promoted(_)) => bug!("qualifying already promoted MIR"),
Place::Static(ref static_) => Self::in_static(cx, static_), Place::Base(PlaceBase::Static(ref static_)) => Self::in_static(cx, static_),
Place::Projection(ref proj) => Self::in_projection(cx, proj), Place::Projection(ref proj) => Self::in_projection(cx, proj),
} }
} }
@ -730,7 +730,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
place = &proj.base; place = &proj.base;
} }
debug!("qualify_consts: promotion candidate: place={:?}", place); debug!("qualify_consts: promotion candidate: place={:?}", place);
if let Place::Local(local) = *place { if let Place::Base(PlaceBase::Local(local)) = *place {
if self.mir.local_kind(local) == LocalKind::Temp { if self.mir.local_kind(local) == LocalKind::Temp {
debug!("qualify_consts: promotion candidate: local={:?}", local); debug!("qualify_consts: promotion candidate: local={:?}", local);
// The borrowed place doesn't have `HasMutInterior` // The borrowed place doesn't have `HasMutInterior`
@ -754,7 +754,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
let index = loop { let index = loop {
match dest { match dest {
// We treat all locals equal in constants // We treat all locals equal in constants
Place::Local(index) => break *index, Place::Base(PlaceBase::Local(index)) => break *index,
// projections are transparent for assignments // projections are transparent for assignments
// we qualify the entire destination at once, even if just a field would have // we qualify the entire destination at once, even if just a field would have
// stricter qualification // stricter qualification
@ -768,8 +768,9 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
); );
dest = &proj.base; dest = &proj.base;
}, },
Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"), Place::Base(PlaceBase::Promoted(..)) =>
Place::Static(..) => { bug!("promoteds don't exist yet during promotion"),
Place::Base(PlaceBase::Static(..)) => {
// Catch more errors in the destination. `visit_place` also checks that we // Catch more errors in the destination. `visit_place` also checks that we
// do not try to access statics from constants or try to mutate statics // do not try to access statics from constants or try to mutate statics
self.visit_place( self.visit_place(
@ -878,7 +879,10 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
match *candidate { match *candidate {
Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => { Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
match self.mir[bb].statements[stmt_idx].kind { match self.mir[bb].statements[stmt_idx].kind {
StatementKind::Assign(_, box Rvalue::Ref(_, _, Place::Local(index))) => { StatementKind::Assign(
_,
box Rvalue::Ref(_, _, Place::Base(PlaceBase::Local(index)))
) => {
promoted_temps.insert(index); promoted_temps.insert(index);
} }
_ => {} _ => {}
@ -915,9 +919,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
debug!("visit_place: place={:?} context={:?} location={:?}", place, context, location); debug!("visit_place: place={:?} context={:?} location={:?}", place, context, location);
self.super_place(place, context, location); self.super_place(place, context, location);
match *place { match *place {
Place::Local(_) | Place::Base(PlaceBase::Local(_)) |
Place::Promoted(_) => {} Place::Base(PlaceBase::Promoted(_)) => {}
Place::Static(ref global) => { Place::Base(PlaceBase::Static(ref global)) => {
if self.tcx if self.tcx
.get_attrs(global.def_id) .get_attrs(global.def_id)
.iter() .iter()
@ -1032,7 +1036,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
match *operand { match *operand {
Operand::Move(ref place) => { Operand::Move(ref place) => {
// Mark the consumed locals to indicate later drops are noops. // Mark the consumed locals to indicate later drops are noops.
if let Place::Local(local) = *place { if let Place::Base(PlaceBase::Local(local)) = *place {
self.cx.per_local[NeedsDrop].remove(local); self.cx.per_local[NeedsDrop].remove(local);
} }
} }
@ -1335,7 +1339,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
unleash_miri!(self); unleash_miri!(self);
// HACK(eddyb): emulate a bit of dataflow analysis, // HACK(eddyb): emulate a bit of dataflow analysis,
// conservatively, that drop elaboration will do. // conservatively, that drop elaboration will do.
let needs_drop = if let Place::Local(local) = *place { let needs_drop = if let Place::Base(PlaceBase::Local(local)) = *place {
if NeedsDrop::in_local(self, local) { if NeedsDrop::in_local(self, local) {
Some(self.mir.local_decls[local].source_info.span) Some(self.mir.local_decls[local].source_info.span)
} else { } else {
@ -1565,7 +1569,11 @@ impl MirPass for QualifyAndPromoteConstants {
}); });
let terminator = block.terminator_mut(); let terminator = block.terminator_mut();
match terminator.kind { match terminator.kind {
TerminatorKind::Drop { location: Place::Local(index), target, .. } => { TerminatorKind::Drop {
location: Place::Base(PlaceBase::Local(index)),
target,
..
} => {
if promoted_temps.contains(index) { if promoted_temps.contains(index) {
terminator.kind = TerminatorKind::Goto { terminator.kind = TerminatorKind::Goto {
target, target,

View file

@ -252,10 +252,11 @@ fn check_place(
span: Span, span: Span,
) -> McfResult { ) -> McfResult {
match place { match place {
Place::Local(_) => Ok(()), Place::Base(PlaceBase::Local(_)) => Ok(()),
// promoteds are always fine, they are essentially constants // promoteds are always fine, they are essentially constants
Place::Promoted(_) => Ok(()), Place::Base(PlaceBase::Promoted(_)) => Ok(()),
Place::Static(_) => Err((span, "cannot access `static` items in const fn".into())), Place::Base(PlaceBase::Static(_)) =>
Err((span, "cannot access `static` items in const fn".into())),
Place::Projection(proj) => { Place::Projection(proj) => {
match proj.elem { match proj.elem {
| ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. }

View file

@ -47,7 +47,7 @@ impl RemoveNoopLandingPads {
// These are all nops in a landing pad // These are all nops in a landing pad
} }
StatementKind::Assign(Place::Local(_), box Rvalue::Use(_)) => { StatementKind::Assign(Place::Base(PlaceBase::Local(_)), box Rvalue::Use(_)) => {
// Writing to a local (e.g., a drop flag) does not // Writing to a local (e.g., a drop flag) does not
// turn a landing pad to a non-nop // turn a landing pad to a non-nop
} }

View file

@ -115,8 +115,8 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}; };
assert!(args.len() == 1); assert!(args.len() == 1);
let peek_arg_place = match args[0] { let peek_arg_place = match args[0] {
mir::Operand::Copy(ref place @ mir::Place::Local(_)) | mir::Operand::Copy(ref place @ mir::Place::Base(mir::PlaceBase::Local(_))) |
mir::Operand::Move(ref place @ mir::Place::Local(_)) => Some(place), mir::Operand::Move(ref place @ mir::Place::Base(mir::PlaceBase::Local(_))) => Some(place),
_ => None, _ => None,
}; };

View file

@ -101,7 +101,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
let temp = self.patch.new_temp(item_ty, self.mir.source_info(location).span); let temp = self.patch.new_temp(item_ty, self.mir.source_info(location).span);
self.patch.add_statement(location, StatementKind::StorageLive(temp)); self.patch.add_statement(location, StatementKind::StorageLive(temp));
self.patch.add_assign(location, self.patch.add_assign(location,
Place::Local(temp), Place::Base(PlaceBase::Local(temp)),
Rvalue::Use( Rvalue::Use(
Operand::Move( Operand::Move(
Place::Projection(box PlaceProjection{ Place::Projection(box PlaceProjection{
@ -113,12 +113,16 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
})))); }))));
temp temp
}).collect(); }).collect();
self.patch.add_assign(location, self.patch.add_assign(
dst_place.clone(), location,
Rvalue::Aggregate(box AggregateKind::Array(item_ty), dst_place.clone(),
temps.iter().map( Rvalue::Aggregate(
|x| Operand::Move(Place::Local(*x))).collect() box AggregateKind::Array(item_ty),
)); temps.iter().map(
|x| Operand::Move(Place::Base(PlaceBase::Local(*x)))
).collect()
)
);
for temp in temps { for temp in temps {
self.patch.add_statement(location, StatementKind::StorageDead(temp)); self.patch.add_statement(location, StatementKind::StorageDead(temp));
} }
@ -176,7 +180,7 @@ impl MirPass for RestoreSubsliceArrayMoveOut {
if let StatementKind::Assign(ref dst_place, ref rval) = statement.kind { if let StatementKind::Assign(ref dst_place, ref rval) = statement.kind {
if let Rvalue::Aggregate(box AggregateKind::Array(_), ref items) = **rval { if let Rvalue::Aggregate(box AggregateKind::Array(_), ref items) = **rval {
let items : Vec<_> = items.iter().map(|item| { let items : Vec<_> = items.iter().map(|item| {
if let Operand::Move(Place::Local(local)) = item { if let Operand::Move(Place::Base(PlaceBase::Local(local))) = item {
let local_use = &visitor.locals_use[*local]; let local_use = &visitor.locals_use[*local];
let opt_index_and_place = Self::try_get_item_source(local_use, mir); let opt_index_and_place = Self::try_get_item_source(local_use, mir);
// each local should be used twice: // each local should be used twice:
@ -257,7 +261,7 @@ impl RestoreSubsliceArrayMoveOut {
if block.statements.len() > location.statement_index { if block.statements.len() > location.statement_index {
let statement = &block.statements[location.statement_index]; let statement = &block.statements[location.statement_index];
if let StatementKind::Assign( if let StatementKind::Assign(
Place::Local(_), Place::Base(PlaceBase::Local(_)),
box Rvalue::Use(Operand::Move(Place::Projection(box PlaceProjection{ box Rvalue::Use(Operand::Move(Place::Projection(box PlaceProjection{
ref base, elem: ProjectionElem::ConstantIndex{ ref base, elem: ProjectionElem::ConstantIndex{
offset, min_length: _, from_end: false}})))) = statement.kind { offset, min_length: _, from_end: false}})))) = statement.kind {

View file

@ -486,7 +486,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
// discriminant after it is free-ed, because that // discriminant after it is free-ed, because that
// way lies only trouble. // way lies only trouble.
let discr_ty = adt.repr.discr_type().to_ty(self.tcx()); let discr_ty = adt.repr.discr_type().to_ty(self.tcx());
let discr = Place::Local(self.new_temp(discr_ty)); let discr = Place::Base(PlaceBase::Local(self.new_temp(discr_ty)));
let discr_rv = Rvalue::Discriminant(self.place.clone()); let discr_rv = Rvalue::Discriminant(self.place.clone());
let switch_block = BasicBlockData { let switch_block = BasicBlockData {
statements: vec![self.assign(&discr, discr_rv)], statements: vec![self.assign(&discr, discr_rv)],
@ -520,11 +520,11 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
mutbl: hir::Mutability::MutMutable mutbl: hir::Mutability::MutMutable
}); });
let ref_place = self.new_temp(ref_ty); let ref_place = self.new_temp(ref_ty);
let unit_temp = Place::Local(self.new_temp(tcx.mk_unit())); let unit_temp = Place::Base(PlaceBase::Local(self.new_temp(tcx.mk_unit())));
let result = BasicBlockData { let result = BasicBlockData {
statements: vec![self.assign( statements: vec![self.assign(
&Place::Local(ref_place), &Place::Base(PlaceBase::Local(ref_place)),
Rvalue::Ref(tcx.types.re_erased, Rvalue::Ref(tcx.types.re_erased,
BorrowKind::Mut { allow_two_phase_borrow: false }, BorrowKind::Mut { allow_two_phase_borrow: false },
self.place.clone()) self.place.clone())
@ -533,7 +533,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
kind: TerminatorKind::Call { kind: TerminatorKind::Call {
func: Operand::function_handle(tcx, drop_fn.def_id, substs, func: Operand::function_handle(tcx, drop_fn.def_id, substs,
self.source_info.span), self.source_info.span),
args: vec![Operand::Move(Place::Local(ref_place))], args: vec![Operand::Move(Place::Base(PlaceBase::Local(ref_place)))],
destination: Some((unit_temp, succ)), destination: Some((unit_temp, succ)),
cleanup: unwind.into_option(), cleanup: unwind.into_option(),
from_hir_call: true, from_hir_call: true,
@ -578,8 +578,8 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
ty: ety, ty: ety,
mutbl: hir::Mutability::MutMutable mutbl: hir::Mutability::MutMutable
}); });
let ptr = &Place::Local(self.new_temp(ref_ty)); let ptr = &Place::Base(PlaceBase::Local(self.new_temp(ref_ty)));
let can_go = &Place::Local(self.new_temp(tcx.types.bool)); let can_go = &Place::Base(PlaceBase::Local(self.new_temp(tcx.types.bool)));
let one = self.constant_usize(1); let one = self.constant_usize(1);
let (ptr_next, cur_next) = if ptr_based { let (ptr_next, cur_next) = if ptr_based {
@ -587,23 +587,23 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
tcx.types.re_erased, tcx.types.re_erased,
BorrowKind::Mut { allow_two_phase_borrow: false }, BorrowKind::Mut { allow_two_phase_borrow: false },
Place::Projection(Box::new(Projection { Place::Projection(Box::new(Projection {
base: Place::Local(cur), base: Place::Base(PlaceBase::Local(cur)),
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
})) }))
), ),
Rvalue::BinaryOp(BinOp::Offset, copy(&Place::Local(cur)), one)) Rvalue::BinaryOp(BinOp::Offset, copy(&Place::Base(PlaceBase::Local(cur))), one))
} else { } else {
(Rvalue::Ref( (Rvalue::Ref(
tcx.types.re_erased, tcx.types.re_erased,
BorrowKind::Mut { allow_two_phase_borrow: false }, BorrowKind::Mut { allow_two_phase_borrow: false },
self.place.clone().index(cur)), self.place.clone().index(cur)),
Rvalue::BinaryOp(BinOp::Add, copy(&Place::Local(cur)), one)) Rvalue::BinaryOp(BinOp::Add, copy(&Place::Base(PlaceBase::Local(cur))), one))
}; };
let drop_block = BasicBlockData { let drop_block = BasicBlockData {
statements: vec![ statements: vec![
self.assign(ptr, ptr_next), self.assign(ptr, ptr_next),
self.assign(&Place::Local(cur), cur_next) self.assign(&Place::Base(PlaceBase::Local(cur)), cur_next)
], ],
is_cleanup: unwind.is_cleanup(), is_cleanup: unwind.is_cleanup(),
terminator: Some(Terminator { terminator: Some(Terminator {
@ -617,7 +617,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
let loop_block = BasicBlockData { let loop_block = BasicBlockData {
statements: vec![ statements: vec![
self.assign(can_go, Rvalue::BinaryOp(BinOp::Eq, self.assign(can_go, Rvalue::BinaryOp(BinOp::Eq,
copy(&Place::Local(cur)), copy(&Place::Base(PlaceBase::Local(cur))),
copy(length_or_end))) copy(length_or_end)))
], ],
is_cleanup: unwind.is_cleanup(), is_cleanup: unwind.is_cleanup(),
@ -667,8 +667,8 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
let move_ = |place: &Place<'tcx>| Operand::Move(place.clone()); let move_ = |place: &Place<'tcx>| Operand::Move(place.clone());
let tcx = self.tcx(); let tcx = self.tcx();
let size = &Place::Local(self.new_temp(tcx.types.usize)); let size = &Place::Base(PlaceBase::Local(self.new_temp(tcx.types.usize)));
let size_is_zero = &Place::Local(self.new_temp(tcx.types.bool)); let size_is_zero = &Place::Base(PlaceBase::Local(self.new_temp(tcx.types.bool)));
let base_block = BasicBlockData { let base_block = BasicBlockData {
statements: vec![ statements: vec![
self.assign(size, Rvalue::NullaryOp(NullOp::SizeOf, ety)), self.assign(size, Rvalue::NullaryOp(NullOp::SizeOf, ety)),
@ -703,9 +703,12 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
}; };
let cur = self.new_temp(iter_ty); let cur = self.new_temp(iter_ty);
let length = Place::Local(self.new_temp(tcx.types.usize)); let length = Place::Base(PlaceBase::Local(self.new_temp(tcx.types.usize)));
let length_or_end = if ptr_based { let length_or_end = if ptr_based {
Place::Local(self.new_temp(iter_ty)) // FIXME check if we want to make it return a `Place` directly
// if all use sites want a `Place::Base` anyway.
let temp = self.new_temp(iter_ty);
Place::Base(PlaceBase::Local(temp))
} else { } else {
length.clone() length.clone()
}; };
@ -728,13 +731,13 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
unwind, unwind,
ptr_based); ptr_based);
let cur = Place::Local(cur); let cur = Place::Base(PlaceBase::Local(cur));
let zero = self.constant_usize(0); let zero = self.constant_usize(0);
let mut drop_block_stmts = vec![]; let mut drop_block_stmts = vec![];
drop_block_stmts.push(self.assign(&length, Rvalue::Len(self.place.clone()))); drop_block_stmts.push(self.assign(&length, Rvalue::Len(self.place.clone())));
if ptr_based { if ptr_based {
let tmp_ty = tcx.mk_mut_ptr(self.place_ty(self.place)); let tmp_ty = tcx.mk_mut_ptr(self.place_ty(self.place));
let tmp = Place::Local(self.new_temp(tmp_ty)); let tmp = Place::Base(PlaceBase::Local(self.new_temp(tmp_ty)));
// tmp = &mut P; // tmp = &mut P;
// cur = tmp as *mut T; // cur = tmp as *mut T;
// end = Offset(cur, len); // end = Offset(cur, len);
@ -883,7 +886,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
unwind: Unwind unwind: Unwind
) -> BasicBlock { ) -> BasicBlock {
let tcx = self.tcx(); let tcx = self.tcx();
let unit_temp = Place::Local(self.new_temp(tcx.mk_unit())); let unit_temp = Place::Base(PlaceBase::Local(self.new_temp(tcx.mk_unit())));
let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem); let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem);
let args = adt.variants[VariantIdx::new(0)].fields.iter().enumerate().map(|(i, f)| { let args = adt.variants[VariantIdx::new(0)].fields.iter().enumerate().map(|(i, f)| {
let field = Field::new(i); let field = Field::new(i);

View file

@ -134,7 +134,11 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
if i > 0 { if i > 0 {
write!(w, ", ")?; write!(w, ", ")?;
} }
write!(w, "{:?}: {}", Place::Local(arg), escape(&mir.local_decls[arg].ty))?; write!(w,
"{:?}: {}",
Place::Base(PlaceBase::Local(arg)),
escape(&mir.local_decls[arg].ty)
)?;
} }
write!(w, ") -&gt; {}", escape(mir.return_ty()))?; write!(w, ") -&gt; {}", escape(mir.return_ty()))?;
@ -150,10 +154,10 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
if let Some(name) = decl.name { if let Some(name) = decl.name {
write!(w, r#"{:?}: {}; // {}<br align="left"/>"#, write!(w, r#"{:?}: {}; // {}<br align="left"/>"#,
Place::Local(local), escape(&decl.ty), name)?; Place::Base(PlaceBase::Local(local)), escape(&decl.ty), name)?;
} else { } else {
write!(w, r#"let mut {:?}: {};<br align="left"/>"#, write!(w, r#"let mut {:?}: {};<br align="left"/>"#,
Place::Local(local), escape(&decl.ty))?; Place::Base(PlaceBase::Local(local)), escape(&decl.ty))?;
} }
} }

View file

@ -625,7 +625,7 @@ fn write_mir_sig(
if i != 0 { if i != 0 {
write!(w, ", ")?; write!(w, ", ")?;
} }
write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].ty)?; write!(w, "{:?}: {}", Place::Base(PlaceBase::Local(arg)), mir.local_decls[arg].ty)?;
} }
write!(w, ") -> {}", mir.return_ty())?; write!(w, ") -> {}", mir.return_ty())?;