@@ -296,12 +296,54 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
296
296
( self . var_origins , self . data )
297
297
}
298
298
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.
301
309
///
302
310
/// Not legal during a snapshot.
303
311
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 ( ) )
305
347
}
306
348
307
349
fn in_snapshot ( & self ) -> bool {
@@ -904,7 +946,11 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
904
946
impl < ' tcx > RegionConstraintData < ' tcx > {
905
947
/// True if this region constraint data contains no constraints.
906
948
pub fn is_empty ( & self ) -> bool {
907
- let RegionConstraintData { constraints, verifys, givens } = self ;
949
+ let RegionConstraintData {
950
+ constraints,
951
+ verifys,
952
+ givens,
953
+ } = self ;
908
954
constraints. is_empty ( ) && verifys. is_empty ( ) && givens. is_empty ( )
909
955
}
910
956
}
0 commit comments