1111//! See README.md
1212
1313use self :: CombineMapType :: * ;
14- use self :: UndoLogEntry :: * ;
14+ use self :: UndoLog :: * ;
1515
1616use super :: unify_key;
1717use super :: { MiscVariable , RegionVariableOrigin , SubregionOrigin } ;
@@ -52,14 +52,17 @@ pub struct RegionConstraintCollector<'tcx> {
5252
5353 /// The undo log records actions that might later be undone.
5454 ///
55- /// Note: when the undo_log is empty, we are not actively
55+ /// Note: `num_open_snapshots` is used to track if we are actively
5656 /// snapshotting. When the `start_snapshot()` method is called, we
57- /// push an OpenSnapshot entry onto the list to indicate that we
58- /// are now actively snapshotting. The reason for this is that
59- /// otherwise we end up adding entries for things like the lower
60- /// bound on a variable and so forth, which can never be rolled
61- /// back.
62- undo_log : Vec < UndoLogEntry < ' tcx > > ,
57+ /// increment `num_open_snapshots` to indicate that we are now actively
58+ /// snapshotting. The reason for this is that otherwise we end up adding
59+ /// entries for things like the lower bound on a variable and so forth,
60+ /// which can never be rolled back.
61+ undo_log : Vec < UndoLog < ' tcx > > ,
62+
63+ /// The number of open snapshots, i.e. those that haven't been committed or
64+ /// rolled back.
65+ num_open_snapshots : usize ,
6366
6467 /// When we add a R1 == R2 constriant, we currently add (a) edges
6568 /// R1 <= R2 and R2 <= R1 and (b) we unify the two regions in this
@@ -254,15 +257,7 @@ struct TwoRegions<'tcx> {
254257}
255258
256259#[ derive( Copy , Clone , PartialEq ) ]
257- enum UndoLogEntry < ' tcx > {
258- /// Pushed when we start a snapshot.
259- OpenSnapshot ,
260-
261- /// Replaces an `OpenSnapshot` when a snapshot is committed, but
262- /// that snapshot is not the root. If the root snapshot is
263- /// unrolled, all nested snapshots must be committed.
264- CommitedSnapshot ,
265-
260+ enum UndoLog < ' tcx > {
266261 /// We added `RegionVid`
267262 AddVar ( RegionVid ) ,
268263
@@ -387,6 +382,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
387382 glbs,
388383 bound_count : _,
389384 undo_log : _,
385+ num_open_snapshots : _,
390386 unification_table,
391387 any_unifications,
392388 } = self ;
@@ -415,53 +411,60 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
415411 }
416412
417413 fn in_snapshot ( & self ) -> bool {
418- ! self . undo_log . is_empty ( )
414+ self . num_open_snapshots > 0
419415 }
420416
421417 pub fn start_snapshot ( & mut self ) -> RegionSnapshot {
422418 let length = self . undo_log . len ( ) ;
423419 debug ! ( "RegionConstraintCollector: start_snapshot({})" , length) ;
424- self . undo_log . push ( OpenSnapshot ) ;
420+ self . num_open_snapshots += 1 ;
425421 RegionSnapshot {
426422 length,
427423 region_snapshot : self . unification_table . snapshot ( ) ,
428424 any_unifications : self . any_unifications ,
429425 }
430426 }
431427
428+ fn assert_open_snapshot ( & self , snapshot : & RegionSnapshot ) {
429+ assert ! ( self . undo_log. len( ) >= snapshot. length) ;
430+ assert ! ( self . num_open_snapshots > 0 ) ;
431+ }
432+
432433 pub fn commit ( & mut self , snapshot : RegionSnapshot ) {
433434 debug ! ( "RegionConstraintCollector: commit({})" , snapshot. length) ;
434- assert ! ( self . undo_log. len( ) > snapshot. length) ;
435- assert ! ( self . undo_log[ snapshot. length] == OpenSnapshot ) ;
435+ self . assert_open_snapshot ( & snapshot) ;
436436
437- if snapshot. length == 0 {
437+ if self . num_open_snapshots == 1 {
438+ // The root snapshot. It's safe to clear the undo log because
439+ // there's no snapshot further out that we might need to roll back
440+ // to.
441+ assert ! ( snapshot. length == 0 ) ;
438442 self . undo_log . clear ( ) ;
439- } else {
440- ( * self . undo_log ) [ snapshot. length ] = CommitedSnapshot ;
441443 }
444+
445+ self . num_open_snapshots -= 1 ;
446+
442447 self . unification_table . commit ( snapshot. region_snapshot ) ;
443448 }
444449
445450 pub fn rollback_to ( & mut self , snapshot : RegionSnapshot ) {
446451 debug ! ( "RegionConstraintCollector: rollback_to({:?})" , snapshot) ;
447- assert ! ( self . undo_log . len ( ) > snapshot. length ) ;
448- assert ! ( self . undo_log [ snapshot . length ] == OpenSnapshot ) ;
449- while self . undo_log . len ( ) > snapshot. length + 1 {
452+ self . assert_open_snapshot ( & snapshot) ;
453+
454+ while self . undo_log . len ( ) > snapshot. length {
450455 let undo_entry = self . undo_log . pop ( ) . unwrap ( ) ;
451456 self . rollback_undo_entry ( undo_entry) ;
452457 }
453- let c = self . undo_log . pop ( ) . unwrap ( ) ;
454- assert ! ( c == OpenSnapshot ) ;
458+
459+ self . num_open_snapshots -= 1 ;
460+
455461 self . unification_table . rollback_to ( snapshot. region_snapshot ) ;
456462 self . any_unifications = snapshot. any_unifications ;
457463 }
458464
459- fn rollback_undo_entry ( & mut self , undo_entry : UndoLogEntry < ' tcx > ) {
465+ fn rollback_undo_entry ( & mut self , undo_entry : UndoLog < ' tcx > ) {
460466 match undo_entry {
461- OpenSnapshot => {
462- panic ! ( "Failure to observe stack discipline" ) ;
463- }
464- Purged | CommitedSnapshot => {
467+ Purged => {
465468 // nothing to do here
466469 }
467470 AddVar ( vid) => {
@@ -521,15 +524,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
521524 /// in `skols`. This is used after a higher-ranked operation
522525 /// completes to remove all trace of the placeholder regions
523526 /// created in that time.
524- pub fn pop_placeholders (
525- & mut self ,
526- placeholders : & FxHashSet < ty:: Region < ' tcx > > ,
527- snapshot : & RegionSnapshot ,
528- ) {
527+ pub fn pop_placeholders ( & mut self , placeholders : & FxHashSet < ty:: Region < ' tcx > > ) {
529528 debug ! ( "pop_placeholders(placeholders={:?})" , placeholders) ;
530529
531530 assert ! ( self . in_snapshot( ) ) ;
532- assert ! ( self . undo_log[ snapshot. length] == OpenSnapshot ) ;
533531
534532 let constraints_to_kill: Vec < usize > = self . undo_log
535533 . iter ( )
@@ -548,7 +546,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
548546
549547 fn kill_constraint < ' tcx > (
550548 placeholders : & FxHashSet < ty:: Region < ' tcx > > ,
551- undo_entry : & UndoLogEntry < ' tcx > ,
549+ undo_entry : & UndoLog < ' tcx > ,
552550 ) -> bool {
553551 match undo_entry {
554552 & AddConstraint ( Constraint :: VarSubVar ( ..) ) => false ,
@@ -562,7 +560,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
562560 & AddCombination ( _, ref two_regions) => {
563561 placeholders. contains ( & two_regions. a ) || placeholders. contains ( & two_regions. b )
564562 }
565- & AddVar ( ..) | & OpenSnapshot | & Purged | & CommitedSnapshot => false ,
563+ & AddVar ( ..) | & Purged => false ,
566564 }
567565 }
568566 }
0 commit comments