From 90e6d2995581b9f03be52ed7fa92fa6a5b981294 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 12 Oct 2023 17:19:19 +0000 Subject: [PATCH] Avoid using a magic value for untracked locals. --- .../src/diagnostics/conflict_errors.rs | 7 ++-- compiler/rustc_borrowck/src/lib.rs | 6 ++-- .../src/type_check/liveness/trace.rs | 2 +- .../src/impls/initialized.rs | 10 ++++-- .../src/move_paths/builder.rs | 34 +++++++++---------- .../rustc_mir_dataflow/src/move_paths/mod.rs | 13 ++++--- 6 files changed, 41 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 00816c0f253..f47703f72de 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2611,9 +2611,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /* Check if the mpi is initialized as an argument */ let mut is_argument = false; for arg in self.body.args_iter() { - let path = self.move_data.rev_lookup.find_local(arg); - if mpis.contains(&path) { - is_argument = true; + if let Some(path) = self.move_data.rev_lookup.find_local(arg) { + if mpis.contains(&path) { + is_argument = true; + } } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 244b953e29b..3f6cab102e1 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1416,7 +1416,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // As such we have to search for the local that this // capture comes from and mark it as being used as mut. - let temp_mpi = self.move_data.rev_lookup.find_local(local); + let Some(temp_mpi) = self.move_data.rev_lookup.find_local(local) else { + bug!("temporary should be tracked"); + }; let init = if let [init_index] = *self.move_data.init_path_map[temp_mpi] { &self.move_data.inits[init_index] } else { @@ -2223,7 +2225,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { local: Local, flow_state: &Flows<'cx, 'tcx>, ) -> Option { - let mpi = self.move_data.rev_lookup.find_local(local); + let mpi = self.move_data.rev_lookup.find_local(local)?; let ii = &self.move_data.init_path_map[mpi]; ii.into_iter().find(|&&index| flow_state.ever_inits.contains(index)).copied() } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 80e6c6c1dfb..cfefe0a3e65 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -317,7 +317,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> { fn compute_drop_live_points_for(&mut self, local: Local) { debug!("compute_drop_live_points_for(local={:?})", local); - let mpi = self.cx.move_data.rev_lookup.find_local(local); + let Some(mpi) = self.cx.move_data.rev_lookup.find_local(local) else { return }; debug!("compute_drop_live_points_for: mpi = {:?}", mpi); // Find the drops where `local` is initialized. diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index 182f2590137..60488626974 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -690,9 +690,13 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { if let mir::StatementKind::StorageDead(local) = stmt.kind { // End inits for StorageDead, so that an immutable variable can // be reinitialized on the next iteration of the loop. - let move_path_index = rev_lookup.find_local(local); - debug!("clears the ever initialized status of {:?}", init_path_map[move_path_index]); - trans.kill_all(init_path_map[move_path_index].iter().copied()); + if let Some(move_path_index) = rev_lookup.find_local(local) { + debug!( + "clears the ever initialized status of {:?}", + init_path_map[move_path_index] + ); + trans.kill_all(init_path_map[move_path_index].iter().copied()); + } } } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index c171a7ebdbe..0796794d436 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -39,15 +39,15 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { .iter_enumerated() .map(|(i, l)| { if l.is_deref_temp() { - MovePathIndex::MAX + None } else { - Self::new_move_path( + Some(Self::new_move_path( &mut move_paths, &mut path_map, &mut init_path_map, None, Place::from(i), - ) + )) } }) .collect(), @@ -100,7 +100,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { let data = &mut self.builder.data; debug!("lookup({:?})", place); - let mut base = data.rev_lookup.find_local(place.local); + let Some(mut base) = data.rev_lookup.find_local(place.local) else { + return Err(MoveError::UntrackedLocal); + }; // 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 @@ -328,17 +330,17 @@ pub(super) fn gather_moves<'tcx>( impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { fn gather_args(&mut self) { for arg in self.body.args_iter() { - let path = self.data.rev_lookup.find_local(arg); + if let Some(path) = self.data.rev_lookup.find_local(arg) { + let init = self.data.inits.push(Init { + path, + kind: InitKind::Deep, + location: InitLocation::Argument(arg), + }); - let init = self.data.inits.push(Init { - path, - kind: InitKind::Deep, - location: InitLocation::Argument(arg), - }); + debug!("gather_args: adding init {:?} of {:?} for argument {:?}", init, path, arg); - debug!("gather_args: adding init {:?} of {:?} for argument {:?}", init, path, arg); - - self.data.init_path_map[path].push(init); + self.data.init_path_map[path].push(init); + } } } @@ -546,9 +548,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { self.record_move(place, path); return; } - Err(MoveError::IllegalMove { .. }) => { - return; - } + Err(MoveError::IllegalMove { .. } | MoveError::UntrackedLocal) => return, }; let base_ty = base_place.ty(self.builder.body, self.builder.tcx).ty; let len: u64 = match base_ty.kind() { @@ -567,7 +567,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } else { match self.move_path_for(place) { Ok(path) | Err(MoveError::UnionMove { path }) => self.record_move(place, path), - Err(MoveError::IllegalMove { .. }) => {} + Err(MoveError::IllegalMove { .. } | MoveError::UntrackedLocal) => {} }; } } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index 389deb7b355..fff7d12ec48 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -290,7 +290,7 @@ impl Init { /// Tables mapping from a place to its MovePathIndex. #[derive(Debug)] pub struct MovePathLookup<'tcx> { - locals: IndexVec, + locals: IndexVec>, /// projections are made from a base-place and a projection /// elem. The base-place will have a unique MovePathIndex; we use @@ -317,7 +317,9 @@ impl<'tcx> MovePathLookup<'tcx> { // unknown place, but will rather return the nearest available // parent. pub fn find(&self, place: PlaceRef<'tcx>) -> LookupResult { - let mut result = self.find_local(place.local); + let Some(mut result) = self.find_local(place.local) else { + return LookupResult::Parent(None); + }; for (_, elem) in self.un_derefer.iter_projections(place) { if let Some(&subpath) = self.projections.get(&(result, elem.lift())) { @@ -331,7 +333,7 @@ impl<'tcx> MovePathLookup<'tcx> { } #[inline] - pub fn find_local(&self, local: Local) -> MovePathIndex { + pub fn find_local(&self, local: Local) -> Option { self.locals[local] } @@ -339,8 +341,8 @@ impl<'tcx> MovePathLookup<'tcx> { /// `MovePathIndex`es. pub fn iter_locals_enumerated( &self, - ) -> impl DoubleEndedIterator + ExactSizeIterator + '_ { - self.locals.iter_enumerated().map(|(l, &idx)| (l, idx)) + ) -> impl DoubleEndedIterator + '_ { + self.locals.iter_enumerated().filter_map(|(l, &idx)| Some((l, idx?))) } } @@ -373,6 +375,7 @@ pub enum IllegalMoveOriginKind<'tcx> { pub enum MoveError<'tcx> { IllegalMove { cannot_move_out_of: IllegalMoveOrigin<'tcx> }, UnionMove { path: MovePathIndex }, + UntrackedLocal, } impl<'tcx> MoveError<'tcx> {