1
Fork 0

Call all Domain values state.

Currently they are called (most common) `state`, or `trans`, or (rare)
`on_entry`. I think `trans` is short for "transfer function", which
perhaps made more sense when `GenKillAnalysis` existed. Using `state`
everywhere now is more consistent.
This commit is contained in:
Nicholas Nethercote 2024-11-26 14:30:49 +11:00
parent 086233e282
commit 2298104f3f
5 changed files with 105 additions and 105 deletions

View file

@ -506,7 +506,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
/// That means they went out of a nonlexical scope
fn kill_loans_out_of_scope_at_location(
&self,
trans: &mut <Self as Analysis<'tcx>>::Domain,
state: &mut <Self as Analysis<'tcx>>::Domain,
location: Location,
) {
// NOTE: The state associated with a given `location`
@ -521,14 +521,14 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
// region, then setting that gen-bit will override any
// potential kill introduced here.
if let Some(indices) = self.borrows_out_of_scope_at_location.get(&location) {
trans.kill_all(indices.iter().copied());
state.kill_all(indices.iter().copied());
}
}
/// Kill any borrows that conflict with `place`.
fn kill_borrows_on_place(
&self,
trans: &mut <Self as Analysis<'tcx>>::Domain,
state: &mut <Self as Analysis<'tcx>>::Domain,
place: Place<'tcx>,
) {
debug!("kill_borrows_on_place: place={:?}", place);
@ -546,7 +546,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
// `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);
state.kill_all(other_borrows_of_local);
}
return;
}
@ -565,7 +565,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
)
});
trans.kill_all(definitely_conflicting_borrows);
state.kill_all(definitely_conflicting_borrows);
}
}
@ -595,16 +595,16 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
fn apply_before_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
_statement: &mir::Statement<'tcx>,
location: Location,
) {
self.kill_loans_out_of_scope_at_location(trans, location);
self.kill_loans_out_of_scope_at_location(state, location);
}
fn apply_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
stmt: &mir::Statement<'tcx>,
location: Location,
) {
@ -622,18 +622,18 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
panic!("could not find BorrowIndex for location {location:?}");
});
trans.gen_(index);
state.gen_(index);
}
// Make sure there are no remaining borrows for variables
// that are assigned over.
self.kill_borrows_on_place(trans, *lhs);
self.kill_borrows_on_place(state, *lhs);
}
mir::StatementKind::StorageDead(local) => {
// Make sure there are no remaining borrows for locals that
// are gone out of scope.
self.kill_borrows_on_place(trans, Place::from(*local));
self.kill_borrows_on_place(state, Place::from(*local));
}
mir::StatementKind::FakeRead(..)
@ -653,16 +653,16 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
fn apply_before_terminator_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
_terminator: &mir::Terminator<'tcx>,
location: Location,
) {
self.kill_loans_out_of_scope_at_location(trans, location);
self.kill_loans_out_of_scope_at_location(state, location);
}
fn apply_terminator_effect<'mir>(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
_location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
@ -671,7 +671,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
if let mir::InlineAsmOperand::Out { place: Some(place), .. }
| mir::InlineAsmOperand::InOut { out_place: Some(place), .. } = *op
{
self.kill_borrows_on_place(trans, place);
self.kill_borrows_on_place(state, place);
}
}
}

View file

@ -35,20 +35,20 @@ impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals {
fn apply_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
statement: &Statement<'tcx>,
location: Location,
) {
Self::transfer_function(trans).visit_statement(statement, location);
Self::transfer_function(state).visit_statement(statement, location);
}
fn apply_terminator_effect<'mir>(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
terminator: &'mir Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
Self::transfer_function(trans).visit_terminator(terminator, location);
Self::transfer_function(state).visit_terminator(terminator, location);
terminator.edges()
}
}

View file

