Auto merge of #126023 - amandasystems:you-dropped-this-again, r=nikom… · rust-lang/rust@d49994b (original) (raw)
`@@ -217,35 +217,52 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
`
217
217
`/// Add facts for all locals with free regions, since regions may outlive
`
218
218
`/// the function body only at certain nodes in the CFG.
`
219
219
`fn add_extra_drop_facts(&mut self, relevant_live_locals: &[Local]) -> Option<()> {
`
220
``
`-
let drop_used = self
`
221
``
`-
.cx
`
222
``
`-
.typeck
`
223
``
`-
.borrowck_context
`
224
``
`-
.all_facts
`
225
``
`-
.as_ref()
`
226
``
`-
.map(|facts| facts.var_dropped_at.clone())?;
`
``
220
`+
// This collect is more necessary than immediately apparent
`
``
221
`` +
// because these facts go into add_drop_live_facts_for()
,
``
``
222
`` +
// which also writes to all_facts
, and so this is genuinely
``
``
223
`+
// a simulatneous overlapping mutable borrow.
`
``
224
`+
// FIXME for future hackers: investigate whether this is
`
``
225
`+
// actually necessary; these facts come from Polonius
`
``
226
`+
// and probably maybe plausibly does not need to go back in.
`
``
227
`+
// It may be necessary to just pick out the parts of
`
``
228
`` +
// add_drop_live_facts_for()
that make sense.
``
``
229
`+
let facts_to_add: Vec<_> = {
`
``
230
`+
let drop_used = &self.cx.typeck.borrowck_context.all_facts.as_ref()?.var_dropped_at;
`
``
231
+
``
232
`+
let relevant_live_locals: FxIndexSet<_> =
`
``
233
`+
relevant_live_locals.iter().copied().collect();
`
``
234
+
``
235
`+
drop_used
`
``
236
`+
.iter()
`
``
237
`+
.filter_map(|(local, location_index)| {
`
``
238
`+
let local_ty = self.cx.body.local_decls[*local].ty;
`
``
239
`+
if relevant_live_locals.contains(local) || !local_ty.has_free_regions() {
`
``
240
`+
return None;
`
``
241
`+
}
`
227
242
``
228
``
`-
let relevant_live_locals: FxIndexSet<_> = relevant_live_locals.iter().copied().collect();
`
229
``
-
230
``
`-
let locations = IntervalSet::new(self.cx.elements.num_points());
`
231
``
-
232
``
`-
for (local, location_index) in drop_used {
`
233
``
`-
if !relevant_live_locals.contains(&local) {
`
234
``
`-
let local_ty = self.cx.body.local_decls[local].ty;
`
235
``
`-
if local_ty.has_free_regions() {
`
236
243
`let location = match self
`
237
244
`.cx
`
238
245
`.typeck
`
239
246
`.borrowck_context
`
240
247
`.location_table
`
241
``
`-
.to_location(location_index)
`
``
248
`+
.to_location(*location_index)
`
242
249
`{
`
243
250
`RichLocation::Start(l) => l,
`
244
251
`RichLocation::Mid(l) => l,
`
245
252
`};
`
246
``
`-
self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations);
`
247
``
`-
}
`
248
``
`-
}
`
``
253
+
``
254
`+
Some((*local, local_ty, location))
`
``
255
`+
})
`
``
256
`+
.collect()
`
``
257
`+
};
`
``
258
+
``
259
`+
// FIXME: these locations seem to have a special meaning (e.g. everywhere, at the end, ...), but I don't know which one. Please help me rename it to something descriptive!
`
``
260
`+
// Also, if this IntervalSet is used in many places, it maybe should have a newtype'd
`
``
261
`+
// name with a description of what it means for future mortals passing by.
`
``
262
`+
let locations = IntervalSet::new(self.cx.elements.num_points());
`
``
263
+
``
264
`+
for (local, local_ty, location) in facts_to_add {
`
``
265
`+
self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations);
`
249
266
`}
`
250
267
`Some(())
`
251
268
`}
`