about summary refs log tree commit diff
path: root/src/librustc_data_structures/snapshot_map
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-10-18 21:32:31 -0400
committerNiko Matsakis <niko@alum.mit.edu>2016-10-21 11:13:34 -0400
commit974817d4932fd447f724c4527360a258952ffd48 (patch)
treeabf55340848ec3df65ca2773cbdd155dfc028a01 /src/librustc_data_structures/snapshot_map
parentda5b6467c33f7f86b4964b08b37726f7611a8f0c (diff)
downloadrust-974817d4932fd447f724c4527360a258952ffd48.tar.gz
rust-974817d4932fd447f724c4527360a258952ffd48.zip
when pop skol, also remove from proj cache
Diffstat (limited to 'src/librustc_data_structures/snapshot_map')
-rw-r--r--src/librustc_data_structures/snapshot_map/mod.rs57
1 files changed, 42 insertions, 15 deletions
diff --git a/src/librustc_data_structures/snapshot_map/mod.rs b/src/librustc_data_structures/snapshot_map/mod.rs
index 0306066d6e7..23a67b3bd93 100644
--- a/src/librustc_data_structures/snapshot_map/mod.rs
+++ b/src/librustc_data_structures/snapshot_map/mod.rs
@@ -11,6 +11,7 @@
 use fnv::FnvHashMap;
 use std::hash::Hash;
 use std::ops;
+use std::mem;
 
 #[cfg(test)]
 mod test;
@@ -31,6 +32,7 @@ enum UndoLog<K, V> {
     CommittedSnapshot,
     Inserted(K),
     Overwrite(K, V),
+    Noop,
 }
 
 impl<K, V> SnapshotMap<K, V>
@@ -100,24 +102,29 @@ impl<K, V> SnapshotMap<K, V>
         }
     }
 
+    pub fn partial_rollback(&mut self, snapshot: &Snapshot) {
+        self.assert_open_snapshot(snapshot);
+        for i in (snapshot.len + 1..self.undo_log.len()).rev() {
+            let reverse = match self.undo_log[i] {
+                UndoLog::OpenSnapshot => false,
+                UndoLog::CommittedSnapshot => false,
+                UndoLog::Noop => false,
+                UndoLog::Inserted(..) => true,
+                UndoLog::Overwrite(..) => true,
+            };
+
+            if reverse {
+                let entry = mem::replace(&mut self.undo_log[i], UndoLog::Noop);
+                self.reverse(entry);
+            }
+        }
+    }
+
     pub fn rollback_to(&mut self, snapshot: Snapshot) {
         self.assert_open_snapshot(&snapshot);
         while self.undo_log.len() > snapshot.len + 1 {
-            match self.undo_log.pop().unwrap() {
-                UndoLog::OpenSnapshot => {
-                    panic!("cannot rollback an uncommitted snapshot");
-                }
-
-                UndoLog::CommittedSnapshot => {}
-
-                UndoLog::Inserted(key) => {
-                    self.map.remove(&key);
-                }
-
-                UndoLog::Overwrite(key, old_value) => {
-                    self.map.insert(key, old_value);
-                }
-            }
+            let entry = self.undo_log.pop().unwrap();
+            self.reverse(entry);
         }
 
         let v = self.undo_log.pop().unwrap();
@@ -127,6 +134,26 @@ impl<K, V> SnapshotMap<K, V>
         });
         assert!(self.undo_log.len() == snapshot.len);
     }
+
+    fn reverse(&mut self, entry: UndoLog<K, V>) {
+        match entry {
+            UndoLog::OpenSnapshot => {
+                panic!("cannot rollback an uncommitted snapshot");
+            }
+
+            UndoLog::CommittedSnapshot => {}
+
+            UndoLog::Inserted(key) => {
+                self.map.remove(&key);
+            }
+
+            UndoLog::Overwrite(key, old_value) => {
+                self.map.insert(key, old_value);
+            }
+
+            UndoLog::Noop => {}
+        }
+    }
 }
 
 impl<'k, K, V> ops::Index<&'k K> for SnapshotMap<K, V>