1
Fork 0

Avoid using a magic value for untracked locals.

This commit is contained in:
Camille GILLOT 2023-10-12 17:19:19 +00:00
parent 8d535070a2
commit 90e6d29955
6 changed files with 41 additions and 31 deletions

View file

@ -2611,11 +2611,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/* Check if the mpi is initialized as an argument */ /* Check if the mpi is initialized as an argument */
let mut is_argument = false; let mut is_argument = false;
for arg in self.body.args_iter() { for arg in self.body.args_iter() {
let path = self.move_data.rev_lookup.find_local(arg); if let Some(path) = self.move_data.rev_lookup.find_local(arg) {
if mpis.contains(&path) { if mpis.contains(&path) {
is_argument = true; is_argument = true;
} }
} }
}
let mut visited = FxIndexSet::default(); let mut visited = FxIndexSet::default();
let mut move_locations = FxIndexSet::default(); let mut move_locations = FxIndexSet::default();

View file

@ -1416,7 +1416,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// As such we have to search for the local that this // As such we have to search for the local that this
// capture comes from and mark it as being used as mut. // 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] { let init = if let [init_index] = *self.move_data.init_path_map[temp_mpi] {
&self.move_data.inits[init_index] &self.move_data.inits[init_index]
} else { } else {
@ -2223,7 +2225,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
local: Local, local: Local,
flow_state: &Flows<'cx, 'tcx>, flow_state: &Flows<'cx, 'tcx>,
) -> Option<InitIndex> { ) -> Option<InitIndex> {
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]; let ii = &self.move_data.init_path_map[mpi];
ii.into_iter().find(|&&index| flow_state.ever_inits.contains(index)).copied() ii.into_iter().find(|&&index| flow_state.ever_inits.contains(index)).copied()
} }

View file

@ -317,7 +317,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
fn compute_drop_live_points_for(&mut self, local: Local) { fn compute_drop_live_points_for(&mut self, local: Local) {
debug!("compute_drop_live_points_for(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); debug!("compute_drop_live_points_for: mpi = {:?}", mpi);
// Find the drops where `local` is initialized. // Find the drops where `local` is initialized.

View file

@ -690,11 +690,15 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
if let mir::StatementKind::StorageDead(local) = stmt.kind { if let mir::StatementKind::StorageDead(local) = stmt.kind {
// End inits for StorageDead, so that an immutable variable can // End inits for StorageDead, so that an immutable variable can
// be reinitialized on the next iteration of the loop. // be reinitialized on the next iteration of the loop.
let move_path_index = rev_lookup.find_local(local); if let Some(move_path_index) = rev_lookup.find_local(local) {
debug!("clears the ever initialized status of {:?}", init_path_map[move_path_index]); debug!(
"clears the ever initialized status of {:?}",
init_path_map[move_path_index]
);
trans.kill_all(init_path_map[move_path_index].iter().copied()); trans.kill_all(init_path_map[move_path_index].iter().copied());
} }
} }
}
#[instrument(skip(self, trans, terminator), level = "debug")] #[instrument(skip(self, trans, terminator), level = "debug")]
fn terminator_effect<'mir>( fn terminator_effect<'mir>(

View file

@ -39,15 +39,15 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
.iter_enumerated() .iter_enumerated()
.map(|(i, l)| { .map(|(i, l)| {
if l.is_deref_temp() { if l.is_deref_temp() {
MovePathIndex::MAX None
} else { } else {
Self::new_move_path( Some(Self::new_move_path(
&mut move_paths, &mut move_paths,
&mut path_map, &mut path_map,
&mut init_path_map, &mut init_path_map,
None, None,
Place::from(i), Place::from(i),
) ))
} }
}) })
.collect(), .collect(),
@ -100,7 +100,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
let data = &mut self.builder.data; let data = &mut self.builder.data;
debug!("lookup({:?})", place); 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 // 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 // some we stop creating child move paths, since moves from unions
@ -328,8 +330,7 @@ pub(super) fn gather_moves<'tcx>(
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
fn gather_args(&mut self) { fn gather_args(&mut self) {
for arg in self.body.args_iter() { 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 { let init = self.data.inits.push(Init {
path, path,
kind: InitKind::Deep, kind: InitKind::Deep,
@ -341,6 +342,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
self.data.init_path_map[path].push(init); self.data.init_path_map[path].push(init);
} }
} }
}
fn gather_statement(&mut self, loc: Location, stmt: &Statement<'tcx>) { fn gather_statement(&mut self, loc: Location, stmt: &Statement<'tcx>) {
debug!("gather_statement({:?}, {:?})", loc, stmt); debug!("gather_statement({:?}, {:?})", loc, stmt);
@ -546,9 +548,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
self.record_move(place, path); self.record_move(place, path);
return; return;
} }
Err(MoveError::IllegalMove { .. }) => { Err(MoveError::IllegalMove { .. } | MoveError::UntrackedLocal) => return,
return;
}
}; };
let base_ty = base_place.ty(self.builder.body, self.builder.tcx).ty; let base_ty = base_place.ty(self.builder.body, self.builder.tcx).ty;
let len: u64 = match base_ty.kind() { let len: u64 = match base_ty.kind() {
@ -567,7 +567,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
} else { } else {
match self.move_path_for(place) { match self.move_path_for(place) {
Ok(path) | Err(MoveError::UnionMove { path }) => self.record_move(place, path), Ok(path) | Err(MoveError::UnionMove { path }) => self.record_move(place, path),
Err(MoveError::IllegalMove { .. }) => {} Err(MoveError::IllegalMove { .. } | MoveError::UntrackedLocal) => {}
}; };
} }
} }

