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);
|
debug!("pop_skolemized({:?})", skol_map);
|
||||||
let skol_regions: FnvHashSet<_> = skol_map.values().cloned().collect();
|
let skol_regions: FnvHashSet<_> = skol_map.values().cloned().collect();
|
||||||
self.region_vars.pop_skolemized(&skol_regions, &snapshot.region_vars_snapshot);
|
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);
|
infcx.skolemize_late_bound_regions(&obligation.predicate, snapshot);
|
||||||
|
|
||||||
let skol_obligation = obligation.with(skol_predicate);
|
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) => {
|
Ok(result) => {
|
||||||
let span = obligation.cause.span;
|
let span = obligation.cause.span;
|
||||||
match infcx.leak_check(false, span, &skol_map, snapshot) {
|
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) => {
|
||||||
Err(e)
|
Err(e)
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
r
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1396,6 +1398,10 @@ impl<'tcx> ProjectionCache<'tcx> {
|
||||||
self.map.rollback_to(snapshot.snapshot);
|
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) {
|
pub fn commit(&mut self, snapshot: ProjectionCacheSnapshot) {
|
||||||
self.map.commit(snapshot.snapshot);
|
self.map.commit(snapshot.snapshot);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
@ -31,6 +32,7 @@ enum UndoLog<K, V> {
|
||||||
CommittedSnapshot,
|
CommittedSnapshot,
|
||||||
Inserted(K),
|
Inserted(K),
|
||||||
Overwrite(K, V),
|
Overwrite(K, V),
|
||||||
|
Noop,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V> SnapshotMap<K, V>
|
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) {
|
pub fn rollback_to(&mut self, snapshot: Snapshot) {
|
||||||
self.assert_open_snapshot(&snapshot);
|
self.assert_open_snapshot(&snapshot);
|
||||||
while self.undo_log.len() > snapshot.len + 1 {
|
while self.undo_log.len() > snapshot.len + 1 {
|
||||||
match self.undo_log.pop().unwrap() {
|
let entry = self.undo_log.pop().unwrap();
|
||||||
UndoLog::OpenSnapshot => {
|
self.reverse(entry);
|
||||||
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 v = self.undo_log.pop().unwrap();
|
let v = self.undo_log.pop().unwrap();
|
||||||
|
@ -127,6 +134,26 @@ impl<K, V> SnapshotMap<K, V>
|
||||||
});
|
});
|
||||||
assert!(self.undo_log.len() == snapshot.len);
|
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>
|
impl<'k, K, V> ops::Index<&'k K> for SnapshotMap<K, V>
|
||||||
|
|
Loading…
Reference in New Issue