From: Santiago Pastorino Date: Wed, 11 Dec 2019 19:50:03 +0000 (-0300) Subject: Remove PlaceBase enum and make Place base field be local: Local X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=5d9b39904436f6f20e34e85a4e06384116080f56;p=rust.git Remove PlaceBase enum and make Place base field be local: Local --- diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 05bb1d96980..32d85314c7a 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1655,7 +1655,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { /// changing or disturbing program state. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable)] pub struct Place<'tcx> { - pub base: PlaceBase, + pub local: Local, /// projection out of a place (access a field, deref a pointer, etc) pub projection: &'tcx List>, @@ -1663,12 +1663,6 @@ pub struct Place<'tcx> { impl<'tcx> rustc_serialize::UseSpecializedDecodable for Place<'tcx> {} -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)] -pub enum PlaceBase { - /// local variable - Local(Local), -} - #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(RustcEncodable, RustcDecodable, HashStable)] pub enum ProjectionElem { @@ -1756,14 +1750,14 @@ pub struct Field { #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct PlaceRef<'a, 'tcx> { - pub base: &'a PlaceBase, + pub local: &'a Local, pub projection: &'a [PlaceElem<'tcx>], } impl<'tcx> Place<'tcx> { // FIXME change this to a const fn by also making List::empty a const fn. pub fn return_place() -> Place<'tcx> { - Place { base: PlaceBase::Local(RETURN_PLACE), projection: List::empty() } + Place { local: RETURN_PLACE, projection: List::empty() } } /// Returns `true` if this `Place` contains a `Deref` projection. @@ -1780,10 +1774,8 @@ pub fn is_indirect(&self) -> bool { // FIXME: can we safely swap the semantics of `fn base_local` below in here instead? pub fn local_or_deref_local(&self) -> Option { match self.as_ref() { - PlaceRef { base: &PlaceBase::Local(local), projection: &[] } - | PlaceRef { base: &PlaceBase::Local(local), projection: &[ProjectionElem::Deref] } => { - Some(local) - } + PlaceRef { local, projection: &[] } + | PlaceRef { local, projection: &[ProjectionElem::Deref] } => Some(*local), _ => None, } } @@ -1795,19 +1787,13 @@ pub fn as_local(&self) -> Option { } pub fn as_ref(&self) -> PlaceRef<'_, 'tcx> { - PlaceRef { base: &self.base, projection: &self.projection } + PlaceRef { local: &self.local, projection: &self.projection } } } impl From for Place<'_> { fn from(local: Local) -> Self { - Place { base: local.into(), projection: List::empty() } - } -} - -impl From for PlaceBase { - fn from(local: Local) -> Self { - PlaceBase::Local(local) + Place { local: local.into(), projection: List::empty() } } } @@ -1818,10 +1804,8 @@ impl<'a, 'tcx> PlaceRef<'a, 'tcx> { // FIXME: can we safely swap the semantics of `fn base_local` below in here instead? pub fn local_or_deref_local(&self) -> Option { match self { - PlaceRef { base: PlaceBase::Local(local), projection: [] } - | PlaceRef { base: PlaceBase::Local(local), projection: [ProjectionElem::Deref] } => { - Some(*local) - } + PlaceRef { local, projection: [] } + | PlaceRef { local, projection: [ProjectionElem::Deref] } => Some(**local), _ => None, } } @@ -1830,7 +1814,7 @@ pub fn local_or_deref_local(&self) -> Option { /// projections, return `Some(_X)`. pub fn as_local(&self) -> Option { match self { - PlaceRef { base: PlaceBase::Local(l), projection: [] } => Some(*l), + PlaceRef { local, projection: [] } => Some(**local), _ => None, } } @@ -1852,7 +1836,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { } } - write!(fmt, "{:?}", self.base)?; + write!(fmt, "{:?}", self.local)?; for elem in self.projection.iter() { match elem { @@ -1896,14 +1880,6 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { } } -impl Debug for PlaceBase { - fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { - match *self { - PlaceBase::Local(id) => write!(fmt, "{:?}", id), - } - } -} - /////////////////////////////////////////////////////////////////////////// // Scopes @@ -2964,25 +2940,11 @@ fn super_visit_with>(&self, _: &mut V) -> bool { impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { - Place { base: self.base.fold_with(folder), projection: self.projection.fold_with(folder) } + Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) } } fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.base.visit_with(visitor) || self.projection.visit_with(visitor) - } -} - -impl<'tcx> TypeFoldable<'tcx> for PlaceBase { - fn super_fold_with>(&self, folder: &mut F) -> Self { - match self { - PlaceBase::Local(local) => PlaceBase::Local(local.fold_with(folder)), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match self { - PlaceBase::Local(local) => local.visit_with(visitor), - } + self.local.visit_with(visitor) || self.projection.visit_with(visitor) } } diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 5adf6447d39..e2aac562cc4 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -114,7 +114,7 @@ pub fn projection_ty_core( impl<'tcx> Place<'tcx> { pub fn ty_from( - base: &PlaceBase, + local: &Local, projection: &[PlaceElem<'tcx>], local_decls: &D, tcx: TyCtxt<'tcx>, @@ -124,25 +124,16 @@ pub fn ty_from( { projection .iter() - .fold(base.ty(local_decls), |place_ty, elem| place_ty.projection_ty(tcx, elem)) + .fold(PlaceTy::from_ty(local_decls.local_decls()[*local].ty), |place_ty, elem| { + place_ty.projection_ty(tcx, elem) + }) } pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> where D: HasLocalDecls<'tcx>, { - Place::ty_from(&self.base, &self.projection, local_decls, tcx) - } -} - -impl<'tcx> PlaceBase { - pub fn ty(&self, local_decls: &D) -> PlaceTy<'tcx> - where - D: HasLocalDecls<'tcx>, - { - match self { - PlaceBase::Local(index) => PlaceTy::from_ty(local_decls.local_decls()[*index].ty), - } + Place::ty_from(&self.local, &self.projection, local_decls, tcx) } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index a31931c8a99..4c5db1b07d2 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -164,10 +164,10 @@ fn visit_place(&mut self, } fn visit_place_base(&mut self, - base: & $($mutability)? PlaceBase, + local: & $($mutability)? Local, context: PlaceContext, location: Location) { - self.super_place_base(base, context, location); + self.super_place_base(local, context, location); } visit_place_fns!($($mutability)?); @@ -705,14 +705,10 @@ fn super_retag(&mut self, } fn super_place_base(&mut self, - place_base: & $($mutability)? PlaceBase, + local: & $($mutability)? Local, context: PlaceContext, location: Location) { - match place_base { - PlaceBase::Local(local) => { - self.visit_local(local, context, location); - } - } + self.visit_local(local, context, location); } fn super_local_decl(&mut self, @@ -845,7 +841,7 @@ fn super_place( context: PlaceContext, location: Location, ) { - self.visit_place_base(&mut place.base, context, location); + self.visit_place_base(&mut place.local, context, location); if let Some(new_projection) = self.process_projection(&place.projection) { place.projection = self.tcx().intern_place_elems(&new_projection); @@ -886,23 +882,23 @@ fn process_projection_elem( () => ( fn visit_projection( &mut self, - base: &PlaceBase, + local: &Local, projection: &[PlaceElem<'tcx>], context: PlaceContext, location: Location, ) { - self.super_projection(base, projection, context, location); + self.super_projection(local, projection, context, location); } fn visit_projection_elem( &mut self, - base: &PlaceBase, + local: &Local, proj_base: &[PlaceElem<'tcx>], elem: &PlaceElem<'tcx>, context: PlaceContext, location: Location, ) { - self.super_projection_elem(base, proj_base, elem, context, location); + self.super_projection_elem(local, proj_base, elem, context, location); } fn super_place( @@ -921,9 +917,9 @@ fn super_place( }; } - self.visit_place_base(&place.base, context, location); + self.visit_place_base(&place.local, context, location); - self.visit_projection(&place.base, + self.visit_projection(&place.local, &place.projection, context, location); @@ -931,7 +927,7 @@ fn super_place( fn super_projection( &mut self, - base: &PlaceBase, + local: &Local, projection: &[PlaceElem<'tcx>], context: PlaceContext, location: Location, @@ -939,13 +935,13 @@ fn super_projection( let mut cursor = projection; while let [proj_base @ .., elem] = cursor { cursor = proj_base; - self.visit_projection_elem(base, cursor, elem, context, location); + self.visit_projection_elem(local, cursor, elem, context, location); } } fn super_projection_elem( &mut self, - _base: &PlaceBase, + _local: &Local, _proj_base: &[PlaceElem<'tcx>], elem: &PlaceElem<'tcx>, _context: PlaceContext, diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index c691cb44f01..df1602b2ac4 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -226,11 +226,11 @@ pub fn decode_place(decoder: &mut D) -> Result, D::Error> where D: TyDecoder<'tcx>, { - let base: mir::PlaceBase = Decodable::decode(decoder)?; + let local: mir::Local = Decodable::decode(decoder)?; let len = decoder.read_usize()?; let projection: &'tcx List> = decoder.tcx().mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?; - Ok(mir::Place { base, projection }) + Ok(mir::Place { local, projection }) } #[inline] diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 17f5b98ab20..52a151439dc 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2434,7 +2434,7 @@ pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<' let mut projection = place.projection.to_vec(); projection.push(elem); - Place { base: place.base, projection: self.intern_place_elems(&projection) } + Place { local: place.local, projection: self.intern_place_elems(&projection) } } pub fn intern_existential_predicates( diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 8d8e86de4d4..d1f70ad43bd 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1286,9 +1286,9 @@ fn generator_layout_and_saved_local_names( let generator_layout = body.generator_layout.as_ref().unwrap(); let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys); - let state_arg = mir::PlaceBase::Local(mir::Local::new(1)); + let state_arg = mir::Local::new(1); for var in &body.var_debug_info { - if var.place.base != state_arg { + if var.place.local != state_arg { continue; } match var.place.projection[..] { diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 7b9bc923cd6..c3affd233f8 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -128,17 +128,13 @@ fn process_place( }; if is_consume { let base_ty = - mir::Place::ty_from(place_ref.base, proj_base, *self.fx.mir, cx.tcx()); + mir::Place::ty_from(place_ref.local, proj_base, *self.fx.mir, cx.tcx()); let base_ty = self.fx.monomorphize(&base_ty); // ZSTs don't require any actual memory access. let elem_ty = base_ty.projection_ty(cx.tcx(), elem).ty; let elem_ty = self.fx.monomorphize(&elem_ty); - let span = match place_ref.base { - mir::PlaceBase::Local(index) => { - self.fx.mir.local_decls[*index].source_info.span - } - }; + let span = self.fx.mir.local_decls[*place_ref.local].source_info.span; if cx.spanned_layout_of(elem_ty, span).is_zst() { return; } @@ -178,9 +174,7 @@ fn process_place( // We use `NonUseContext::VarDebugInfo` for the base, // which might not force the base local to memory, // so we have to do it manually. - match place_ref.base { - mir::PlaceBase::Local(local) => self.visit_local(&local, context, location), - } + self.visit_local(place_ref.local, context, location); } } @@ -191,7 +185,7 @@ fn process_place( } self.process_place( - &mir::PlaceRef { base: place_ref.base, projection: proj_base }, + &mir::PlaceRef { local: place_ref.local, projection: proj_base }, base_context, location, ); @@ -218,8 +212,8 @@ fn process_place( }; } - self.visit_place_base(place_ref.base, context, location); - self.visit_projection(place_ref.base, place_ref.projection, context, location); + self.visit_place_base(place_ref.local, context, location); + self.visit_projection(place_ref.local, place_ref.projection, context, location); } } } diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index a1ff62fde0a..fa79541701e 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -1109,7 +1109,7 @@ fn make_return_dest( } else { self.codegen_place( bx, - &mir::PlaceRef { base: &dest.base, projection: &dest.projection }, + &mir::PlaceRef { local: &dest.local, projection: &dest.projection }, ) }; if fn_ret.is_indirect() { diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs index 88e43c7f535..e0aec5d6dd5 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -258,9 +258,7 @@ pub fn per_local_var_debug_info( if tcx.sess.opts.debuginfo == DebugInfo::Full || !tcx.sess.fewer_names() { let mut per_local = IndexVec::from_elem(vec![], &body.local_decls); for var in &body.var_debug_info { - match var.place.base { - mir::PlaceBase::Local(local) => per_local[local].push(var), - } + per_local[var.place.local].push(var); } Some(per_local) } else { diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index be6e05b948c..a155a6e78f7 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -373,43 +373,39 @@ fn maybe_codegen_consume_direct( ) -> Option> { debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref); - match place_ref.base { - mir::PlaceBase::Local(index) => { - match self.locals[*index] { - LocalRef::Operand(Some(mut o)) => { - // Moves out of scalar and scalar pair fields are trivial. - for elem in place_ref.projection.iter() { - match elem { - mir::ProjectionElem::Field(ref f, _) => { - o = o.extract_field(bx, f.index()); - } - mir::ProjectionElem::Index(_) - | mir::ProjectionElem::ConstantIndex { .. } => { - // ZSTs don't require any actual memory access. - // FIXME(eddyb) deduplicate this with the identical - // checks in `codegen_consume` and `extract_field`. - let elem = o.layout.field(bx.cx(), 0); - if elem.is_zst() { - o = OperandRef::new_zst(bx, elem); - } else { - return None; - } - } - _ => return None, + match self.locals[*place_ref.local] { + LocalRef::Operand(Some(mut o)) => { + // Moves out of scalar and scalar pair fields are trivial. + for elem in place_ref.projection.iter() { + match elem { + mir::ProjectionElem::Field(ref f, _) => { + o = o.extract_field(bx, f.index()); + } + mir::ProjectionElem::Index(_) + | mir::ProjectionElem::ConstantIndex { .. } => { + // ZSTs don't require any actual memory access. + // FIXME(eddyb) deduplicate this with the identical + // checks in `codegen_consume` and `extract_field`. + let elem = o.layout.field(bx.cx(), 0); + if elem.is_zst() { + o = OperandRef::new_zst(bx, elem); + } else { + return None; } } - - Some(o) - } - LocalRef::Operand(None) => { - bug!("use of {:?} before def", place_ref); - } - LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => { - // watch out for locals that do not have an - // alloca; they are handled somewhat differently - None + _ => return None, } } + + Some(o) + } + LocalRef::Operand(None) => { + bug!("use of {:?} before def", place_ref); + } + LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => { + // watch out for locals that do not have an + // alloca; they are handled somewhat differently + None } } } diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 3d94cf9aa2c..5e03a35b8a6 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -415,28 +415,26 @@ pub fn codegen_place( let tcx = self.cx.tcx(); let result = match place_ref { - mir::PlaceRef { base: mir::PlaceBase::Local(index), projection: [] } => { - match self.locals[*index] { - LocalRef::Place(place) => { - return place; - } - LocalRef::UnsizedPlace(place) => { - return bx.load_operand(place).deref(cx); - } - LocalRef::Operand(..) => { - bug!("using operand local {:?} as place", place_ref); - } + mir::PlaceRef { local, projection: [] } => match self.locals[**local] { + LocalRef::Place(place) => { + return place; } - } - mir::PlaceRef { base, projection: [proj_base @ .., mir::ProjectionElem::Deref] } => { + LocalRef::UnsizedPlace(place) => { + return bx.load_operand(place).deref(cx); + } + LocalRef::Operand(..) => { + bug!("using operand local {:?} as place", place_ref); + } + }, + mir::PlaceRef { local, projection: [proj_base @ .., mir::ProjectionElem::Deref] } => { // Load the pointer from its location. - self.codegen_consume(bx, &mir::PlaceRef { base, projection: proj_base }) + self.codegen_consume(bx, &mir::PlaceRef { local, projection: proj_base }) .deref(bx.cx()) } - mir::PlaceRef { base, projection: [proj_base @ .., elem] } => { + mir::PlaceRef { local, projection: [proj_base @ .., elem] } => { // FIXME turn this recursion into iteration let cg_base = - self.codegen_place(bx, &mir::PlaceRef { base, projection: proj_base }); + self.codegen_place(bx, &mir::PlaceRef { local, projection: proj_base }); match elem { mir::ProjectionElem::Deref => bug!(), @@ -501,7 +499,7 @@ pub fn codegen_place( pub fn monomorphized_place_ty(&self, place_ref: &mir::PlaceRef<'_, 'tcx>) -> Ty<'tcx> { let tcx = self.cx.tcx(); - let place_ty = mir::Place::ty_from(place_ref.base, place_ref.projection, *self.mir, tcx); + let place_ty = mir::Place::ty_from(place_ref.local, place_ref.projection, *self.mir, tcx); self.monomorphize(&place_ty.ty) } } diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index 4c6b9bc02a4..f2a44986cc4 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -208,11 +208,7 @@ fn visit_assign( self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx); - match borrowed_place.base { - mir::PlaceBase::Local(local) => { - self.local_map.entry(local).or_default().insert(idx); - } - } + self.local_map.entry(borrowed_place.local).or_default().insert(idx); } self.super_assign(assigned_place, rvalue, location) diff --git a/src/librustc_mir/borrow_check/constraint_generation.rs b/src/librustc_mir/borrow_check/constraint_generation.rs index 2a9ad6a1505..0f6a360c793 100644 --- a/src/librustc_mir/borrow_check/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/constraint_generation.rs @@ -2,8 +2,8 @@ use rustc::mir::visit::TyContext; use rustc::mir::visit::Visitor; use rustc::mir::{ - BasicBlock, BasicBlockData, Body, Local, Location, Place, PlaceBase, PlaceRef, ProjectionElem, - Rvalue, SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UserTypeProjection, + BasicBlock, BasicBlockData, Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, + SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UserTypeProjection, }; use rustc::ty::fold::TypeFoldable; use rustc::ty::subst::SubstsRef; @@ -188,11 +188,8 @@ fn record_killed_borrows_for_place(&mut self, place: &Place<'tcx>, location: Loc // of the borrows are killed: the ones whose `borrowed_place` // conflicts with the `place`. match place.as_ref() { - PlaceRef { base: &PlaceBase::Local(local), projection: &[] } - | PlaceRef { - base: &PlaceBase::Local(local), - projection: &[ProjectionElem::Deref], - } => { + PlaceRef { local, projection: &[] } + | PlaceRef { local, projection: &[ProjectionElem::Deref] } => { debug!( "Recording `killed` facts for borrows of local={:?} at location={:?}", local, location @@ -202,12 +199,12 @@ fn record_killed_borrows_for_place(&mut self, place: &Place<'tcx>, location: Loc all_facts, self.borrow_set, self.location_table, - &local, + local, location, ); } - PlaceRef { base: &PlaceBase::Local(local), projection: &[.., _] } => { + PlaceRef { local, projection: &[.., _] } => { // Kill conflicting borrows of the innermost local. debug!( "Recording `killed` facts for borrows of \ @@ -215,7 +212,7 @@ fn record_killed_borrows_for_place(&mut self, place: &Place<'tcx>, location: Loc local, location ); - if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) { + if let Some(borrow_indices) = self.borrow_set.local_map.get(local) { for &borrow_index in borrow_indices { let places_conflict = places_conflict::places_conflict( self.infcx.tcx, diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index dc3157f6b4d..08333ae423d 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -1,7 +1,7 @@ use rustc::mir::{ self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, - FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceBase, - PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm, + FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, + ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm, }; use rustc::traits::error_reporting::suggest_constraining_type_param; use rustc::ty::{self, Ty}; @@ -186,7 +186,7 @@ pub(in crate::borrow_check) fn report_use_of_moved_or_uninitialized( } let ty = - Place::ty_from(used_place.base, used_place.projection, *self.body, self.infcx.tcx) + Place::ty_from(used_place.local, used_place.projection, *self.body, self.infcx.tcx) .ty; let needs_note = match ty.kind { ty::Closure(id, _) => { @@ -597,15 +597,15 @@ pub(in crate::borrow_check) fn describe_place_for_conflicting_borrow( // field access to a union. If we find that, then we will keep the place of the // union being accessed and the field that was being accessed so we can check the // second borrowed place for the same union and a access to a different field. - let Place { base, projection } = first_borrowed_place; + let Place { local, projection } = first_borrowed_place; let mut cursor = projection.as_ref(); while let [proj_base @ .., elem] = cursor { cursor = proj_base; match elem { - ProjectionElem::Field(field, _) if union_ty(base, proj_base).is_some() => { - return Some((PlaceRef { base: base, projection: proj_base }, field)); + ProjectionElem::Field(field, _) if union_ty(local, proj_base).is_some() => { + return Some((PlaceRef { local, projection: proj_base }, field)); } _ => {} } @@ -615,21 +615,21 @@ pub(in crate::borrow_check) fn describe_place_for_conflicting_borrow( .and_then(|(target_base, target_field)| { // With the place of a union and a field access into it, we traverse the second // borrowed place and look for a access to a different field of the same union. - let Place { base, projection } = second_borrowed_place; + let Place { local, projection } = second_borrowed_place; let mut cursor = projection.as_ref(); while let [proj_base @ .., elem] = cursor { cursor = proj_base; if let ProjectionElem::Field(field, _) = elem { - if let Some(union_ty) = union_ty(base, proj_base) { + if let Some(union_ty) = union_ty(local, proj_base) { if field != target_field - && base == target_base.base + && local == target_base.local && proj_base == target_base.projection { // FIXME when we avoid clone reuse describe_place closure let describe_base_place = self - .describe_place(PlaceRef { base: base, projection: proj_base }) + .describe_place(PlaceRef { local, projection: proj_base }) .unwrap_or_else(|| "_".to_owned()); return Some(( @@ -686,14 +686,12 @@ pub(in crate::borrow_check) fn report_borrowed_value_does_not_live_long_enough( let borrow_span = borrow_spans.var_or_use(); assert!(root_place.projection.is_empty()); - let proper_span = match root_place.base { - PlaceBase::Local(local) => self.body.local_decls[*local].source_info.span, - }; + let proper_span = self.body.local_decls[*root_place.local].source_info.span; let root_place_projection = self.infcx.tcx.intern_place_elems(root_place.projection); if self.access_place_error_reported.contains(&( - Place { base: root_place.base.clone(), projection: root_place_projection }, + Place { local: root_place.local.clone(), projection: root_place_projection }, borrow_span, )) { debug!( @@ -704,22 +702,17 @@ pub(in crate::borrow_check) fn report_borrowed_value_does_not_live_long_enough( } self.access_place_error_reported.insert(( - Place { base: root_place.base.clone(), projection: root_place_projection }, + Place { local: root_place.local.clone(), projection: root_place_projection }, borrow_span, )); - match borrow.borrowed_place.base { - PlaceBase::Local(local) => { - if self.body.local_decls[local].is_ref_to_thread_local() { - let err = self.report_thread_local_value_does_not_live_long_enough( - drop_span, - borrow_span, - ); - err.buffer(&mut self.errors_buffer); - return; - } - } - }; + let borrowed_local = borrow.borrowed_place.local; + if self.body.local_decls[borrowed_local].is_ref_to_thread_local() { + let err = + self.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span); + err.buffer(&mut self.errors_buffer); + return; + } if let StorageDeadOrDrop::Destructor(dropped_ty) = self.classify_drop_access_kind(borrow.borrowed_place.as_ref()) @@ -1145,12 +1138,7 @@ fn try_report_cannot_return_reference_to_local( } else { let root_place = self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap(); - let local = - if let PlaceRef { base: PlaceBase::Local(local), projection: [] } = root_place { - local - } else { - bug!("try_report_cannot_return_reference_to_local: not a local") - }; + let local = root_place.local; match self.body.local_kind(*local) { LocalKind::ReturnPointer | LocalKind::Temp => { ("temporary value".to_string(), "temporary value created here".to_string()) @@ -1517,7 +1505,7 @@ fn classify_drop_access_kind(&self, place: PlaceRef<'cx, 'tcx>) -> StorageDeadOr [proj_base @ .., elem] => { // FIXME(spastorino) make this iterate let base_access = self.classify_drop_access_kind(PlaceRef { - base: place.base, + local: place.local, projection: proj_base, }); match elem { @@ -1525,7 +1513,9 @@ fn classify_drop_access_kind(&self, place: PlaceRef<'cx, 'tcx>) -> StorageDeadOr StorageDeadOrDrop::LocalStorageDead | StorageDeadOrDrop::BoxedStorageDead => { assert!( - Place::ty_from(&place.base, proj_base, *self.body, tcx).ty.is_box(), + Place::ty_from(&place.local, proj_base, *self.body, tcx) + .ty + .is_box(), "Drop of value behind a reference or raw pointer" ); StorageDeadOrDrop::BoxedStorageDead @@ -1533,7 +1523,7 @@ fn classify_drop_access_kind(&self, place: PlaceRef<'cx, 'tcx>) -> StorageDeadOr StorageDeadOrDrop::Destructor(_) => base_access, }, ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => { - let base_ty = Place::ty_from(&place.base, proj_base, *self.body, tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, *self.body, tcx).ty; match base_ty.kind { ty::Adt(def, _) if def.has_dtor(tcx) => { // Report the outermost adt with a destructor diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index 38c479c72c1..3f3bdb9d36c 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -2,8 +2,7 @@ use rustc::mir::{ AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place, - PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, - TerminatorKind, + PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc::ty::layout::VariantIdx; use rustc::ty::print::Print; @@ -169,30 +168,30 @@ fn append_place_to_string( including_downcast: &IncludingDowncast, ) -> Result<(), ()> { match place { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => { + PlaceRef { local, projection: [] } => { self.append_local_to_string(*local, buf)?; } - PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } - if self.body.local_decls[local].is_ref_for_guard() => + PlaceRef { local, projection: [ProjectionElem::Deref] } + if self.body.local_decls[*local].is_ref_for_guard() => { self.append_place_to_string( - PlaceRef { base: &PlaceBase::Local(local), projection: &[] }, + PlaceRef { local: local, projection: &[] }, buf, autoderef, &including_downcast, )?; } - PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } - if self.body.local_decls[local].is_ref_to_static() => + PlaceRef { local, projection: [ProjectionElem::Deref] } + if self.body.local_decls[*local].is_ref_to_static() => { - let local_info = &self.body.local_decls[local].local_info; + let local_info = &self.body.local_decls[*local].local_info; if let LocalInfo::StaticRef { def_id, .. } = *local_info { buf.push_str(&self.infcx.tcx.item_name(def_id).as_str()); } else { unreachable!(); } } - PlaceRef { base, projection: [proj_base @ .., elem] } => { + PlaceRef { local, projection: [proj_base @ .., elem] } => { match elem { ProjectionElem::Deref => { let upvar_field_projection = self.is_upvar_field_projection(place); @@ -208,29 +207,25 @@ fn append_place_to_string( if autoderef { // FIXME turn this recursion into iteration self.append_place_to_string( - PlaceRef { base, projection: proj_base }, + PlaceRef { local, projection: proj_base }, buf, autoderef, &including_downcast, )?; } else { - match (proj_base, base) { - _ => { - buf.push_str(&"*"); - self.append_place_to_string( - PlaceRef { base, projection: proj_base }, - buf, - autoderef, - &including_downcast, - )?; - } - } + buf.push_str(&"*"); + self.append_place_to_string( + PlaceRef { local, projection: proj_base }, + buf, + autoderef, + &including_downcast, + )?; } } } ProjectionElem::Downcast(..) => { self.append_place_to_string( - PlaceRef { base, projection: proj_base }, + PlaceRef { local, projection: proj_base }, buf, autoderef, &including_downcast, @@ -249,9 +244,9 @@ fn append_place_to_string( buf.push_str(&name); } else { let field_name = self - .describe_field(PlaceRef { base, projection: proj_base }, *field); + .describe_field(PlaceRef { local, projection: proj_base }, *field); self.append_place_to_string( - PlaceRef { base, projection: proj_base }, + PlaceRef { local, projection: proj_base }, buf, autoderef, &including_downcast, @@ -263,7 +258,7 @@ fn append_place_to_string( autoderef = true; self.append_place_to_string( - PlaceRef { base, projection: proj_base }, + PlaceRef { local, projection: proj_base }, buf, autoderef, &including_downcast, @@ -280,7 +275,7 @@ fn append_place_to_string( // then use another while the borrow is held, don't output indices details // to avoid confusing the end-user self.append_place_to_string( - PlaceRef { base, projection: proj_base }, + PlaceRef { local, projection: proj_base }, buf, autoderef, &including_downcast, @@ -311,17 +306,18 @@ fn append_local_to_string(&self, local: Local, buf: &mut String) -> Result<(), ( fn describe_field(&self, place: PlaceRef<'cx, 'tcx>, field: Field) -> String { // FIXME Place2 Make this work iteratively match place { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => { + PlaceRef { local, projection: [] } => { let local = &self.body.local_decls[*local]; self.describe_field_from_ty(&local.ty, field, None) } - PlaceRef { base, projection: [proj_base @ .., elem] } => match elem { + PlaceRef { local, projection: [proj_base @ .., elem] } => match elem { ProjectionElem::Deref => { - self.describe_field(PlaceRef { base, projection: proj_base }, field) + self.describe_field(PlaceRef { local, projection: proj_base }, field) } ProjectionElem::Downcast(_, variant_index) => { let base_ty = - Place::ty_from(place.base, place.projection, *self.body, self.infcx.tcx).ty; + Place::ty_from(place.local, place.projection, *self.body, self.infcx.tcx) + .ty; self.describe_field_from_ty(&base_ty, field, Some(*variant_index)) } ProjectionElem::Field(_, field_type) => { @@ -330,7 +326,7 @@ fn describe_field(&self, place: PlaceRef<'cx, 'tcx>, field: Field) -> String { ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { - self.describe_field(PlaceRef { base, projection: proj_base }, field) + self.describe_field(PlaceRef { local, projection: proj_base }, field) } }, } @@ -451,7 +447,7 @@ pub(super) fn borrowed_content_source( // If we didn't find an overloaded deref or index, then assume it's a // built in deref and check the type of the base. - let base_ty = Place::ty_from(deref_base.base, deref_base.projection, *self.body, tcx).ty; + let base_ty = Place::ty_from(deref_base.local, deref_base.projection, *self.body, tcx).ty; if base_ty.is_unsafe_ptr() { BorrowedContentSource::DerefRawPointer } else if base_ty.is_mutable_ptr() { diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs index ceb97a98f1f..eb6db7c145c 100644 --- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs @@ -273,7 +273,8 @@ fn report_cannot_move_from_static( let description = if place.projection.len() == 1 { format!("static item `{}`", self.describe_place(place.as_ref()).unwrap()) } else { - let base_static = PlaceRef { base: &place.base, projection: &[ProjectionElem::Deref] }; + let base_static = + PlaceRef { local: &place.local, projection: &[ProjectionElem::Deref] }; format!( "`{:?}` as `{:?}` is a static item", @@ -302,12 +303,12 @@ fn report_cannot_move_from_borrowed_content( let deref_base = match deref_target_place.projection.as_ref() { &[ref proj_base @ .., ProjectionElem::Deref] => { - PlaceRef { base: &deref_target_place.base, projection: &proj_base } + PlaceRef { local: &deref_target_place.local, projection: &proj_base } } _ => bug!("deref_target_place is not a deref projection"), }; - if let PlaceRef { base: PlaceBase::Local(local), projection: [] } = deref_base { + if let PlaceRef { local, projection: [] } = deref_base { let decl = &self.body.local_decls[*local]; if decl.is_ref_for_guard() { let mut err = self.cannot_move_out_of( diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index e81a012cef5..ae468e83ae2 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -1,5 +1,5 @@ use rustc::mir::{self, ClearCrossCrate, Local, LocalInfo, Location, ReadOnlyBodyAndCache}; -use rustc::mir::{Mutability, Place, PlaceBase, PlaceRef, ProjectionElem}; +use rustc::mir::{Mutability, Place, PlaceRef, ProjectionElem}; use rustc::ty::{self, Ty, TyCtxt}; use rustc_hir as hir; use rustc_hir::Node; @@ -42,7 +42,7 @@ pub(crate) fn report_mutability_error( debug!("report_mutability_error: access_place_desc={:?}", access_place_desc); match the_place_err { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => { + PlaceRef { local, projection: [] } => { item_msg = format!("`{}`", access_place_desc.unwrap()); if access_place.as_local().is_some() { reason = ", as it is not declared as mutable".to_string(); @@ -53,11 +53,11 @@ pub(crate) fn report_mutability_error( } PlaceRef { - base: _, + local, projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)], } => { debug_assert!(is_closure_or_generator( - Place::ty_from(&the_place_err.base, proj_base, *self.body, self.infcx.tcx).ty + Place::ty_from(local, proj_base, *self.body, self.infcx.tcx).ty )); item_msg = format!("`{}`", access_place_desc.unwrap()); @@ -69,21 +69,21 @@ pub(crate) fn report_mutability_error( } } - PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } - if self.body.local_decls[local].is_ref_for_guard() => + PlaceRef { local, projection: [ProjectionElem::Deref] } + if self.body.local_decls[*local].is_ref_for_guard() => { item_msg = format!("`{}`", access_place_desc.unwrap()); reason = ", as it is immutable for the pattern guard".to_string(); } - PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } - if self.body.local_decls[local].is_ref_to_static() => + PlaceRef { local, projection: [ProjectionElem::Deref] } + if self.body.local_decls[*local].is_ref_to_static() => { if access_place.projection.len() == 1 { item_msg = format!("immutable static item `{}`", access_place_desc.unwrap()); reason = String::new(); } else { item_msg = format!("`{}`", access_place_desc.unwrap()); - let local_info = &self.body.local_decls[local].local_info; + let local_info = &self.body.local_decls[*local].local_info; if let LocalInfo::StaticRef { def_id, .. } = *local_info { let static_name = &self.infcx.tcx.item_name(def_id); reason = format!(", as `{}` is an immutable static item", static_name); @@ -92,8 +92,8 @@ pub(crate) fn report_mutability_error( } } } - PlaceRef { base: _, projection: [proj_base @ .., ProjectionElem::Deref] } => { - if the_place_err.base == &PlaceBase::Local(Local::new(1)) + PlaceRef { local: _, projection: [proj_base @ .., ProjectionElem::Deref] } => { + if *the_place_err.local == Local::new(1) && proj_base.is_empty() && !self.upvars.is_empty() { @@ -101,7 +101,7 @@ pub(crate) fn report_mutability_error( debug_assert!(self.body.local_decls[Local::new(1)].ty.is_region_ptr()); debug_assert!(is_closure_or_generator( Place::ty_from( - the_place_err.base, + the_place_err.local, the_place_err.projection, *self.body, self.infcx.tcx @@ -116,7 +116,7 @@ pub(crate) fn report_mutability_error( } } else { let source = self.borrowed_content_source(PlaceRef { - base: the_place_err.base, + local: the_place_err.local, projection: proj_base, }); let pointer_type = source.describe_for_immutable_place(); @@ -136,10 +136,10 @@ pub(crate) fn report_mutability_error( } } - PlaceRef { base: _, projection: [.., ProjectionElem::Index(_)] } - | PlaceRef { base: _, projection: [.., ProjectionElem::ConstantIndex { .. }] } - | PlaceRef { base: _, projection: [.., ProjectionElem::Subslice { .. }] } - | PlaceRef { base: _, projection: [.., ProjectionElem::Downcast(..)] } => { + PlaceRef { local: _, projection: [.., ProjectionElem::Index(_)] } + | PlaceRef { local: _, projection: [.., ProjectionElem::ConstantIndex { .. }] } + | PlaceRef { local: _, projection: [.., ProjectionElem::Subslice { .. }] } + | PlaceRef { local: _, projection: [.., ProjectionElem::Downcast(..)] } => { bug!("Unexpected immutable place.") } } @@ -187,7 +187,7 @@ pub(crate) fn report_mutability_error( // struct we've got a field access of (it must be a reference since there's a deref // after the field access). PlaceRef { - base, + local, projection: [proj_base @ .., ProjectionElem::Deref, ProjectionElem::Field(field, _), ProjectionElem::Deref], } => { @@ -195,7 +195,7 @@ pub(crate) fn report_mutability_error( if let Some((span, message)) = annotate_struct_field( self.infcx.tcx, - Place::ty_from(base, proj_base, *self.body, self.infcx.tcx).ty, + Place::ty_from(local, proj_base, *self.body, self.infcx.tcx).ty, field, ) { err.span_suggestion( @@ -208,7 +208,7 @@ pub(crate) fn report_mutability_error( } // Suggest removing a `&mut` from the use of a mutable reference. - PlaceRef { base: PlaceBase::Local(local), projection: [] } + PlaceRef { local, projection: [] } if { self.body .local_decls @@ -246,7 +246,7 @@ pub(crate) fn report_mutability_error( // We want to suggest users use `let mut` for local (user // variable) mutations... - PlaceRef { base: PlaceBase::Local(local), projection: [] } + PlaceRef { local, projection: [] } if self.body.local_decls[*local].can_be_made_mutable() => { // ... but it doesn't make sense to suggest it on @@ -267,11 +267,11 @@ pub(crate) fn report_mutability_error( // Also suggest adding mut for upvars PlaceRef { - base, + local, projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)], } => { debug_assert!(is_closure_or_generator( - Place::ty_from(base, proj_base, *self.body, self.infcx.tcx).ty + Place::ty_from(local, proj_base, *self.body, self.infcx.tcx).ty )); err.span_label(span, format!("cannot {ACT}", ACT = act)); @@ -298,7 +298,7 @@ pub(crate) fn report_mutability_error( // complete hack to approximate old AST-borrowck // diagnostic: if the span starts with a mutable borrow of // a local variable, then just suggest the user remove it. - PlaceRef { base: PlaceBase::Local(_), projection: [] } + PlaceRef { local: _, projection: [] } if { if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { snippet.starts_with("&mut ") @@ -311,7 +311,7 @@ pub(crate) fn report_mutability_error( err.span_label(span, "try removing `&mut` here"); } - PlaceRef { base: PlaceBase::Local(local), projection: [ProjectionElem::Deref] } + PlaceRef { local, projection: [ProjectionElem::Deref] } if self.body.local_decls[*local].is_ref_for_guard() => { err.span_label(span, format!("cannot {ACT}", ACT = act)); @@ -325,7 +325,7 @@ pub(crate) fn report_mutability_error( // // FIXME: can this case be generalized to work for an // arbitrary base for the projection? - PlaceRef { base: PlaceBase::Local(local), projection: [ProjectionElem::Deref] } + PlaceRef { local, projection: [ProjectionElem::Deref] } if self.body.local_decls[*local].is_user_variable() => { let local_decl = &self.body.local_decls[*local]; @@ -408,10 +408,10 @@ pub(crate) fn report_mutability_error( } PlaceRef { - base, + local, projection: [ProjectionElem::Deref], // FIXME document what is this 1 magic number about - } if *base == PlaceBase::Local(Local::new(1)) && !self.upvars.is_empty() => { + } if *local == Local::new(1) && !self.upvars.is_empty() => { err.span_label(span, format!("cannot {ACT}", ACT = act)); err.span_help( self.body.span, @@ -419,7 +419,7 @@ pub(crate) fn report_mutability_error( ); } - PlaceRef { base: _, projection: [.., ProjectionElem::Deref] } => { + PlaceRef { local: _, projection: [.., ProjectionElem::Deref] } => { err.span_label(span, format!("cannot {ACT}", ACT = act)); match opt_source { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index d0b0a159e86..7b0a103fd00 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -5,7 +5,7 @@ use rustc::lint::builtin::UNUSED_MUT; use rustc::mir::{ read_only, Body, BodyAndCache, ClearCrossCrate, Local, Location, Mutability, Operand, Place, - PlaceBase, PlaceElem, PlaceRef, ReadOnlyBodyAndCache, + PlaceElem, PlaceRef, ReadOnlyBodyAndCache, }; use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; @@ -815,7 +815,7 @@ enum InitializationRequiringAction { } struct RootPlace<'d, 'tcx> { - place_base: &'d PlaceBase, + place_local: &'d Local, place_projection: &'d [PlaceElem<'tcx>], is_local_mutation_allowed: LocalMutationIsAllowed, } @@ -1252,11 +1252,7 @@ fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) { this.used_mut_upvars.push(field); } } else { - match place.base { - PlaceBase::Local(local) => { - this.used_mut.insert(local); - } - } + this.used_mut.insert(place.local); } }; @@ -1380,7 +1376,7 @@ fn check_for_invalidation_at_exit( debug!("check_for_invalidation_at_exit({:?})", borrow); let place = &borrow.borrowed_place; let deref = [ProjectionElem::Deref]; - let mut root_place = PlaceRef { base: &place.base, projection: &[] }; + let mut root_place = PlaceRef { local: &place.local, projection: &[] }; // FIXME(nll-rfc#40): do more precise destructor tracking here. For now // we just know that all locals are dropped at function exit (otherwise @@ -1388,19 +1384,16 @@ fn check_for_invalidation_at_exit( // // FIXME: allow thread-locals to borrow other thread locals? - let (might_be_alive, will_be_dropped) = match root_place.base { - PlaceBase::Local(local) => { - if self.body.local_decls[*local].is_ref_to_thread_local() { - // Thread-locals might be dropped after the function exits - // We have to dereference the outer reference because - // borrows don't conflict behind shared references. - root_place.projection = &deref; - (true, true) - } else { - (false, self.locals_are_invalidated_at_exit) - } - } - }; + let (might_be_alive, will_be_dropped) = + if self.body.local_decls[*root_place.local].is_ref_to_thread_local() { + // Thread-locals might be dropped after the function exits + // We have to dereference the outer reference because + // borrows don't conflict behind shared references. + root_place.projection = &deref; + (true, true) + } else { + (false, self.locals_are_invalidated_at_exit) + }; if !will_be_dropped { debug!("place_is_invalidated_at_exit({:?}) - won't be dropped", place); @@ -1738,9 +1731,9 @@ fn check_if_path_or_subpath_is_moved( place_span.0.projection { let place_ty = - Place::ty_from(place_span.0.base, base_proj, self.body(), self.infcx.tcx); + Place::ty_from(place_span.0.local, base_proj, self.body(), self.infcx.tcx); if let ty::Array(..) = place_ty.ty.kind { - let array_place = PlaceRef { base: place_span.0.base, projection: base_proj }; + let array_place = PlaceRef { local: place_span.0.local, projection: base_proj }; self.check_if_subslice_element_is_moved( location, desired_action, @@ -1837,7 +1830,7 @@ fn check_if_assigned_path_is_moved( self.check_if_full_path_is_moved( location, InitializationRequiringAction::Use, (PlaceRef { - base: &place.base, + local: &place.local, projection: proj_base, }, span), flow_state); // (base initialized; no need to @@ -1855,13 +1848,13 @@ fn check_if_assigned_path_is_moved( // assigning to `P.f` requires `P` itself // be already initialized let tcx = self.infcx.tcx; - let base_ty = Place::ty_from(&place.base, proj_base, self.body(), tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, self.body(), tcx).ty; match base_ty.kind { ty::Adt(def, _) if def.has_dtor(tcx) => { self.check_if_path_or_subpath_is_moved( location, InitializationRequiringAction::Assignment, (PlaceRef { - base: &place.base, + local: &place.local, projection: proj_base, }, span), flow_state); @@ -1874,23 +1867,14 @@ fn check_if_assigned_path_is_moved( // is allowed, remove this match arm. ty::Adt(..) | ty::Tuple(..) => { check_parent_of_field(self, location, PlaceRef { - base: &place.base, + local: &place.local, projection: proj_base, }, span, flow_state); - match place.base { - // rust-lang/rust#21232, - // #54499, #54986: during - // period where we reject - // partial initialization, do - // not complain about - // unnecessary `mut` on an - // attempt to do a partial - // initialization. - PlaceBase::Local(local) => { - self.used_mut.insert(local); - } - } + // rust-lang/rust#21232, #54499, #54986: during period where we reject + // partial initialization, do not complain about unnecessary `mut` on + // an attempt to do a partial initialization. + self.used_mut.insert(place.local); } _ => {} @@ -1968,7 +1952,7 @@ fn check_parent_of_field<'cx, 'tcx>( // of the union - we should error in that case. let tcx = this.infcx.tcx; if let ty::Adt(def, _) = - Place::ty_from(base.base, base.projection, this.body(), tcx).ty.kind + Place::ty_from(base.local, base.projection, this.body(), tcx).ty.kind { if def.is_union() { if this.move_data.path_map[mpi].iter().any(|moi| { @@ -2087,9 +2071,8 @@ fn check_access_permissions( // partial initialization, do not complain about mutability // errors except for actual mutation (as opposed to an attempt // to do a partial initialization). - let previously_initialized = match place.base { - PlaceBase::Local(local) => self.is_local_ever_initialized(local, flow_state).is_some(), - }; + let previously_initialized = + self.is_local_ever_initialized(place.local, flow_state).is_some(); // at this point, we have set up the error reporting state. if previously_initialized { @@ -2118,11 +2101,7 @@ fn is_local_ever_initialized( /// Adds the place into the used mutable variables set fn add_used_mut<'d>(&mut self, root_place: RootPlace<'d, 'tcx>, flow_state: &Flows<'cx, 'tcx>) { match root_place { - RootPlace { - place_base: PlaceBase::Local(local), - place_projection: [], - is_local_mutation_allowed, - } => { + RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => { // If the local may have been initialized, and it is now currently being // mutated, then it is justified to be annotated with the `mut` // keyword, since the mutation may be a possible reassignment. @@ -2133,18 +2112,18 @@ fn add_used_mut<'d>(&mut self, root_place: RootPlace<'d, 'tcx>, flow_state: &Flo } } RootPlace { - place_base: _, + place_local: _, place_projection: _, is_local_mutation_allowed: LocalMutationIsAllowed::Yes, } => {} RootPlace { - place_base, + place_local, place_projection: place_projection @ [.., _], is_local_mutation_allowed: _, } => { if let Some(field) = self.is_upvar_field_projection(PlaceRef { - base: &place_base, - projection: &place_projection, + local: place_local, + projection: place_projection, }) { self.used_mut_upvars.push(field); } @@ -2160,34 +2139,34 @@ fn is_mutable<'d>( is_local_mutation_allowed: LocalMutationIsAllowed, ) -> Result, PlaceRef<'d, 'tcx>> { match place { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => { + PlaceRef { local, projection: [] } => { let local = &self.body.local_decls[*local]; match local.mutability { Mutability::Not => match is_local_mutation_allowed { LocalMutationIsAllowed::Yes => Ok(RootPlace { - place_base: place.base, + place_local: place.local, place_projection: place.projection, is_local_mutation_allowed: LocalMutationIsAllowed::Yes, }), LocalMutationIsAllowed::ExceptUpvars => Ok(RootPlace { - place_base: place.base, + place_local: place.local, place_projection: place.projection, is_local_mutation_allowed: LocalMutationIsAllowed::ExceptUpvars, }), LocalMutationIsAllowed::No => Err(place), }, Mutability::Mut => Ok(RootPlace { - place_base: place.base, + place_local: place.local, place_projection: place.projection, is_local_mutation_allowed, }), } } - PlaceRef { base: _, projection: [proj_base @ .., elem] } => { + PlaceRef { local: _, projection: [proj_base @ .., elem] } => { match elem { ProjectionElem::Deref => { let base_ty = - Place::ty_from(place.base, proj_base, self.body(), self.infcx.tcx).ty; + Place::ty_from(place.local, proj_base, self.body(), self.infcx.tcx).ty; // Check the kind of deref to decide match base_ty.kind { @@ -2206,7 +2185,7 @@ fn is_mutable<'d>( }; self.is_mutable( - PlaceRef { base: place.base, projection: proj_base }, + PlaceRef { local: place.local, projection: proj_base }, mode, ) } @@ -2219,7 +2198,7 @@ fn is_mutable<'d>( // `*mut` raw pointers are always mutable, regardless of // context. The users have to check by themselves. hir::Mutability::Mut => Ok(RootPlace { - place_base: place.base, + place_local: place.local, place_projection: place.projection, is_local_mutation_allowed, }), @@ -2227,7 +2206,7 @@ fn is_mutable<'d>( } // `Box` owns its content, so mutable if its location is mutable _ if base_ty.is_box() => self.is_mutable( - PlaceRef { base: place.base, projection: proj_base }, + PlaceRef { local: place.local, projection: proj_base }, is_local_mutation_allowed, ), // Deref should only be for reference, pointers or boxes @@ -2283,11 +2262,11 @@ fn is_mutable<'d>( // } // ``` let _ = self.is_mutable( - PlaceRef { base: place.base, projection: proj_base }, + PlaceRef { local: place.local, projection: proj_base }, is_local_mutation_allowed, )?; Ok(RootPlace { - place_base: place.base, + place_local: place.local, place_projection: place.projection, is_local_mutation_allowed, }) @@ -2295,7 +2274,7 @@ fn is_mutable<'d>( } } else { self.is_mutable( - PlaceRef { base: place.base, projection: proj_base }, + PlaceRef { local: place.local, projection: proj_base }, is_local_mutation_allowed, ) } @@ -2321,7 +2300,7 @@ pub fn is_upvar_field_projection(&self, place_ref: PlaceRef<'cx, 'tcx>) -> Optio match place_projection { [base @ .., ProjectionElem::Field(field, _ty)] => { let tcx = self.infcx.tcx; - let base_ty = Place::ty_from(place_ref.base, base, self.body(), tcx).ty; + let base_ty = Place::ty_from(place_ref.local, base, self.body(), tcx).ty; if (base_ty.is_closure() || base_ty.is_generator()) && (!by_ref || self.upvars[field.index()].by_ref) diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index 41bf1aa47d4..deec6f386ff 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -3,7 +3,7 @@ use crate::borrow_check::AccessDepth; use crate::dataflow::indexes::BorrowIndex; use rustc::mir::BorrowKind; -use rustc::mir::{BasicBlock, Body, Location, Place, PlaceBase}; +use rustc::mir::{BasicBlock, Body, Location, Place}; use rustc::ty::TyCtxt; use rustc_data_structures::graph::dominators::Dominators; @@ -131,9 +131,7 @@ pub(super) fn is_active<'tcx>( /// Determines if a given borrow is borrowing local data /// This is called for all Yield expressions on movable generators pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool { - match place.base { - // Reborrow of already borrowed data is ignored - // Any errors will be caught on the initial borrow - PlaceBase::Local(_) => !place.is_indirect(), - } + // Reborrow of already borrowed data is ignored + // Any errors will be caught on the initial borrow + !place.is_indirect() } diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs index 445ba057c1b..ac02da26615 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/src/librustc_mir/borrow_check/place_ext.rs @@ -1,6 +1,6 @@ use crate::borrow_check::borrow_set::LocalsStateAtExit; use rustc::mir::ProjectionElem; -use rustc::mir::{Body, Mutability, Place, PlaceBase}; +use rustc::mir::{Body, Mutability, Place}; use rustc::ty::{self, TyCtxt}; use rustc_hir as hir; @@ -25,40 +25,35 @@ fn ignore_borrow( body: &Body<'tcx>, locals_state_at_exit: &LocalsStateAtExit, ) -> bool { - let local = match self.base { - // If a local variable is immutable, then we only need to track borrows to guard - // against two kinds of errors: - // * The variable being dropped while still borrowed (e.g., because the fn returns - // a reference to a local variable) - // * The variable being moved while still borrowed - // - // In particular, the variable cannot be mutated -- the "access checks" will fail -- - // so we don't have to worry about mutation while borrowed. - PlaceBase::Local(local) => match locals_state_at_exit { - LocalsStateAtExit::AllAreInvalidated => local, - LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => { - let ignore = !has_storage_dead_or_moved.contains(local) - && body.local_decls[local].mutability == Mutability::Not; - debug!("ignore_borrow: local {:?} => {:?}", local, ignore); - if ignore { - return true; - } else { - local - } - } - }, - }; + // If a local variable is immutable, then we only need to track borrows to guard + // against two kinds of errors: + // * The variable being dropped while still borrowed (e.g., because the fn returns + // a reference to a local variable) + // * The variable being moved while still borrowed + // + // In particular, the variable cannot be mutated -- the "access checks" will fail -- + // so we don't have to worry about mutation while borrowed. + if let LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } = + locals_state_at_exit + { + let ignore = !has_storage_dead_or_moved.contains(self.local) + && body.local_decls[self.local].mutability == Mutability::Not; + debug!("ignore_borrow: local {:?} => {:?}", self.local, ignore); + if ignore { + return true; + } + } for (i, elem) in self.projection.iter().enumerate() { let proj_base = &self.projection[..i]; if *elem == ProjectionElem::Deref { - let ty = Place::ty_from(&self.base, proj_base, body, tcx).ty; + let ty = Place::ty_from(&self.local, proj_base, body, tcx).ty; match ty.kind { ty::Ref(_, _, hir::Mutability::Not) if i == 0 => { // For references to thread-local statics, we do need // to track the borrow. - if body.local_decls[local].is_ref_to_thread_local() { + if body.local_decls[self.local].is_ref_to_thread_local() { continue; } return true; diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index a09779a766f..b95d1af11ad 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -1,7 +1,7 @@ use crate::borrow_check::ArtificialField; use crate::borrow_check::Overlap; use crate::borrow_check::{AccessDepth, Deep, Shallow}; -use rustc::mir::{Body, BorrowKind, Place, PlaceBase, PlaceElem, PlaceRef, ProjectionElem}; +use rustc::mir::{Body, BorrowKind, Local, Place, PlaceElem, PlaceRef, ProjectionElem}; use rustc::ty::{self, TyCtxt}; use rustc_hir as hir; use std::cmp::max; @@ -119,10 +119,10 @@ fn place_components_conflict<'tcx>( // and either equal or disjoint. // - If we did run out of access, the borrow can access a part of it. - let borrow_base = &borrow_place.base; - let access_base = access_place.base; + let borrow_local = &borrow_place.local; + let access_local = access_place.local; - match place_base_conflict(borrow_base, access_base) { + match place_base_conflict(borrow_local, access_local) { Overlap::Arbitrary => { bug!("Two base can't return Arbitrary"); } @@ -161,7 +161,7 @@ fn place_components_conflict<'tcx>( match place_projection_conflict( tcx, body, - borrow_base, + borrow_local, borrow_proj_base, borrow_c, access_c, @@ -208,7 +208,7 @@ fn place_components_conflict<'tcx>( // access cares about. let proj_base = &borrow_place.projection[..access_place.projection.len() + i]; - let base_ty = Place::ty_from(borrow_base, proj_base, body, tcx).ty; + let base_ty = Place::ty_from(borrow_local, proj_base, body, tcx).ty; match (elem, &base_ty.kind, access) { (_, _, Shallow(Some(ArtificialField::ArrayLength))) @@ -293,19 +293,15 @@ fn place_components_conflict<'tcx>( // Given that the bases of `elem1` and `elem2` are always either equal // or disjoint (and have the same type!), return the overlap situation // between `elem1` and `elem2`. -fn place_base_conflict(elem1: &PlaceBase, elem2: &PlaceBase) -> Overlap { - match (elem1, elem2) { - (PlaceBase::Local(l1), PlaceBase::Local(l2)) => { - if l1 == l2 { - // the same local - base case, equal - debug!("place_element_conflict: DISJOINT-OR-EQ-LOCAL"); - Overlap::EqualOrDisjoint - } else { - // different locals - base case, disjoint - debug!("place_element_conflict: DISJOINT-LOCAL"); - Overlap::Disjoint - } - } +fn place_base_conflict(l1: &Local, l2: &Local) -> Overlap { + if l1 == l2 { + // the same local - base case, equal + debug!("place_element_conflict: DISJOINT-OR-EQ-LOCAL"); + Overlap::EqualOrDisjoint + } else { + // different locals - base case, disjoint + debug!("place_element_conflict: DISJOINT-LOCAL"); + Overlap::Disjoint } } @@ -315,7 +311,7 @@ fn place_base_conflict(elem1: &PlaceBase, elem2: &PlaceBase) -> Overlap { fn place_projection_conflict<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - pi1_base: &PlaceBase, + pi1_local: &Local, pi1_proj_base: &[PlaceElem<'tcx>], pi1_elem: &PlaceElem<'tcx>, pi2_elem: &PlaceElem<'tcx>, @@ -333,7 +329,7 @@ fn place_projection_conflict<'tcx>( debug!("place_element_conflict: DISJOINT-OR-EQ-FIELD"); Overlap::EqualOrDisjoint } else { - let ty = Place::ty_from(pi1_base, pi1_proj_base, body, tcx).ty; + let ty = Place::ty_from(pi1_local, pi1_proj_base, body, tcx).ty; match ty.kind { ty::Adt(def, _) if def.is_union() => { // Different fields of a union, we are basically stuck. diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index c41f2f45012..31bee460fa0 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -9,7 +9,7 @@ use super::MirBorrowckCtxt; -use rustc::mir::{Place, PlaceBase, PlaceRef, ProjectionElem, ReadOnlyBodyAndCache}; +use rustc::mir::{Place, PlaceRef, ProjectionElem, ReadOnlyBodyAndCache}; use rustc::ty::{self, TyCtxt}; use rustc_hir as hir; @@ -19,7 +19,7 @@ pub trait IsPrefixOf<'cx, 'tcx> { impl<'cx, 'tcx> IsPrefixOf<'cx, 'tcx> for PlaceRef<'cx, 'tcx> { fn is_prefix_of(&self, other: PlaceRef<'cx, 'tcx>) -> bool { - self.base == other.base + self.local == other.local && self.projection.len() <= other.projection.len() && self.projection == &other.projection[..self.projection.len()] } @@ -69,22 +69,23 @@ fn next(&mut self) -> Option { 'cursor: loop { match &cursor { - PlaceRef { base: PlaceBase::Local(_), projection: [] } => { + PlaceRef { local: _, projection: [] } => { self.next = None; return Some(cursor); } - PlaceRef { base: _, projection: [proj_base @ .., elem] } => { + PlaceRef { local: _, projection: [proj_base @ .., elem] } => { match elem { ProjectionElem::Field(_ /*field*/, _ /*ty*/) => { // FIXME: add union handling - self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); + self.next = + Some(PlaceRef { local: cursor.local, projection: proj_base }); return Some(cursor); } ProjectionElem::Downcast(..) | ProjectionElem::Subslice { .. } | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Index(_) => { - cursor = PlaceRef { base: cursor.base, projection: proj_base }; + cursor = PlaceRef { local: cursor.local, projection: proj_base }; continue 'cursor; } ProjectionElem::Deref => { @@ -105,7 +106,8 @@ fn next(&mut self) -> Option { PrefixSet::All => { // All prefixes: just blindly enqueue the base // of the projection. - self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); + self.next = + Some(PlaceRef { local: cursor.local, projection: proj_base }); return Some(cursor); } PrefixSet::Supporting => { @@ -118,7 +120,7 @@ fn next(&mut self) -> Option { // derefs, except we stop at the deref of a shared // reference. - let ty = Place::ty_from(cursor.base, proj_base, *self.body, self.tcx).ty; + let ty = Place::ty_from(cursor.local, proj_base, *self.body, self.tcx).ty; match ty.kind { ty::RawPtr(_) | ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Not) => { // don't continue traversing over derefs of raw pointers or shared @@ -128,12 +130,14 @@ fn next(&mut self) -> Option { } ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Mut) => { - self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); + self.next = + Some(PlaceRef { local: cursor.local, projection: proj_base }); return Some(cursor); } ty::Adt(..) if ty.is_box() => { - self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); + self.next = + Some(PlaceRef { local: cursor.local, projection: proj_base }); return Some(cursor); } diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 001f2fc3b22..947bbef4379 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -465,9 +465,7 @@ fn sanitize_place( ) -> PlaceTy<'tcx> { debug!("sanitize_place: {:?}", place); - let mut place_ty = match &place.base { - PlaceBase::Local(index) => PlaceTy::from_ty(self.body.local_decls[*index].ty), - }; + let mut place_ty = PlaceTy::from_ty(self.body.local_decls[place.local].ty); if place.projection.is_empty() { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { @@ -2389,7 +2387,7 @@ fn add_reborrow_constraint( match elem { ProjectionElem::Deref => { let tcx = self.infcx.tcx; - let base_ty = Place::ty_from(&borrowed_place.base, proj_base, body, tcx).ty; + let base_ty = Place::ty_from(&borrowed_place.local, proj_base, body, tcx).ty; debug!("add_reborrow_constraint - base_ty = {:?}", base_ty); match base_ty.kind { diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs index ea530042913..5e4eebb771f 100644 --- a/src/librustc_mir/borrow_check/used_muts.rs +++ b/src/librustc_mir/borrow_check/used_muts.rs @@ -1,5 +1,5 @@ use rustc::mir::visit::{PlaceContext, Visitor}; -use rustc::mir::{Local, Location, Place, PlaceBase, Statement, StatementKind, TerminatorKind}; +use rustc::mir::{Local, Location, Place, Statement, StatementKind, TerminatorKind}; use rustc_data_structures::fx::FxHashSet; @@ -57,11 +57,7 @@ fn remove_never_initialized_mut_locals(&mut self, into: &Place<'_>) { // be those that were never initialized - we will consider those as being used as // they will either have been removed by unreachable code optimizations; or linted // as unused variables. - match into.base { - PlaceBase::Local(local) => { - self.never_initialized_mut_locals.remove(&local); - } - } + self.never_initialized_mut_locals.remove(&into.local); } } @@ -82,13 +78,11 @@ fn visit_terminator_kind(&mut self, kind: &TerminatorKind<'tcx>, _location: Loca fn visit_statement(&mut self, statement: &Statement<'tcx>, _location: Location) { match &statement.kind { StatementKind::Assign(box (into, _)) => { - match into.base { - PlaceBase::Local(local) => debug!( - "visit_statement: statement={:?} local={:?} \ - never_initialized_mut_locals={:?}", - statement, local, self.never_initialized_mut_locals - ), - } + debug!( + "visit_statement: statement={:?} local={:?} \ + never_initialized_mut_locals={:?}", + statement, into.local, self.never_initialized_mut_locals + ); self.remove_never_initialized_mut_locals(into); } _ => {} diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 661111ed948..eb2e87f4a2d 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -20,13 +20,13 @@ /// and `c` can be progressively pushed onto the place builder that is created when converting `a`. #[derive(Clone)] struct PlaceBuilder<'tcx> { - base: PlaceBase, + local: Local, projection: Vec>, } impl PlaceBuilder<'tcx> { fn into_place(self, tcx: TyCtxt<'tcx>) -> Place<'tcx> { - Place { base: self.base, projection: tcx.intern_place_elems(&self.projection) } + Place { local: self.local, projection: tcx.intern_place_elems(&self.projection) } } fn field(self, f: Field, ty: Ty<'tcx>) -> Self { @@ -49,13 +49,7 @@ fn project(mut self, elem: PlaceElem<'tcx>) -> Self { impl From for PlaceBuilder<'tcx> { fn from(local: Local) -> Self { - Self { base: local.into(), projection: Vec::new() } - } -} - -impl From for PlaceBuilder<'tcx> { - fn from(base: PlaceBase) -> Self { - Self { base, projection: Vec::new() } + Self { local, projection: Vec::new() } } } @@ -370,7 +364,7 @@ fn add_fake_borrows_of_base( ) { let tcx = self.hir.tcx(); let place_ty = - Place::ty_from(&base_place.base, &base_place.projection, &self.local_decls, tcx); + Place::ty_from(&base_place.local, &base_place.projection, &self.local_decls, tcx); if let ty::Slice(_) = place_ty.ty.kind { // We need to create fake borrows to ensure that the bounds // check that we just did stays valid. Since we can't assign to @@ -380,7 +374,7 @@ fn add_fake_borrows_of_base( match elem { ProjectionElem::Deref => { let fake_borrow_deref_ty = Place::ty_from( - &base_place.base, + &base_place.local, &base_place.projection[..idx], &self.local_decls, tcx, @@ -398,14 +392,14 @@ fn add_fake_borrows_of_base( Rvalue::Ref( tcx.lifetimes.re_erased, BorrowKind::Shallow, - Place { base: base_place.base.clone(), projection }, + Place { local: base_place.local.clone(), projection }, ), ); fake_borrow_temps.push(fake_borrow_temp); } ProjectionElem::Index(_) => { let index_ty = Place::ty_from( - &base_place.base, + &base_place.local, &base_place.projection[..idx], &self.local_decls, tcx, diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 34b0cbf3b25..6f7b7258b5a 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -393,26 +393,24 @@ fn limit_capture_mutability( let arg_place = unpack!(block = this.as_place(block, arg)); let mutability = match arg_place.as_ref() { - PlaceRef { base: &PlaceBase::Local(local), projection: &[] } => { - this.local_decls[local].mutability - } - PlaceRef { base: &PlaceBase::Local(local), projection: &[ProjectionElem::Deref] } => { + PlaceRef { local, projection: &[] } => this.local_decls[*local].mutability, + PlaceRef { local, projection: &[ProjectionElem::Deref] } => { debug_assert!( - this.local_decls[local].is_ref_for_guard(), + this.local_decls[*local].is_ref_for_guard(), "Unexpected capture place", ); - this.local_decls[local].mutability + this.local_decls[*local].mutability } PlaceRef { - ref base, + ref local, projection: &[ref proj_base @ .., ProjectionElem::Field(upvar_index, _)], } | PlaceRef { - ref base, + ref local, projection: &[ref proj_base @ .., ProjectionElem::Field(upvar_index, _), ProjectionElem::Deref], } => { - let place = PlaceRef { base, projection: proj_base }; + let place = PlaceRef { local, projection: proj_base }; // Not projected from the implicit `self` in a closure. debug_assert!( diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 7eea90befb0..1dcd29d9232 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -890,7 +890,7 @@ fn select_matched_candidates( let proj_base = &source.projection[..i]; fake_borrows.insert(Place { - base: source.base.clone(), + local: source.local.clone(), projection: self.hir.tcx().intern_place_elems(proj_base), }); } @@ -1241,7 +1241,7 @@ fn calculate_fake_borrows<'b>( // Insert a shallow borrow after a deref. For other // projections the borrow of prefix_cursor will // conflict with any mutation of base. - all_fake_borrows.push(PlaceRef { base: &place.base, projection: proj_base }); + all_fake_borrows.push(PlaceRef { local: &place.local, projection: proj_base }); } } @@ -1258,7 +1258,7 @@ fn calculate_fake_borrows<'b>( .into_iter() .map(|matched_place_ref| { let matched_place = Place { - base: matched_place_ref.base.clone(), + local: matched_place_ref.local.clone(), projection: tcx.intern_place_elems(matched_place_ref.projection), }; let fake_borrow_deref_ty = matched_place.ty(&self.local_decls, tcx).ty; diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index d6d22db9ff2..d4813d8ab68 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -834,7 +834,7 @@ fn args_and_body( span: tcx_hir.span(var_id), }, place: Place { - base: closure_env_arg.into(), + local: closure_env_arg.into(), projection: tcx.intern_place_elems(&projs), }, }); diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index 65976908f59..63834d0ecda 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -86,10 +86,7 @@ struct BorrowedLocalsVisitor<'gk> { } fn find_local(place: &Place<'_>) -> Option { - match place.base { - PlaceBase::Local(local) if !place.is_indirect() => Some(local), - _ => None, - } + if !place.is_indirect() { Some(place.local) } else { None } } impl<'tcx> Visitor<'tcx> for BorrowedLocalsVisitor<'_> { diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index d6ada916227..f94ee67f2be 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -1,4 +1,4 @@ -use rustc::mir::{self, Body, Location, Place, PlaceBase}; +use rustc::mir::{self, Body, Location, Place}; use rustc::ty::RegionVid; use rustc::ty::TyCtxt; @@ -195,38 +195,34 @@ fn kill_loans_out_of_scope_at_location( fn kill_borrows_on_place(&self, trans: &mut GenKillSet, place: &Place<'tcx>) { debug!("kill_borrows_on_place: place={:?}", place); - match place.base { - PlaceBase::Local(local) => { - let other_borrows_of_local = - self.borrow_set.local_map.get(&local).into_iter().flat_map(|bs| bs.into_iter()); - - // If the borrowed place is a local with no projections, all other borrows of this - // local must conflict. This is purely an optimization so we don't have to call - // `places_conflict` for every borrow. - if place.projection.is_empty() { - if !self.body.local_decls[local].is_ref_to_static() { - trans.kill_all(other_borrows_of_local); - } - return; - } - - // By passing `PlaceConflictBias::NoOverlap`, we conservatively assume that any given - // pair of array indices are unequal, so that when `places_conflict` returns true, we - // will be assured that two places being compared definitely denotes the same sets of - // locations. - let definitely_conflicting_borrows = other_borrows_of_local.filter(|&&i| { - places_conflict( - self.tcx, - self.body, - &self.borrow_set.borrows[i].borrowed_place, - place, - PlaceConflictBias::NoOverlap, - ) - }); + let other_borrows_of_local = + self.borrow_set.local_map.get(&place.local).into_iter().flat_map(|bs| bs.into_iter()); - trans.kill_all(definitely_conflicting_borrows); + // If the borrowed place is a local with no projections, all other borrows of this + // local must conflict. This is purely an optimization so we don't have to call + // `places_conflict` for every borrow. + if place.projection.is_empty() { + if !self.body.local_decls[place.local].is_ref_to_static() { + trans.kill_all(other_borrows_of_local); } + return; } + + // By passing `PlaceConflictBias::NoOverlap`, we conservatively assume that any given + // pair of array indices are unequal, so that when `places_conflict` returns true, we + // will be assured that two places being compared definitely denotes the same sets of + // locations. + let definitely_conflicting_borrows = other_borrows_of_local.filter(|&&i| { + places_conflict( + self.tcx, + self.body, + &self.borrow_set.borrows[i].borrowed_place, + place, + PlaceConflictBias::NoOverlap, + ) + }); + + trans.kill_all(definitely_conflicting_borrows); } } diff --git a/src/librustc_mir/dataflow/impls/indirect_mutation.rs b/src/librustc_mir/dataflow/impls/indirect_mutation.rs index 38401b42b48..85bf342c8a3 100644 --- a/src/librustc_mir/dataflow/impls/indirect_mutation.rs +++ b/src/librustc_mir/dataflow/impls/indirect_mutation.rs @@ -111,12 +111,8 @@ impl<'tcx> Visitor<'tcx> for TransferFunction<'_, '_, 'tcx> { fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) { if let mir::Rvalue::Ref(_, kind, ref borrowed_place) = *rvalue { if self.borrow_allows_mutation(kind, borrowed_place) { - match borrowed_place.base { - mir::PlaceBase::Local(borrowed_local) if !borrowed_place.is_indirect() => { - self.trans.gen(borrowed_local) - } - - _ => (), + if !borrowed_place.is_indirect() { + self.trans.gen(borrowed_place.local); } } } diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index e4d5d6adfc1..6a48d1e9803 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -115,14 +115,12 @@ fn before_statement_effect(&self, sets: &mut GenKillSet, loc: Locatio match stmt.kind { StatementKind::StorageDead(l) => sets.kill(l), StatementKind::Assign(box (ref place, _)) - | StatementKind::SetDiscriminant { box ref place, .. } => match place.base { - PlaceBase::Local(local) => sets.gen(local), - }, + | StatementKind::SetDiscriminant { box ref place, .. } => { + sets.gen(place.local); + } StatementKind::InlineAsm(box InlineAsm { ref outputs, .. }) => { - for p in &**outputs { - match p.base { - PlaceBase::Local(local) => sets.gen(local), - } + for place in &**outputs { + sets.gen(place.local); } } _ => (), @@ -138,10 +136,8 @@ fn statement_effect(&self, sets: &mut GenKillSet, loc: Location) { fn before_terminator_effect(&self, sets: &mut GenKillSet, loc: Location) { self.check_for_borrow(sets, loc); - if let TerminatorKind::Call { - destination: Some((Place { base: PlaceBase::Local(local), .. }, _)), - .. - } = self.body[loc.block].terminator().kind + if let TerminatorKind::Call { destination: Some((Place { local, .. }, _)), .. } = + self.body[loc.block].terminator().kind { sets.gen(local); } @@ -169,11 +165,7 @@ fn propagate_call_return( _dest_bb: mir::BasicBlock, dest_place: &mir::Place<'tcx>, ) { - match dest_place.base { - PlaceBase::Local(local) => { - in_out.insert(local); - } - } + in_out.insert(dest_place.local); } } diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index b0be49689f9..271bcce6ca5 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -96,9 +96,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { /// Maybe we should have separate "borrowck" and "moveck" modes. fn move_path_for(&mut self, place: &Place<'tcx>) -> Result> { debug!("lookup({:?})", place); - let mut base = match place.base { - PlaceBase::Local(local) => self.builder.data.rev_lookup.locals[local], - }; + let mut base = self.builder.data.rev_lookup.locals[place.local]; // The move path index of the first union that we find. Once this is // some we stop creating child move paths, since moves from unions @@ -111,7 +109,7 @@ fn move_path_for(&mut self, place: &Place<'tcx>) -> Result { let proj = &place.projection[..i + 1]; @@ -119,7 +117,7 @@ fn move_path_for(&mut self, place: &Place<'tcx>) -> Result) -> Result) { // `ConstIndex` patterns. This is done to ensure that all move paths // are disjoint, which is expected by drop elaboration. let base_place = Place { - base: place.base.clone(), + local: place.local.clone(), projection: self.builder.tcx.intern_place_elems(base), }; let base_path = match self.move_path_for(&base_place) { @@ -494,10 +492,10 @@ fn gather_init(&mut self, place: PlaceRef<'cx, 'tcx>, kind: InitKind) { // of the union so it is marked as initialized again. if let [proj_base @ .., ProjectionElem::Field(_, _)] = place.projection { if let ty::Adt(def, _) = - Place::ty_from(place.base, proj_base, self.builder.body, self.builder.tcx).ty.kind + Place::ty_from(place.local, proj_base, self.builder.body, self.builder.tcx).ty.kind { if def.is_union() { - place = PlaceRef { base: place.base, projection: proj_base } + place = PlaceRef { local: place.local, projection: proj_base } } } } diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 7133c46d6c7..a46465ab493 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -246,9 +246,7 @@ impl MovePathLookup { // unknown place, but will rather return the nearest available // parent. pub fn find(&self, place: PlaceRef<'_, '_>) -> LookupResult { - let mut result = match place.base { - PlaceBase::Local(local) => self.locals[*local], - }; + let mut result = self.locals[*place.local]; for elem in place.projection.iter() { if let Some(&subpath) = self.projections.get(&(result, elem.lift())) { diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 30725d781dc..6df3e6fc596 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -462,17 +462,15 @@ pub fn eval_place_to_op( place: &mir::Place<'tcx>, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { - use rustc::mir::PlaceBase; - - let base_op = match &place.base { - PlaceBase::Local(mir::RETURN_PLACE) => throw_unsup!(ReadFromReturnPointer), - PlaceBase::Local(local) => { + let base_op = match place.local { + mir::RETURN_PLACE => throw_unsup!(ReadFromReturnPointer), + local => { // Do not use the layout passed in as argument if the base we are looking at // here is not the entire place. // FIXME use place_projection.is_empty() when is available let layout = if place.projection.is_empty() { layout } else { None }; - self.access_local(self.frame(), *local, layout)? + self.access_local(self.frame(), local, layout)? } }; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index bd3059951e8..8888e3fd463 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -624,10 +624,8 @@ pub fn eval_place( &mut self, place: &mir::Place<'tcx>, ) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> { - use rustc::mir::PlaceBase; - - let mut place_ty = match &place.base { - PlaceBase::Local(mir::RETURN_PLACE) => { + let mut place_ty = match place.local { + mir::RETURN_PLACE => { // `return_place` has the *caller* layout, but we want to use our // `layout to verify our assumption. The caller will validate // their layout on return. @@ -648,10 +646,10 @@ pub fn eval_place( ))?, } } - PlaceBase::Local(local) => PlaceTy { + local => PlaceTy { // This works even for dead/uninitialized locals; we check further when writing - place: Place::Local { frame: self.cur_frame(), local: *local }, - layout: self.layout_of_local(self.frame(), *local, None)?, + place: Place::Local { frame: self.cur_frame(), local: local }, + layout: self.layout_of_local(self.frame(), local, None)?, }, }; diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 5da5695a4d4..5ccdb4be624 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -182,7 +182,7 @@ use rustc::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar}; use rustc::mir::mono::{InstantiationMode, MonoItem}; use rustc::mir::visit::Visitor as MirVisitor; -use rustc::mir::{self, Location, PlaceBase}; +use rustc::mir::{self, Local, Location}; use rustc::session::config::EntryFnType; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::ty::print::obsolete::DefPathBasedNames; @@ -642,15 +642,10 @@ fn visit_terminator_kind(&mut self, kind: &mir::TerminatorKind<'tcx>, location: fn visit_place_base( &mut self, - place_base: &mir::PlaceBase, + _place_local: &Local, _context: mir::visit::PlaceContext, _location: Location, ) { - match place_base { - PlaceBase::Local(_) => { - // Locals have no relevance for collector. - } - } } } diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 8c52a4e7a29..577736f9bd1 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -38,12 +38,15 @@ fn in_projection_structurally( place: PlaceRef<'_, 'tcx>, ) -> bool { if let [proj_base @ .., elem] = place.projection { - let base_qualif = - Self::in_place(cx, per_local, PlaceRef { base: place.base, projection: proj_base }); + let base_qualif = Self::in_place( + cx, + per_local, + PlaceRef { local: place.local, projection: proj_base }, + ); let qualif = base_qualif && Self::in_any_value_of_ty( cx, - Place::ty_from(place.base, proj_base, *cx.body, cx.tcx) + Place::ty_from(place.local, proj_base, *cx.body, cx.tcx) .projection_ty(cx.tcx, elem) .ty, ); @@ -75,8 +78,8 @@ fn in_place( place: PlaceRef<'_, 'tcx>, ) -> bool { match place { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => per_local(*local), - PlaceRef { base: _, projection: [.., _] } => Self::in_projection(cx, per_local, place), + PlaceRef { local, projection: [] } => per_local(*local), + PlaceRef { local: _, projection: [.., _] } => Self::in_projection(cx, per_local, place), } } @@ -146,12 +149,12 @@ fn in_rvalue_structurally( Rvalue::Ref(_, _, ref place) | Rvalue::AddressOf(_, ref place) => { // Special-case reborrows to be more like a copy of the reference. if let [proj_base @ .., ProjectionElem::Deref] = place.projection.as_ref() { - let base_ty = Place::ty_from(&place.base, proj_base, *cx.body, cx.tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, *cx.body, cx.tcx).ty; if let ty::Ref(..) = base_ty.kind { return Self::in_place( cx, per_local, - PlaceRef { base: &place.base, projection: proj_base }, + PlaceRef { local: &place.local, projection: proj_base }, ); } } diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs index 207683054f9..c445568dd2a 100644 --- a/src/librustc_mir/transform/check_consts/resolver.rs +++ b/src/librustc_mir/transform/check_consts/resolver.rs @@ -47,15 +47,15 @@ fn assign_qualif_direct(&mut self, place: &mir::Place<'tcx>, value: bool) { debug_assert!(!place.is_indirect()); match (value, place.as_ref()) { - (true, mir::PlaceRef { base: &mir::PlaceBase::Local(local), .. }) => { - self.qualifs_per_local.insert(local); + (true, mir::PlaceRef { local, .. }) => { + self.qualifs_per_local.insert(*local); } // For now, we do not clear the qualif if a local is overwritten in full by // an unqualified rvalue (e.g. `y = 5`). This is to be consistent // with aggregates where we overwrite all fields with assignments, which would not // get this feature. - (false, mir::PlaceRef { base: &mir::PlaceBase::Local(_local), projection: &[] }) => { + (false, mir::PlaceRef { local: _, projection: &[] }) => { // self.qualifs_per_local.remove(*local); } diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index c864abdae66..10a4b7d92b7 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -304,8 +304,8 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { PlaceContext::MutatingUse(MutatingUseContext::Borrow) } }; - self.visit_place_base(&place.base, ctx, location); - self.visit_projection(&place.base, reborrowed_proj, ctx, location); + self.visit_place_base(&place.local, ctx, location); + self.visit_projection(&place.local, reborrowed_proj, ctx, location); return; } } @@ -317,8 +317,8 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { } Mutability::Mut => PlaceContext::MutatingUse(MutatingUseContext::AddressOf), }; - self.visit_place_base(&place.base, ctx, location); - self.visit_projection(&place.base, reborrowed_proj, ctx, location); + self.visit_place_base(&place.local, ctx, location); + self.visit_projection(&place.local, reborrowed_proj, ctx, location); return; } } @@ -412,23 +412,14 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { } } - fn visit_place_base( - &mut self, - place_base: &PlaceBase, - context: PlaceContext, - location: Location, - ) { + fn visit_place_base(&mut self, place_local: &Local, context: PlaceContext, location: Location) { trace!( - "visit_place_base: place_base={:?} context={:?} location={:?}", - place_base, + "visit_place_base: place_local={:?} context={:?} location={:?}", + place_local, context, location, ); - self.super_place_base(place_base, context, location); - - match place_base { - PlaceBase::Local(_) => {} - } + self.super_place_base(place_local, context, location); } fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) { @@ -441,30 +432,30 @@ fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) { } fn visit_projection_elem( &mut self, - place_base: &PlaceBase, + place_local: &Local, proj_base: &[PlaceElem<'tcx>], elem: &PlaceElem<'tcx>, context: PlaceContext, location: Location, ) { trace!( - "visit_projection_elem: place_base={:?} proj_base={:?} elem={:?} \ + "visit_projection_elem: place_local={:?} proj_base={:?} elem={:?} \ context={:?} location={:?}", - place_base, + place_local, proj_base, elem, context, location, ); - self.super_projection_elem(place_base, proj_base, elem, context, location); + self.super_projection_elem(place_local, proj_base, elem, context, location); match elem { ProjectionElem::Deref => { - let base_ty = Place::ty_from(place_base, proj_base, *self.body, self.tcx).ty; + let base_ty = Place::ty_from(place_local, proj_base, *self.body, self.tcx).ty; if let ty::RawPtr(_) = base_ty.kind { if proj_base.is_empty() { - if let (PlaceBase::Local(local), []) = (place_base, proj_base) { + if let (local, []) = (place_local, proj_base) { let decl = &self.body.local_decls[*local]; if let LocalInfo::StaticRef { def_id, .. } = decl.local_info { let span = decl.source_info.span; @@ -485,7 +476,7 @@ fn visit_projection_elem( | ProjectionElem::Subslice { .. } | ProjectionElem::Field(..) | ProjectionElem::Index(_) => { - let base_ty = Place::ty_from(place_base, proj_base, *self.body, self.tcx).ty; + let base_ty = Place::ty_from(place_local, proj_base, *self.body, self.tcx).ty; match base_ty.ty_adt_def() { Some(def) if def.is_union() => { self.check_op(ops::UnionAccess); @@ -669,19 +660,15 @@ fn place_as_reborrow( // A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const` // that points to the allocation for the static. Don't treat these as reborrows. - match place.base { - PlaceBase::Local(local) => { - if body.local_decls[local].is_ref_to_static() { - return None; - } - } + if body.local_decls[place.local].is_ref_to_static() { + return None; } // Ensure the type being derefed is a reference and not a raw pointer. // // This is sufficient to prevent an access to a `static mut` from being marked as a // reborrow, even if the check above were to disappear. - let inner_ty = Place::ty_from(&place.base, inner, body, tcx).ty; + let inner_ty = Place::ty_from(&place.local, inner, body, tcx).ty; match inner_ty.kind { ty::Ref(..) => Some(inner), _ => None, diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 017d0f34674..934b262c2f9 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -190,12 +190,6 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { } fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { - match place.base { - PlaceBase::Local(..) => { - // Locals are safe. - } - } - for (i, elem) in place.projection.iter().enumerate() { let proj_base = &place.projection[..i]; @@ -223,7 +217,7 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: } } let is_borrow_of_interior_mut = context.is_borrow() - && !Place::ty_from(&place.base, proj_base, self.body, self.tcx).ty.is_freeze( + && !Place::ty_from(&place.local, proj_base, self.body, self.tcx).ty.is_freeze( self.tcx, self.param_env, self.source_info.span, @@ -238,7 +232,7 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: self.check_mut_borrowing_layout_constrained_field(place, context.is_mutating_use()); } let old_source_info = self.source_info; - if let (PlaceBase::Local(local), []) = (&place.base, proj_base) { + if let (local, []) = (&place.local, proj_base) { let decl = &self.body.local_decls[*local]; if decl.internal { // Internal locals are used in the `move_val_init` desugaring. @@ -266,7 +260,7 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: } } } - let base_ty = Place::ty_from(&place.base, proj_base, self.body, self.tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, self.body, self.tcx).ty; match base_ty.kind { ty::RawPtr(..) => self.require_unsafe( "dereference of raw pointer", @@ -420,7 +414,8 @@ fn check_mut_borrowing_layout_constrained_field( match elem { ProjectionElem::Field(..) => { let ty = - Place::ty_from(&place.base, proj_base, &self.body.local_decls, self.tcx).ty; + Place::ty_from(&place.local, proj_base, &self.body.local_decls, self.tcx) + .ty; match ty.kind { ty::Adt(def, _) => match self.tcx.layout_scalar_valid_range(def.did) { (Bound::Unbounded, Bound::Unbounded) => {} diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index f9b24b00e87..79506f3f22a 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -10,7 +10,7 @@ }; use rustc::mir::{ read_only, AggregateKind, BasicBlock, BinOp, Body, BodyAndCache, ClearCrossCrate, Constant, - Local, LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, ReadOnlyBodyAndCache, Rvalue, + Local, LocalDecl, LocalKind, Location, Operand, Place, ReadOnlyBodyAndCache, Rvalue, SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind, UnOp, RETURN_PLACE, }; @@ -872,9 +872,7 @@ fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Loca // doesn't use the invalid value match cond { Operand::Move(ref place) | Operand::Copy(ref place) => { - match place.base { - PlaceBase::Local(local) => self.remove_const(local), - } + self.remove_const(place.local); } Operand::Constant(_) => {} } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index b075a399516..825ac4a28d8 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -112,17 +112,17 @@ fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { } fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - if place.base == PlaceBase::Local(self_arg()) { + if place.local == self_arg() { replace_base( place, Place { - base: PlaceBase::Local(self_arg()), + local: self_arg(), projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Deref]), }, self.tcx, ); } else { - self.visit_place_base(&mut place.base, context, location); + self.visit_place_base(&mut place.local, context, location); for elem in place.projection.iter() { if let PlaceElem::Index(local) = elem { @@ -148,11 +148,11 @@ fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { } fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - if place.base == PlaceBase::Local(self_arg()) { + if place.local == self_arg() { replace_base( place, Place { - base: PlaceBase::Local(self_arg()), + local: self_arg(), projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Field( Field::new(0), self.ref_gen_ty, @@ -161,7 +161,7 @@ fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, locati self.tcx, ); } else { - self.visit_place_base(&mut place.base, context, location); + self.visit_place_base(&mut place.local, context, location); for elem in place.projection.iter() { if let PlaceElem::Index(local) = elem { @@ -173,7 +173,7 @@ fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, locati } fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtxt<'tcx>) { - place.base = new_base.base; + place.local = new_base.local; let mut new_projection = new_base.projection.to_vec(); new_projection.append(&mut place.projection.to_vec()); @@ -236,7 +236,7 @@ fn make_field(&self, variant_index: VariantIdx, idx: usize, ty: Ty<'tcx>) -> Pla let mut projection = base.projection.to_vec(); projection.push(ProjectionElem::Field(Field::new(idx), ty)); - Place { base: base.base, projection: self.tcx.intern_place_elems(&projection) } + Place { local: base.local, projection: self.tcx.intern_place_elems(&projection) } } // Create a statement which changes the discriminant @@ -281,14 +281,9 @@ fn visit_place( _context: PlaceContext, _location: Location, ) { - match place.base { - PlaceBase::Local(l) => - // Replace an Local in the remap with a generator struct access - { - if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) { - replace_base(place, self.make_field(variant_index, idx, ty), self.tcx); - } - } + // Replace an Local in the remap with a generator struct access + if let Some(&(ty, variant_index, idx)) = self.remap.get(&place.local) { + replace_base(place, self.make_field(variant_index, idx, ty), self.tcx); } } diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 52992f7d7a8..2dd00fe2fee 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -430,9 +430,7 @@ fn dest_needs_borrow(place: &Place<'_>) -> bool { } } - match place.base { - _ => false, - } + false } let dest = if dest_needs_borrow(&destination.0) { @@ -644,9 +642,7 @@ fn update_target(&self, tgt: BasicBlock) -> BasicBlock { fn make_integrate_local(&self, local: &Local) -> Local { if *local == RETURN_PLACE { - match self.destination.base { - PlaceBase::Local(l) => return l, - } + return self.destination.local; } let idx = local.index() - 1; @@ -668,18 +664,14 @@ fn visit_local(&mut self, local: &mut Local, _ctxt: PlaceContext, _location: Loc } fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - match &mut place.base { - PlaceBase::Local(l) => { - // If this is the `RETURN_PLACE`, we need to rebase any projections onto it. - let dest_proj_len = self.destination.projection.len(); - if *l == RETURN_PLACE && dest_proj_len > 0 { - let mut projs = Vec::with_capacity(dest_proj_len + place.projection.len()); - projs.extend(self.destination.projection); - projs.extend(place.projection); - - place.projection = self.tcx.intern_place_elems(&*projs); - } - } + // If this is the `RETURN_PLACE`, we need to rebase any projections onto it. + let dest_proj_len = self.destination.projection.len(); + if place.local == RETURN_PLACE && dest_proj_len > 0 { + let mut projs = Vec::with_capacity(dest_proj_len + place.projection.len()); + projs.extend(self.destination.projection); + projs.extend(place.projection); + + place.projection = self.tcx.intern_place_elems(&*projs); } // Handles integrating any locals that occur in the base // or projections diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index a2f3fcea756..69eedb1ae18 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -3,7 +3,7 @@ use crate::transform::{MirPass, MirSource}; use rustc::mir::visit::{MutVisitor, Visitor}; use rustc::mir::{ - read_only, Body, BodyAndCache, Constant, Local, Location, Operand, Place, PlaceBase, PlaceRef, + read_only, Body, BodyAndCache, Constant, Local, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, }; use rustc::ty::{self, TyCtxt}; @@ -55,7 +55,7 @@ fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) { Place { // Replace with dummy - base: mem::replace(&mut place.base, PlaceBase::Local(Local::new(0))), + local: mem::replace(&mut place.local, Local::new(0)), projection: self.tcx().intern_place_elems(proj_l), } } else { @@ -92,10 +92,10 @@ fn new(body: &'b Body<'tcx>, tcx: TyCtxt<'tcx>) -> OptimizationFinder<'b, 'tcx> impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> { fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { if let Rvalue::Ref(_, _, place) = rvalue { - if let PlaceRef { base, projection: &[ref proj_base @ .., ProjectionElem::Deref] } = + if let PlaceRef { local, projection: &[ref proj_base @ .., ProjectionElem::Deref] } = place.as_ref() { - if Place::ty_from(base, proj_base, self.body, self.tcx).ty.is_region_ptr() { + if Place::ty_from(local, proj_base, self.body, self.tcx).ty.is_region_ptr() { self.optimizations.and_stars.insert(location); } } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 494b61c5d1e..90393ec6c8c 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -308,17 +308,14 @@ fn validate_candidate(&self, candidate: Candidate) -> Result<(), Unpromotable> { // We can only promote interior borrows of promotable temps (non-temps // don't get promoted anyway). - let base = match place.base { - PlaceBase::Local(local) => local, - }; - self.validate_local(base)?; + self.validate_local(place.local)?; if place.projection.contains(&ProjectionElem::Deref) { return Err(Unpromotable); } let mut has_mut_interior = - self.qualif_local::(base); + self.qualif_local::(place.local); // HACK(eddyb) this should compute the same thing as // `::in_projection` from // `check_consts::qualifs` but without recursion. @@ -332,7 +329,7 @@ fn validate_candidate(&self, candidate: Candidate) -> Result<(), Unpromotable> { // FIXME(eddyb) this is probably excessive, with // the exception of `union` member accesses. let ty = - Place::ty_from(&place.base, proj_base, *self.body, self.tcx) + Place::ty_from(&place.local, proj_base, *self.body, self.tcx) .projection_ty(self.tcx, elem) .ty; if ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) { @@ -348,7 +345,7 @@ fn validate_candidate(&self, candidate: Candidate) -> Result<(), Unpromotable> { if has_mut_interior { return Err(Unpromotable); } - if self.qualif_local::(base) { + if self.qualif_local::(place.local) { return Err(Unpromotable); } @@ -478,10 +475,8 @@ fn validate_local(&self, local: Local) -> Result<(), Unpromotable> { fn validate_place(&self, place: PlaceRef<'_, 'tcx>) -> Result<(), Unpromotable> { match place { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => { - self.validate_local(*local) - } - PlaceRef { base: _, projection: [proj_base @ .., elem] } => { + PlaceRef { local, projection: [] } => self.validate_local(*local), + PlaceRef { local: _, projection: [proj_base @ .., elem] } => { match *elem { ProjectionElem::Deref | ProjectionElem::Downcast(..) => { return Err(Unpromotable); @@ -496,7 +491,7 @@ fn validate_place(&self, place: PlaceRef<'_, 'tcx>) -> Result<(), Unpromotable> ProjectionElem::Field(..) => { if self.const_kind.is_none() { let base_ty = - Place::ty_from(place.base, proj_base, *self.body, self.tcx).ty; + Place::ty_from(place.local, proj_base, *self.body, self.tcx).ty; if let Some(def) = base_ty.ty_adt_def() { // No promotion of union field accesses. if def.is_union() { @@ -507,7 +502,7 @@ fn validate_place(&self, place: PlaceRef<'_, 'tcx>) -> Result<(), Unpromotable> } } - self.validate_place(PlaceRef { base: place.base, projection: proj_base }) + self.validate_place(PlaceRef { local: place.local, projection: proj_base }) } } } @@ -594,10 +589,12 @@ fn validate_rvalue(&self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> { // Raw reborrows can come from reference to pointer coercions, // so are allowed. if let [proj_base @ .., ProjectionElem::Deref] = place.projection.as_ref() { - let base_ty = Place::ty_from(&place.base, proj_base, *self.body, self.tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, *self.body, self.tcx).ty; if let ty::Ref(..) = base_ty.kind { - return self - .validate_place(PlaceRef { base: &place.base, projection: proj_base }); + return self.validate_place(PlaceRef { + local: &place.local, + projection: proj_base, + }); } } Err(Unpromotable) @@ -631,9 +628,9 @@ fn validate_rvalue(&self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> { // Special-case reborrows to be more like a copy of the reference. let mut place = place.as_ref(); if let [proj_base @ .., ProjectionElem::Deref] = &place.projection { - let base_ty = Place::ty_from(&place.base, proj_base, *self.body, self.tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, *self.body, self.tcx).ty; if let ty::Ref(..) = base_ty.kind { - place = PlaceRef { base: &place.base, projection: proj_base }; + place = PlaceRef { local: &place.local, projection: proj_base }; } } @@ -642,16 +639,15 @@ fn validate_rvalue(&self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> { // HACK(eddyb) this should compute the same thing as // `::in_projection` from // `check_consts::qualifs` but without recursion. - let mut has_mut_interior = match place.base { - PlaceBase::Local(local) => self.qualif_local::(*local), - }; + let mut has_mut_interior = + self.qualif_local::(*place.local); if has_mut_interior { let mut place_projection = place.projection; // FIXME(eddyb) use a forward loop instead of a reverse one. while let [proj_base @ .., elem] = place_projection { // FIXME(eddyb) this is probably excessive, with // the exception of `union` member accesses. - let ty = Place::ty_from(place.base, proj_base, *self.body, self.tcx) + let ty = Place::ty_from(place.local, proj_base, *self.body, self.tcx) .projection_ty(self.tcx, elem) .ty; if ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) { @@ -930,7 +926,7 @@ fn promote_candidate( Rvalue::Ref(ref mut region, borrow_kind, ref mut place), )) => { // Use the underlying local for this (necessarily interior) borrow. - let ty = place.base.ty(local_decls).ty; + let ty = local_decls.local_decls()[place.local].ty; let span = statement.source_info.span; let ref_ty = tcx.mk_ref( @@ -965,10 +961,7 @@ fn promote_candidate( tcx.lifetimes.re_static, borrow_kind, Place { - base: mem::replace( - &mut place.base, - PlaceBase::Local(promoted_ref), - ), + local: mem::replace(&mut place.local, promoted_ref), projection: List::empty(), }, ) diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index fcdabb29cd0..ab96ae3b6d6 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -261,7 +261,7 @@ fn check_place( ProjectionElem::Downcast(_symbol, _variant_index) => {} ProjectionElem::Field(..) => { - let base_ty = Place::ty_from(&place.base, &proj_base, body, tcx).ty; + let base_ty = Place::ty_from(&place.local, &proj_base, body, tcx).ty; if let Some(def) = base_ty.ty_adt_def() { // No union field accesses in `const fn` if def.is_union() { diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index e96baefc822..ddf8d73e548 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -388,9 +388,7 @@ fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockDat // Remove unnecessary StorageLive and StorageDead annotations. data.statements.retain(|stmt| match &stmt.kind { StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => self.map[*l].is_some(), - StatementKind::Assign(box (place, _)) => match place.base { - PlaceBase::Local(local) => self.map[local].is_some(), - }, + StatementKind::Assign(box (place, _)) => self.map[place.local].is_some(), _ => true, }); self.super_basic_block_data(block, data); diff --git a/src/librustc_mir/transform/simplify_try.rs b/src/librustc_mir/transform/simplify_try.rs index 3b8871f86b2..e733b0a5b59 100644 --- a/src/librustc_mir/transform/simplify_try.rs +++ b/src/librustc_mir/transform/simplify_try.rs @@ -137,9 +137,9 @@ struct VarField<'tcx> { fn match_variant_field_place<'tcx>(place: &Place<'tcx>) -> Option<(Local, VarField<'tcx>)> { match place.as_ref() { PlaceRef { - base: &PlaceBase::Local(local), + local, projection: &[ProjectionElem::Downcast(_, var_idx), ProjectionElem::Field(field, ty)], - } => Some((local, VarField { field, field_ty: ty, var_idx })), + } => Some((*local, VarField { field, field_ty: ty, var_idx })), _ => None, } } diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs index 70d6aaf70eb..e17c7a80f1a 100644 --- a/src/librustc_mir/util/alignment.rs +++ b/src/librustc_mir/util/alignment.rs @@ -46,7 +46,7 @@ fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: &Place<' // encountered a Deref, which is ABI-aligned ProjectionElem::Deref => break, ProjectionElem::Field(..) => { - let ty = Place::ty_from(&place.base, proj_base, local_decls, tcx).ty; + let ty = Place::ty_from(&place.local, proj_base, local_decls, tcx).ty; match ty.kind { ty::Adt(def, _) if def.repr.packed() => return true, _ => {}