Skip to content

Commit a302055

Browse files
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.
1 parent ff6faab commit a302055

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/librustc_mir/transform/check_consts/resolver.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ where
188188
indirectly_mutable_locals: &'a RefCell<IndirectlyMutableResults<'mir, 'tcx>>,
189189
cursor: dataflow::ResultsCursor<'mir, 'tcx, FlowSensitiveAnalysis<'a, 'mir, 'tcx, Q>>,
190190
qualifs_per_local: BitSet<Local>,
191+
192+
/// The value of `Q::in_any_value_of_ty` for each local.
193+
qualifs_in_any_value_of_ty: BitSet<Local>,
191194
}
192195

193196
impl<Q> FlowSensitiveResolver<'a, 'mir, 'tcx, Q>
@@ -208,10 +211,18 @@ where
208211
dataflow::Engine::new(item.body, dead_unwinds, analysis).iterate_to_fixpoint();
209212
let cursor = dataflow::ResultsCursor::new(item.body, results);
210213

214+
let mut qualifs_in_any_value_of_ty = BitSet::new_empty(item.body.local_decls.len());
215+
for (local, decl) in item.body.local_decls.iter_enumerated() {
216+
if Q::in_any_value_of_ty(item, decl.ty) {
217+
qualifs_in_any_value_of_ty.insert(local);
218+
}
219+
}
220+
211221
FlowSensitiveResolver {
212222
cursor,
213223
indirectly_mutable_locals,
214224
qualifs_per_local: BitSet::new_empty(item.body.local_decls.len()),
225+
qualifs_in_any_value_of_ty,
215226
location: Location { block: mir::START_BLOCK, statement_index: 0 },
216227
}
217228
}
@@ -242,16 +253,23 @@ where
242253

243254
self.qualifs_per_local.overwrite(indirectly_mutable_locals.get());
244255
self.qualifs_per_local.union(self.cursor.get());
256+
self.qualifs_per_local.intersect(&self.qualifs_in_any_value_of_ty);
245257
&self.qualifs_per_local
246258
}
247259

248260
fn contains(&mut self, local: Local) -> bool {
261+
// No need to update the cursor if we know that `Local` cannot possibly be qualified.
262+
if !self.qualifs_in_any_value_of_ty.contains(local) {
263+
return false;
264+
}
265+
266+
// Otherwise, return `true` if this local is qualified or was indirectly mutable at any
267+
// point before this statement.
249268
self.cursor.seek_before(self.location);
250269
if self.cursor.get().contains(local) {
251270
return true;
252271
}
253272

254-
255273
let mut indirectly_mutable_locals = self.indirectly_mutable_locals.borrow_mut();
256274
indirectly_mutable_locals.seek(self.location);
257275
indirectly_mutable_locals.get().contains(local)

0 commit comments

Comments
 (0)