Mask results from flow-sensitive resolver with in_any_value_of_ty
We relied previously on the caller (e.g. `Q::in_operand`) to ignore `Local`s that were indirectly mutable (and thus assumed to be qualified). However, it's much clearer (and more efficient) to do this in the resolver itself. This does not yet remove the masking done in `Q::in_operand` and others for safety's sake, although I believe that should now be possible.
This commit is contained in:
parent
ff6faabda7
commit
a302055caa
1 changed files with 19 additions and 1 deletions
|
|
@ -188,6 +188,9 @@ where
|
|||
indirectly_mutable_locals: &'a RefCell<IndirectlyMutableResults<'mir, 'tcx>>,
|
||||
cursor: dataflow::ResultsCursor<'mir, 'tcx, FlowSensitiveAnalysis<'a, 'mir, 'tcx, Q>>,
|
||||
qualifs_per_local: BitSet<Local>,
|
||||
|
||||
/// The value of `Q::in_any_value_of_ty` for each local.
|
||||
qualifs_in_any_value_of_ty: BitSet<Local>,
|
||||
}
|
||||
|
||||
impl<Q> FlowSensitiveResolver<'a, 'mir, 'tcx, Q>
|
||||
|
|
@ -208,10 +211,18 @@ where
|
|||
dataflow::Engine::new(item.body, dead_unwinds, analysis).iterate_to_fixpoint();
|
||||
let cursor = dataflow::ResultsCursor::new(item.body, results);
|
||||
|
||||
let mut qualifs_in_any_value_of_ty = BitSet::new_empty(item.body.local_decls.len());
|
||||
for (local, decl) in item.body.local_decls.iter_enumerated() {
|
||||
if Q::in_any_value_of_ty(item, decl.ty) {
|
||||
qualifs_in_any_value_of_ty.insert(local);
|
||||
}
|
||||
}
|
||||
|
||||
FlowSensitiveResolver {
|
||||
cursor,
|
||||
indirectly_mutable_locals,
|
||||
qualifs_per_local: BitSet::new_empty(item.body.local_decls.len()),
|
||||
qualifs_in_any_value_of_ty,
|
||||
location: Location { block: mir::START_BLOCK, statement_index: 0 },
|
||||
}
|
||||
}
|
||||
|
|
@ -242,16 +253,23 @@ where
|
|||
|
||||
self.qualifs_per_local.overwrite(indirectly_mutable_locals.get());
|
||||
self.qualifs_per_local.union(self.cursor.get());
|
||||
self.qualifs_per_local.intersect(&self.qualifs_in_any_value_of_ty);
|
||||
&self.qualifs_per_local
|
||||
}
|
||||
|
||||
fn contains(&mut self, local: Local) -> bool {
|
||||
// No need to update the cursor if we know that `Local` cannot possibly be qualified.
|
||||
if !self.qualifs_in_any_value_of_ty.contains(local) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, return `true` if this local is qualified or was indirectly mutable at any
|
||||
// point before this statement.
|
||||
self.cursor.seek_before(self.location);
|
||||
if self.cursor.get().contains(local) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
let mut indirectly_mutable_locals = self.indirectly_mutable_locals.borrow_mut();
|
||||
indirectly_mutable_locals.seek(self.location);
|
||||
indirectly_mutable_locals.get().contains(local)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue