Skip to content

Commit 4477b07

Browse files
Add snapshotting to ObligationForest
1 parent 7fce503 commit 4477b07

File tree

5 files changed

+587
-67
lines changed

5 files changed

+587
-67
lines changed

src/librustc/middle/traits/fulfill.rs

+45-5
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
use dep_graph::DepGraph;
1212
use middle::infer::InferCtxt;
1313
use middle::ty::{self, Ty, TypeFoldable};
14-
use rustc_data_structures::obligation_forest::{Backtrace, ObligationForest, Error};
14+
use rustc_data_structures::obligation_forest::{Backtrace, ObligationForest, UndoLog, Error};
15+
use rustc_data_structures::undoable::{Undoable, UndoableTracker, Undoer};
16+
use std::cell::RefCell;
1517
use std::iter;
18+
use std::rc::Rc;
1619
use syntax::ast;
1720
use util::common::ErrorReported;
1821
use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
@@ -31,14 +34,18 @@ use super::select::SelectionContext;
3134
use super::Unimplemented;
3235
use super::util::predicate_for_builtin_bound;
3336

37+
pub type ObligationForestUndoLog<'tcx> = UndoLog<PendingPredicateObligation<'tcx>,
38+
LocalFulfilledPredicates<'tcx>>;
39+
3440
pub struct GlobalFulfilledPredicates<'tcx> {
3541
set: FnvHashSet<ty::PolyTraitPredicate<'tcx>>,
3642
dep_graph: DepGraph,
3743
}
3844

39-
#[derive(Debug)]
45+
#[derive(Debug, Clone)]
4046
pub struct LocalFulfilledPredicates<'tcx> {
41-
set: FnvHashSet<ty::Predicate<'tcx>>
47+
set: FnvHashSet<ty::Predicate<'tcx>>,
48+
log: Option<(Rc<RefCell<ObligationForestUndoLog<'tcx>>>, usize)>,
4249
}
4350

4451
/// The fulfillment context is used to drive trait resolution. It
@@ -110,6 +117,12 @@ pub struct PendingPredicateObligation<'tcx> {
110117
pub stalled_on: Vec<Ty<'tcx>>,
111118
}
112119

120+
#[derive(Debug)]
121+
pub enum LocalFulfilledPredicatesAction<'tcx> {
122+
Add { key: ty::Predicate<'tcx> }
123+
}
124+
125+
113126
impl<'tcx> FulfillmentContext<'tcx> {
114127
/// Creates a new fulfillment context.
115128
pub fn new() -> FulfillmentContext<'tcx> {
@@ -670,19 +683,46 @@ fn register_region_obligation<'tcx>(t_a: Ty<'tcx>,
670683
impl<'tcx> LocalFulfilledPredicates<'tcx> {
671684
pub fn new() -> LocalFulfilledPredicates<'tcx> {
672685
LocalFulfilledPredicates {
673-
set: FnvHashSet()
686+
set: FnvHashSet(),
687+
log: None,
674688
}
675689
}
676690

677691
fn is_duplicate_or_add(&mut self, key: &ty::Predicate<'tcx>) -> bool {
692+
let insert_result = self.set.insert(key.clone());
693+
if insert_result {
694+
if let Some((ref log, id)) = self.log {
695+
(*log).borrow_mut().push_action(
696+
id, LocalFulfilledPredicatesAction::Add { key: key.clone() });
697+
}
698+
}
678699
// For a `LocalFulfilledPredicates`, if we find a match, we
679700
// don't need to add a read edge to the dep-graph. This is
680701
// because it means that the predicate has already been
681702
// considered by this `FulfillmentContext`, and hence the
682703
// containing task will already have an edge. (Here we are
683704
// assuming each `FulfillmentContext` only gets used from one
684705
// task; but to do otherwise makes no sense)
685-
!self.set.insert(key.clone())
706+
!insert_result
707+
}
708+
}
709+
710+
impl<'tcx> Undoer for LocalFulfilledPredicatesAction<'tcx> {
711+
type Undoable = LocalFulfilledPredicates<'tcx>;
712+
fn undo(self, predicates: &mut LocalFulfilledPredicates<'tcx>) {
713+
match self {
714+
LocalFulfilledPredicatesAction::Add { key } => {
715+
assert!(predicates.set.remove(&key));
716+
}
717+
}
718+
}
719+
}
720+
721+
impl<'tcx> Undoable for LocalFulfilledPredicates<'tcx> {
722+
type Undoer = LocalFulfilledPredicatesAction<'tcx>;
723+
type Tracker = ObligationForestUndoLog<'tcx>;
724+
fn register_tracker(&mut self, log: Rc<RefCell<Self::Tracker>>, id: usize) {
725+
self.log = Some((log, id));
686726
}
687727
}
688728

src/librustc_data_structures/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub mod transitive_relation;
4444
pub mod unify;
4545
pub mod fnv;
4646
pub mod tuple_slice;
47+
pub mod undoable;
4748
pub mod veccell;
4849

4950
// See comments in src/librustc/lib.rs

0 commit comments

Comments
 (0)