]> git.lizzy.rs Git - rust.git/commitdiff
introduce ProvisionalEvaluationCache
authorNiko Matsakis <niko@alum.mit.edu>
Mon, 10 Jun 2019 19:36:38 +0000 (15:36 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Wed, 12 Jun 2019 17:56:28 +0000 (13:56 -0400)
src/librustc/traits/select.rs

index 8725c6bb718115528888a9a31c4f83a91cad1f9f..1de248378bdf52d3350b58076d2dc3211ac7b044 100644 (file)
@@ -606,7 +606,8 @@ pub fn select(
         debug!("select({:?})", obligation);
         debug_assert!(!obligation.predicate.has_escaping_bound_vars());
 
-        let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
+        let pec = &ProvisionalEvaluationCache::default();
+        let stack = self.push_stack(TraitObligationStackList::empty(pec), obligation);
 
         let candidate = match self.candidate_from_obligation(&stack) {
             Err(SelectionError::Overflow) => {
@@ -666,7 +667,7 @@ pub fn evaluate_root_obligation(
     ) -> Result<EvaluationResult, OverflowError> {
         self.evaluation_probe(|this| {
             this.evaluate_predicate_recursively(
-                TraitObligationStackList::empty(),
+                TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
                 obligation.clone(),
             )
         })
@@ -3968,6 +3969,10 @@ fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> {
         TraitObligationStackList::with(self)
     }
 
+    fn cache(&self) -> &'o ProvisionalEvaluationCache<'tcx> {
+        self.previous.cache
+    }
+
     fn iter(&'o self) -> TraitObligationStackList<'o, 'tcx> {
         self.list()
     }
@@ -3992,18 +3997,24 @@ fn update_reached_depth(&self, reached_depth: usize) {
     }
 }
 
+#[derive(Default)]
+struct ProvisionalEvaluationCache<'tcx> {
+    _dummy: Vec<&'tcx ()>,
+}
+
 #[derive(Copy, Clone)]
 struct TraitObligationStackList<'o, 'tcx: 'o> {
+    cache: &'o ProvisionalEvaluationCache<'tcx>,
     head: Option<&'o TraitObligationStack<'o, 'tcx>>,
 }
 
 impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> {
-    fn empty() -> TraitObligationStackList<'o, 'tcx> {
-        TraitObligationStackList { head: None }
+    fn empty(cache: &'o ProvisionalEvaluationCache<'tcx>) -> TraitObligationStackList<'o, 'tcx> {
+        TraitObligationStackList { cache, head: None }
     }
 
     fn with(r: &'o TraitObligationStack<'o, 'tcx>) -> TraitObligationStackList<'o, 'tcx> {
-        TraitObligationStackList { head: Some(r) }
+        TraitObligationStackList { cache: r.cache(), head: Some(r) }
     }
 
     fn head(&self) -> Option<&'o TraitObligationStack<'o, 'tcx>> {