diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index d4609142928ba..a74ca7a98ed36 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2110,30 +2110,6 @@ impl<'tcx> Place<'tcx> { pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> { Place::Projection(Box::new(PlaceProjection { base: self, elem })) } - - /// Find the innermost `Local` from this `Place`, *if* it is either a local itself or - /// a single deref of a local. - /// - /// FIXME: can we safely swap the semantics of `fn base_local` below in here instead? - pub fn local(&self) -> Option { - match self { - Place::Local(local) | - Place::Projection(box Projection { - base: Place::Local(local), - elem: ProjectionElem::Deref, - }) => Some(*local), - _ => None, - } - } - - /// Find the innermost `Local` from this `Place`. - pub fn base_local(&self) -> Option { - match self { - Place::Local(local) => Some(*local), - Place::Projection(box Projection { base, elem: _ }) => base.base_local(), - Place::Promoted(..) | Place::Static(..) => None, - } - } } impl<'tcx> NeoPlace<'tcx> { @@ -2184,6 +2160,15 @@ impl<'tcx> NeoPlace<'tcx> { self.elem(tcx, ProjectionElem::Index(index)) } + /// Find the innermost `Local` from this `Place`. + pub fn base_local(&self) -> Option { + if let PlaceBase::Local(local) = self.base { + Some(local) + } else { + None + } + } + pub fn constant_index( self, tcx: TyCtxt<'_, '_, 'tcx>, diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 4efe0ecc7dbd5..2c59889e5f9b0 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -579,7 +579,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // is a union. let is_union = |place: &Place<'tcx>| -> bool { let neo_place = self.infcx.tcx.as_new_place(place); - neo_place.ty(self.mir, self.infcx.tcx) + neo_place + .ty(self.mir, self.infcx.tcx) .to_ty(self.infcx.tcx) .ty_adt_def() .map(|adt| adt.is_union()) @@ -1481,15 +1482,22 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { diag: &mut DiagnosticBuilder<'_>, ) { debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); - let mut target = place.local(); + let neo_place = self.infcx.tcx.as_new_place(place); + let mut target = neo_place.base_local(); for stmt in &self.mir[location.block].statements[location.statement_index..] { debug!("add_moved_or_invoked_closure_note: stmt={:?} target={:?}", stmt, target); if let StatementKind::Assign(into, box Rvalue::Use(from)) = &stmt.kind { debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from); match from { - Operand::Copy(ref place) | - Operand::Move(ref place) if target == place.local() => - target = into.local(), + Operand::Copy(ref place) | Operand::Move(ref place) + if { + let neo_place = self.infcx.tcx.as_new_place(place); + target == neo_place.base_local() + } => + { + let neo_into = self.infcx.tcx.as_new_place(into); + target = neo_into.base_local(); + } _ => {}, } } @@ -1512,9 +1520,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { debug!("add_moved_or_invoked_closure_note: id={:?}", id); if self.infcx.tcx.parent(id) == self.infcx.tcx.lang_items().fn_once_trait() { let closure = match args.first() { - Some(Operand::Copy(ref place)) | - Some(Operand::Move(ref place)) if target == place.local() => - place.local().unwrap(), + Some(Operand::Copy(ref place)) | Some(Operand::Move(ref place)) + if { + let neo_place = self.infcx.tcx.as_new_place(place); + target == neo_place.base_local() + } => + { + neo_place.base_local().unwrap() + } _ => return, }; @@ -1949,7 +1962,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); // Find the local from the operand. - let assigned_from_local = match assigned_from.local() { + let neo_assigned_from = self.infcx.tcx.as_new_place(assigned_from); + let assigned_from_local = match neo_assigned_from.base_local() { Some(local) => local, None => continue, }; @@ -2005,7 +2019,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); // Find the local from the rvalue. - let assigned_from_local = match assigned_from.local() { + let neo_assigned_from = self.infcx.tcx.as_new_place(assigned_from); + let assigned_from_local = match neo_assigned_from.base_local() { Some(local) => local, None => continue, }; @@ -2068,7 +2083,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { assigned_from, ); - if let Some(assigned_from_local) = assigned_from.local() { + let neo_assigned_from = self.infcx.tcx.as_new_place(assigned_from); + if let Some(assigned_from_local) = neo_assigned_from.base_local() { debug!( "annotate_argument_and_return_for_borrow: assigned_from_local={:?}", assigned_from_local, diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 433cb1dc0d5e9..f2a1fe45c77c1 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1680,7 +1680,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ty::Adt(..) | ty::Tuple(..) => { check_parent_of_field(self, context, base, span, flow_state); - if let Some(local) = place.base_local() { + let neo_place = tcx.as_new_place(place); + if let Some(local) = neo_place.base_local() { // rust-lang/rust#21232, // #54499, #54986: during // period where we reject @@ -1814,7 +1815,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // 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 = if let Some(local) = place.base_local() { + let neo_place = self.infcx.tcx.as_new_place(place); + let previously_initialized = if let Some(local) = neo_place.base_local() { self.is_local_ever_initialized(local, flow_state).is_some() } else { true diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs index 6f338158af3bd..c43e80749d6b5 100644 --- a/src/librustc_mir/borrow_check/used_muts.rs +++ b/src/librustc_mir/borrow_check/used_muts.rs @@ -61,7 +61,8 @@ impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'c debug!("visit_terminator_kind: kind={:?}", kind); match &kind { TerminatorKind::Call { destination: Some((into, _)), .. } => { - if let Some(local) = into.base_local() { + let neo_into = self.mbcx.infcx.tcx.as_new_place(into); + if let Some(local) = neo_into.base_local() { debug!( "visit_terminator_kind: kind={:?} local={:?} \ never_initialized_mut_locals={:?}", @@ -87,7 +88,8 @@ impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'c // 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. - if let Some(local) = into.base_local() { + let neo_into = self.mbcx.infcx.tcx.as_new_place(into); + if let Some(local) = neo_into.base_local() { debug!( "visit_statement: statement={:?} local={:?} \ never_initialized_mut_locals={:?}",