when pop skol, also remove from proj cache
This commit is contained in:
parent
da5b6467c3
commit
974817d493
|
@ -839,5 +839,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
debug!("pop_skolemized({:?})", skol_map);
|
||||
let skol_regions: FnvHashSet<_> = skol_map.values().cloned().collect();
|
||||
self.region_vars.pop_skolemized(&skol_regions, &snapshot.region_vars_snapshot);
|
||||
self.projection_cache.borrow_mut().partial_rollback(&snapshot.projection_cache_snapshot);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>(
|
|||
infcx.skolemize_late_bound_regions(&obligation.predicate, snapshot);
|
||||
|
||||
let skol_obligation = obligation.with(skol_predicate);
|
||||
match project_and_unify_type(selcx, &skol_obligation) {
|
||||
let r = match project_and_unify_type(selcx, &skol_obligation) {
|
||||
Ok(result) => {
|
||||
let span = obligation.cause.span;
|
||||
match infcx.leak_check(false, span, &skol_map, snapshot) {
|
||||
|
@ -178,7 +178,9 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>(
|
|||
Err(e) => {
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
r
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1396,6 +1398,10 @@ impl<'tcx> ProjectionCache<'tcx> {
|
|||
self.map.rollback_to(snapshot.snapshot);
|
||||
}
|
||||
|
||||
pub fn partial_rollback(&mut self, snapshot: &ProjectionCacheSnapshot) {
|
||||
self.map.partial_rollback(&snapshot.snapshot);
|
||||
}
|
||||
|
||||
pub fn commit(&mut self, snapshot: ProjectionCacheSnapshot) {
|
||||
self.map.commit(snapshot.snapshot);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue