Skip to content

Commit 94967ae

Browse files
committed
Remove OpenSnapshot and CommittedSnapshot markers from RegionConstraintCollector.
They're not strictly necessary, and they result in the `Vec` being allocated even for the trivial (and common) case where a `start_snapshot` is immediately followed by a `commit` or `rollback_to`. The commit also removes a now-unnecessary argument of `pop_placeholders()`.
1 parent 2d68fa0 commit 94967ae

File tree

3 files changed

+32
-42
lines changed

3 files changed

+32
-42
lines changed

src/librustc/infer/higher_ranked/mod.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -543,11 +543,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
543543
) {
544544
debug!("pop_placeholders({:?})", placeholder_map);
545545
let placeholder_regions: FxHashSet<_> = placeholder_map.values().cloned().collect();
546-
self.borrow_region_constraints()
547-
.pop_placeholders(
548-
&placeholder_regions,
549-
&snapshot.region_constraints_snapshot,
550-
);
546+
self.borrow_region_constraints().pop_placeholders(&placeholder_regions);
551547
self.universe.set(snapshot.universe);
552548
if !placeholder_map.is_empty() {
553549
self.projection_cache.borrow_mut().rollback_placeholder(

src/librustc/infer/region_constraints/mod.rs

+30-35
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,18 @@ 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.
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.
6261
undo_log: Vec<UndoLog<'tcx>>,
6362

63+
/// The number of open snapshots, i.e. those that haven't been committed or
64+
/// rolled back.
65+
num_open_snapshots: usize,
66+
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
6669
/// table. You can then call `opportunistic_resolve_var` early
@@ -255,14 +258,6 @@ struct TwoRegions<'tcx> {
255258

256259
#[derive(Copy, Clone, PartialEq)]
257260
enum UndoLog<'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-
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,13 +411,13 @@ 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(),
@@ -430,41 +426,45 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
430426
}
431427

432428
fn assert_open_snapshot(&self, snapshot: &RegionSnapshot) {
433-
assert!(self.undo_log.len() > snapshot.length);
434-
assert!(self.undo_log[snapshot.length] == OpenSnapshot);
429+
assert!(self.undo_log.len() >= snapshot.length);
430+
assert!(self.num_open_snapshots > 0);
435431
}
436432

437433
pub fn commit(&mut self, snapshot: RegionSnapshot) {
438434
debug!("RegionConstraintCollector: commit({})", snapshot.length);
439435
self.assert_open_snapshot(&snapshot);
440436

441-
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);
442442
self.undo_log.clear();
443-
} else {
444-
(*self.undo_log)[snapshot.length] = CommitedSnapshot;
445443
}
444+
445+
self.num_open_snapshots -= 1;
446+
446447
self.unification_table.commit(snapshot.region_snapshot);
447448
}
448449

449450
pub fn rollback_to(&mut self, snapshot: RegionSnapshot) {
450451
debug!("RegionConstraintCollector: rollback_to({:?})", snapshot);
451452
self.assert_open_snapshot(&snapshot);
452-
while self.undo_log.len() > snapshot.length + 1 {
453+
454+
while self.undo_log.len() > snapshot.length {
453455
let undo_entry = self.undo_log.pop().unwrap();
454456
self.rollback_undo_entry(undo_entry);
455457
}
456-
let c = self.undo_log.pop().unwrap();
457-
assert!(c == OpenSnapshot);
458+
459+
self.num_open_snapshots -= 1;
460+
458461
self.unification_table.rollback_to(snapshot.region_snapshot);
459462
self.any_unifications = snapshot.any_unifications;
460463
}
461464

462465
fn rollback_undo_entry(&mut self, undo_entry: UndoLog<'tcx>) {
463466
match undo_entry {
464-
OpenSnapshot => {
465-
panic!("Failure to observe stack discipline");
466-
}
467-
Purged | CommitedSnapshot => {
467+
Purged => {
468468
// nothing to do here
469469
}
470470
AddVar(vid) => {
@@ -524,15 +524,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
524524
/// in `skols`. This is used after a higher-ranked operation
525525
/// completes to remove all trace of the placeholder regions
526526
/// created in that time.
527-
pub fn pop_placeholders(
528-
&mut self,
529-
placeholders: &FxHashSet<ty::Region<'tcx>>,
530-
snapshot: &RegionSnapshot,
531-
) {
527+
pub fn pop_placeholders(&mut self, placeholders: &FxHashSet<ty::Region<'tcx>>) {
532528
debug!("pop_placeholders(placeholders={:?})", placeholders);
533529

534530
assert!(self.in_snapshot());
535-
assert!(self.undo_log[snapshot.length] == OpenSnapshot);
536531

537532
let constraints_to_kill: Vec<usize> = self.undo_log
538533
.iter()
@@ -565,7 +560,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
565560
&AddCombination(_, ref two_regions) => {
566561
placeholders.contains(&two_regions.a) || placeholders.contains(&two_regions.b)
567562
}
568-
&AddVar(..) | &OpenSnapshot | &Purged | &CommitedSnapshot => false,
563+
&AddVar(..) | &Purged => false,
569564
}
570565
}
571566
}

src/librustc/infer/region_constraints/taint.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ impl<'tcx> TaintSet<'tcx> {
6565
"we never add verifications while doing higher-ranked things",
6666
)
6767
}
68-
&Purged | &AddCombination(..) | &AddVar(..) | &OpenSnapshot
69-
| &CommitedSnapshot => {}
68+
&Purged | &AddCombination(..) | &AddVar(..) => {}
7069
}
7170
}
7271
}

0 commit comments

Comments
 (0)