View file

@ -290,7 +290,7 @@ impl Init {
/// Tables mapping from a place to its MovePathIndex. /// Tables mapping from a place to its MovePathIndex.
#[derive(Debug)] #[derive(Debug)]
pub struct MovePathLookup<'tcx> { pub struct MovePathLookup<'tcx> {
locals: IndexVec<Local, MovePathIndex>, locals: IndexVec<Local, Option<MovePathIndex>>,
/// projections are made from a base-place and a projection /// projections are made from a base-place and a projection
/// elem. The base-place will have a unique MovePathIndex; we use /// 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 // unknown place, but will rather return the nearest available
// parent. // parent.
pub fn find(&self, place: PlaceRef<'tcx>) -> LookupResult { 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) { for (_, elem) in self.un_derefer.iter_projections(place) {
if let Some(&subpath) = self.projections.get(&(result, elem.lift())) { if let Some(&subpath) = self.projections.get(&(result, elem.lift())) {
@ -331,7 +333,7 @@ impl<'tcx> MovePathLookup<'tcx> {
} }
#[inline] #[inline]
pub fn find_local(&self, local: Local) -> MovePathIndex { pub fn find_local(&self, local: Local) -> Option<MovePathIndex> {
self.locals[local] self.locals[local]
} }
@ -339,8 +341,8 @@ impl<'tcx> MovePathLookup<'tcx> {
/// `MovePathIndex`es. /// `MovePathIndex`es.
pub fn iter_locals_enumerated( pub fn iter_locals_enumerated(
&self, &self,
) -> impl DoubleEndedIterator<Item = (Local, MovePathIndex)> + ExactSizeIterator + '_ { ) -> impl DoubleEndedIterator<Item = (Local, MovePathIndex)> + '_ {
self.locals.iter_enumerated().map(|(l, &idx)| (l, idx)) self.locals.iter_enumerated().filter_map(|(l, &idx)| Some((l, idx?)))
} }
} }
@ -373,6 +375,7 @@ pub enum IllegalMoveOriginKind<'tcx> {
pub enum MoveError<'tcx> { pub enum MoveError<'tcx> {
IllegalMove { cannot_move_out_of: IllegalMoveOrigin<'tcx> }, IllegalMove { cannot_move_out_of: IllegalMoveOrigin<'tcx> },
UnionMove { path: MovePathIndex }, UnionMove { path: MovePathIndex },
UntrackedLocal,
} }
impl<'tcx> MoveError<'tcx> { impl<'tcx> MoveError<'tcx> {