@ -218,26 +218,26 @@ impl<'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'_, 'tcx> {
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
fn update_bits(
trans: &mut <Self as Analysis<'tcx>>::Domain,
state: &mut <Self as Analysis<'tcx>>::Domain,
path: MovePathIndex,
state: DropFlagState,
dfstate: DropFlagState,
) {
match state {
DropFlagState::Absent => trans.kill(path),
DropFlagState::Present => trans.gen_(path),
match dfstate {
DropFlagState::Absent => state.kill(path),
DropFlagState::Present => state.gen_(path),
}
}
}
impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> {
fn update_bits(
trans: &mut <Self as Analysis<'tcx>>::Domain,
state: &mut <Self as Analysis<'tcx>>::Domain,
path: MovePathIndex,
state: DropFlagState,
dfstate: DropFlagState,
) {
match state {
DropFlagState::Absent => trans.gen_(path),
DropFlagState::Present => trans.kill(path),
match dfstate {
DropFlagState::Absent => state.gen_(path),
DropFlagState::Present => state.kill(path),
}
}
}
@ -265,12 +265,12 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
fn apply_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
statement: &mir::Statement<'tcx>,
location: Location,
) {
drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
Self::update_bits(trans, path, s)
Self::update_bits(state, path, s)
});
// Mark all places as "maybe init" if they are mutably borrowed. See #90752.
@ -282,7 +282,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
&& let LookupResult::Exact(mpi) = self.move_data().rev_lookup.find(place.as_ref())
{
on_all_children_bits(self.move_data(), mpi, |child| {
trans.gen_(child);
state.gen_(child);
})
}
}
@ -309,7 +309,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
fn apply_call_return_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
_block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
@ -320,7 +320,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
self.move_data(),
self.move_data().rev_lookup.find(place.as_ref()),
|mpi| {
trans.gen_(mpi);
state.gen_(mpi);
},
);
});
@ -345,7 +345,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
};
let mut discriminants = enum_def.discriminants(self.tcx);
edge_effects.apply(|trans, edge| {
edge_effects.apply(|state, edge| {
let Some(value) = edge.value else {
return;
};
@ -363,7 +363,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
self.move_data(),
enum_place,
variant,
|mpi| trans.kill(mpi),
|mpi| state.kill(mpi),
);
});
}
@ -383,7 +383,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
MixedBitSet::new_empty(self.move_data().move_paths.len())
}
// sets on_entry bits for Arg places
// sets state bits for Arg places
fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) {
// set all bits to 1 (uninit) before gathering counter-evidence
state.insert_all();
@ -396,12 +396,12 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
fn apply_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
_statement: &mir::Statement<'tcx>,
location: Location,
) {
drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
Self::update_bits(trans, path, s)
Self::update_bits(state, path, s)
});
// Unlike in `MaybeInitializedPlaces` above, we don't need to change the state when a
@ -410,12 +410,12 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
fn apply_terminator_effect<'mir>(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
Self::update_bits(trans, path, s)
Self::update_bits(state, path, s)
});
if self.skip_unreachable_unwind.contains(location.block) {
let mir::TerminatorKind::Drop { target, unwind, .. } = terminator.kind else { bug!() };
@ -428,7 +428,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
fn apply_call_return_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
_block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
@ -439,7 +439,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
self.move_data(),
self.move_data().rev_lookup.find(place.as_ref()),
|mpi| {
trans.kill(mpi);
state.kill(mpi);
},
);
});
@ -468,7 +468,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
};
let mut discriminants = enum_def.discriminants(self.tcx);
edge_effects.apply(|trans, edge| {
edge_effects.apply(|state, edge| {
let Some(value) = edge.value else {
return;
};
@ -486,7 +486,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
self.move_data(),
enum_place,
variant,
|mpi| trans.gen_(mpi),
|mpi| state.gen_(mpi),
);
});
}
@ -512,10 +512,10 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
}
}
#[instrument(skip(self, trans), level = "debug")]
#[instrument(skip(self, state), level = "debug")]
fn apply_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
stmt: &mir::Statement<'tcx>,
location: Location,
) {
@ -525,7 +525,7 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
let rev_lookup = &move_data.rev_lookup;
debug!("initializes move_indexes {:?}", init_loc_map[location]);
trans.gen_all(init_loc_map[location].iter().copied());
state.gen_all(init_loc_map[location].iter().copied());
if let mir::StatementKind::StorageDead(local) = stmt.kind {
// End inits for StorageDead, so that an immutable variable can
@ -535,15 +535,15 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
"clears the ever initialized status of {:?}",
init_path_map[move_path_index]
);
trans.kill_all(init_path_map[move_path_index].iter().copied());
state.kill_all(init_path_map[move_path_index].iter().copied());
}
}
}
#[instrument(skip(self, trans, terminator), level = "debug")]
#[instrument(skip(self, state, terminator), level = "debug")]
fn apply_terminator_effect<'mir>(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
@ -552,7 +552,7 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
let init_loc_map = &move_data.init_loc_map;
debug!(?term);
debug!("initializes move_indexes {:?}", init_loc_map[location]);
trans.gen_all(
state.gen_all(
init_loc_map[location]
.iter()
.filter(|init_index| {
@ -565,7 +565,7 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
fn apply_call_return_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
block: mir::BasicBlock,
_return_places: CallReturnPlaces<'_, 'tcx>,
) {
@ -574,7 +574,7 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
let call_loc = self.body.terminator_loc(block);
for init_index in &init_loc_map[call_loc] {
trans.gen_(*init_index);
state.gen_(*init_index);
}
}
}

View file

@ -42,31 +42,31 @@ impl<'tcx> Analysis<'tcx> for MaybeLiveLocals {
fn apply_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
statement: &mir::Statement<'tcx>,
location: Location,
) {
TransferFunction(trans).visit_statement(statement, location);
TransferFunction(state).visit_statement(statement, location);
}
fn apply_terminator_effect<'mir>(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
TransferFunction(trans).visit_terminator(terminator, location);
TransferFunction(state).visit_terminator(terminator, location);
terminator.edges()
}
fn apply_call_return_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
_block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
if let CallReturnPlaces::Yield(resume_place) = return_places {
YieldResumeEffect(trans).visit_place(
YieldResumeEffect(state).visit_place(
&resume_place,
PlaceContext::MutatingUse(MutatingUseContext::Yield),
Location::START,
@ -74,7 +74,7 @@ impl<'tcx> Analysis<'tcx> for MaybeLiveLocals {
} else {
return_places.for_each(|place| {
if let Some(local) = place.as_local() {
trans.kill(local);
state.kill(local);
}
});
}
@ -137,10 +137,10 @@ enum DefUse {
}
impl DefUse {
fn apply(trans: &mut BitSet<Local>, place: Place<'_>, context: PlaceContext) {
fn apply(state: &mut BitSet<Local>, place: Place<'_>, context: PlaceContext) {
match DefUse::for_place(place, context) {
Some(DefUse::Def) => trans.kill(place.local),
Some(DefUse::Use) => trans.gen_(place.local),
Some(DefUse::Def) => state.kill(place.local),
Some(DefUse::Use) => state.gen_(place.local),
None => {}
}
}
@ -234,7 +234,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
fn apply_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
statement: &mir::Statement<'tcx>,
location: Location,
) {
@ -258,34 +258,34 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
};
if let Some(destination) = destination {
if !destination.is_indirect()
&& !trans.contains(destination.local)
&& !state.contains(destination.local)
&& !self.always_live.contains(destination.local)
{
// This store is dead
return;
}
}
TransferFunction(trans).visit_statement(statement, location);
TransferFunction(state).visit_statement(statement, location);
}
fn apply_terminator_effect<'mir>(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
TransferFunction(trans).visit_terminator(terminator, location);
TransferFunction(state).visit_terminator(terminator, location);
terminator.edges()
}
fn apply_call_return_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
_block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
if let CallReturnPlaces::Yield(resume_place) = return_places {
YieldResumeEffect(trans).visit_place(
YieldResumeEffect(state).visit_place(
&resume_place,
PlaceContext::MutatingUse(MutatingUseContext::Yield),
Location::START,
@ -293,7 +293,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
} else {
return_places.for_each(|place| {
if let Some(local) = place.as_local() {
trans.remove(local);
state.remove(local);
}
});
}

View file

@ -44,23 +44,23 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageLive<'a> {
BitSet::new_empty(body.local_decls.len())
}
fn initialize_start_block(&self, body: &Body<'tcx>, on_entry: &mut Self::Domain) {
on_entry.union(&*self.always_live_locals);
fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) {
state.union(&*self.always_live_locals);
for arg in body.args_iter() {
on_entry.insert(arg);
state.insert(arg);
}
}
fn apply_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
stmt: &Statement<'tcx>,
_: Location,
) {
match stmt.kind {
StatementKind::StorageLive(l) => trans.gen_(l),
StatementKind::StorageDead(l) => trans.kill(l),
StatementKind::StorageLive(l) => state.gen_(l),
StatementKind::StorageDead(l) => state.kill(l),
_ => (),
}
}
@ -86,25 +86,25 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageDead<'a> {
BitSet::new_empty(body.local_decls.len())
}
fn initialize_start_block(&self, body: &Body<'tcx>, on_entry: &mut Self::Domain) {
fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) {
assert_eq!(body.local_decls.len(), self.always_live_locals.domain_size());
// Do not iterate on return place and args, as they are trivially always live.
for local in body.vars_and_temps_iter() {
if !self.always_live_locals.contains(local) {
on_entry.insert(local);
state.insert(local);
}
}
}
fn apply_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
stmt: &Statement<'tcx>,
_: Location,
) {
match stmt.kind {
StatementKind::StorageLive(l) => trans.kill(l),
StatementKind::StorageDead(l) => trans.gen_(l),
StatementKind::StorageLive(l) => state.kill(l),
StatementKind::StorageDead(l) => state.gen_(l),
_ => (),
}
}
@ -134,31 +134,31 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
BitSet::new_empty(body.local_decls.len())
}
fn initialize_start_block(&self, body: &Body<'tcx>, on_entry: &mut Self::Domain) {
fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) {
// The resume argument is live on function entry (we don't care about
// the `self` argument)
for arg in body.args_iter().skip(1) {
on_entry.insert(arg);
state.insert(arg);
}
}
fn apply_before_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
stmt: &Statement<'tcx>,
loc: Location,
) {
// If a place is borrowed in a statement, it needs storage for that statement.
MaybeBorrowedLocals::transfer_function(trans).visit_statement(stmt, loc);
MaybeBorrowedLocals::transfer_function(state).visit_statement(stmt, loc);
match &stmt.kind {
StatementKind::StorageDead(l) => trans.kill(*l),
StatementKind::StorageDead(l) => state.kill(*l),
// If a place is assigned to in a statement, it needs storage for that statement.
StatementKind::Assign(box (place, _))
| StatementKind::SetDiscriminant { box place, .. }
| StatementKind::Deinit(box place) => {
trans.gen_(place.local);
state.gen_(place.local);
}
// Nothing to do for these. Match exhaustively so this fails to compile when new
@ -178,27 +178,27 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
fn apply_statement_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
_: &Statement<'tcx>,
loc: Location,
) {
// If we move from a place then it only stops needing storage *after*
// that statement.
self.check_for_move(trans, loc);
self.check_for_move(state, loc);
}
fn apply_before_terminator_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
terminator: &Terminator<'tcx>,
loc: Location,
) {
// If a place is borrowed in a terminator, it needs storage for that terminator.
MaybeBorrowedLocals::transfer_function(trans).visit_terminator(terminator, loc);
MaybeBorrowedLocals::transfer_function(state).visit_terminator(terminator, loc);
match &terminator.kind {
TerminatorKind::Call { destination, .. } => {
trans.gen_(destination.local);
state.gen_(destination.local);
}
// Note that we do *not* gen the `resume_arg` of `Yield` terminators. The reason for
@ -213,7 +213,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
InlineAsmOperand::Out { place, .. }
| InlineAsmOperand::InOut { out_place: place, .. } => {
if let Some(place) = place {
trans.gen_(place.local);
state.gen_(place.local);
}
}
InlineAsmOperand::In { .. }
@ -244,7 +244,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
fn apply_terminator_effect<'t>(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
terminator: &'t Terminator<'tcx>,
loc: Location,
) -> TerminatorEdges<'t, 'tcx> {
@ -254,12 +254,12 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
// Since `propagate_call_unwind` doesn't exist, we have to kill the
// destination here, and then gen it again in `call_return_effect`.
TerminatorKind::Call { destination, .. } => {
trans.kill(destination.local);
state.kill(destination.local);
}
// The same applies to InlineAsm outputs.
TerminatorKind::InlineAsm { ref operands, .. } => {
CallReturnPlaces::InlineAsm(operands).for_each(|place| trans.kill(place.local));
CallReturnPlaces::InlineAsm(operands).for_each(|place| state.kill(place.local));
}
// Nothing to do for these. Match exhaustively so this fails to compile when new
@ -279,32 +279,32 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
| TerminatorKind::Unreachable => {}
}
self.check_for_move(trans, loc);
self.check_for_move(state, loc);
terminator.edges()
}
fn apply_call_return_effect(
&mut self,
trans: &mut Self::Domain,
state: &mut Self::Domain,
_block: BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
return_places.for_each(|place| trans.gen_(place.local));
return_places.for_each(|place| state.gen_(place.local));
}
}
impl<'tcx> MaybeRequiresStorage<'_, 'tcx> {
/// Kill locals that are fully moved and have not been borrowed.
fn check_for_move(&mut self, trans: &mut <Self as Analysis<'tcx>>::Domain, loc: Location) {
fn check_for_move(&mut self, state: &mut <Self as Analysis<'tcx>>::Domain, loc: Location) {
let body = self.borrowed_locals.body();
let mut visitor = MoveVisitor { trans, borrowed_locals: &mut self.borrowed_locals };
let mut visitor = MoveVisitor { state, borrowed_locals: &mut self.borrowed_locals };
visitor.visit_location(body, loc);
}
}
struct MoveVisitor<'a, 'mir, 'tcx> {
borrowed_locals: &'a mut BorrowedLocalsResults<'mir, 'tcx>,
trans: &'a mut BitSet<Local>,
state: &'a mut BitSet<Local>,
}
impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, 'tcx> {
@ -312,7 +312,7 @@ impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, 'tcx> {
if PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) == context {
self.borrowed_locals.seek_before_primary_effect(loc);
if !self.borrowed_locals.get().contains(local) {
self.trans.kill(local);
self.state.kill(local);
}
}
}