Skip to content

Commit a73d620

Browse files
committed
Nit: reset more state after take_and_reset_data
1 parent 11c84c6 commit a73d620

File tree

1 file changed

+50
-4
lines changed
  • src/librustc/infer/region_constraints

1 file changed

+50
-4
lines changed

src/librustc/infer/region_constraints/mod.rs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,54 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
296296
(self.var_origins, self.data)
297297
}
298298

299-
/// Takes (and clears) the current set of constraints. Note that the set of
300-
/// variables remains intact.
299+
/// Takes (and clears) the current set of constraints. Note that
300+
/// the set of variables remains intact, but all relationships
301+
/// between them are reset. This is used during NLL checking to
302+
/// grab the set of constraints that arose from a particular
303+
/// operation.
304+
///
305+
/// We don't want to leak relationships between variables between
306+
/// points because just because (say) `r1 == r2` was true at some
307+
/// point P in the graph doesn't imply that it will be true at
308+
/// some other point Q, in NLL.
301309
///
302310
/// Not legal during a snapshot.
303311
pub fn take_and_reset_data(&mut self) -> RegionConstraintData<'tcx> {
304-
mem::replace(&mut self.data, RegionConstraintData::default())
312+
assert!(!self.in_snapshot());
313+
314+
// If you add a new field to `RegionConstraintCollector`, you
315+
// should think carefully about whether it needs to be cleared
316+
// or updated in some way.
317+
let RegionConstraintCollector {
318+
var_origins,
319+
data,
320+
lubs,
321+
glbs,
322+
skolemization_count,
323+
bound_count: _,
324+
undo_log: _,
325+
unification_table,
326+
} = self;
327+
328+
assert_eq!(*skolemization_count, 0);
329+
330+
// Clear the tables of (lubs, glbs), so that we will create
331+
// fresh regions if we do a LUB operation. As it happens,
332+
// LUB/GLB are not performed by the MIR type-checker, which is
333+
// the one that uses this method, but it's good to be correct.
334+
lubs.clear();
335+
glbs.clear();
336+
337+
// Clear all unifications and recreate the variables a "now
338+
// un-unified" state. Note that when we unify `a` and `b`, we
339+
// also insert `a <= b` and a `b <= a` edges, so the
340+
// `RegionConstraintData` contains the relationship here.
341+
*unification_table = UnificationTable::new();
342+
for vid in var_origins.indices() {
343+
unification_table.new_key(unify_key::RegionVidKey { min_vid: vid });
344+
}
345+
346+
mem::replace(data, RegionConstraintData::default())
305347
}
306348

307349
fn in_snapshot(&self) -> bool {
@@ -904,7 +946,11 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
904946
impl<'tcx> RegionConstraintData<'tcx> {
905947
/// True if this region constraint data contains no constraints.
906948
pub fn is_empty(&self) -> bool {
907-
let RegionConstraintData { constraints, verifys, givens } = self;
949+
let RegionConstraintData {
950+
constraints,
951+
verifys,
952+
givens,
953+
} = self;
908954
constraints.is_empty() && verifys.is_empty() && givens.is_empty()
909955
}
910956
}

0 commit comments

Comments
 (0)