about summary refs log tree commit diff
path: root/src/librustc/traits
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-09-13 18:31:26 -0400
committerNiko Matsakis <niko@alum.mit.edu>2016-09-14 11:04:39 -0400
commit6353e30bb2d7968332217c04ac25e0800500fb33 (patch)
treecb7e73aa0816f4ad143ccf54adf1cbe4e74e3830 /src/librustc/traits
parentc87ba3f1222ba20d491e8ed76a04977283280742 (diff)
downloadrust-6353e30bb2d7968332217c04ac25e0800500fb33.tar.gz
rust-6353e30bb2d7968332217c04ac25e0800500fb33.zip
clear obligations-added flag with nested fulfillcx
This flag is a debugging measure designed to detect cases where we start
a snapshot, create type variables, register obligations involving those
type variables in the fulfillment cx, and then have to unroll the
snapshot, leaving "dangling type variables" behind.  HOWEVER, in some
cases the flag is wrong. In particular, we sometimes create a
"mini-fulfilment-cx" in which we enroll obligations. As long as this
fulfillment cx is fully drained before we return, this is not a problem,
as there won't be any escaping obligations in the main cx. So we add a
fn to save/restore the flag.
Diffstat (limited to 'src/librustc/traits')
-rw-r--r--src/librustc/traits/specialize/mod.rs46
1 files changed, 24 insertions, 22 deletions
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index f3ba4d16eb0..2f63526bf6c 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -203,32 +203,34 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
     // attempt to prove all of the predicates for impl2 given those for impl1
     // (which are packed up in penv)
 
-    let mut fulfill_cx = FulfillmentContext::new();
-    for oblig in obligations.into_iter() {
-        fulfill_cx.register_predicate_obligation(&infcx, oblig);
-    }
-    match fulfill_cx.select_all_or_error(infcx) {
-        Err(errors) => {
-            // no dice!
-            debug!("fulfill_implication: for impls on {:?} and {:?}, could not fulfill: {:?} given \
-                    {:?}",
-                   source_trait_ref,
-                   target_trait_ref,
-                   errors,
-                   infcx.parameter_environment.caller_bounds);
-            Err(())
+    infcx.save_and_restore_obligations_in_snapshot_flag(|infcx| {
+        let mut fulfill_cx = FulfillmentContext::new();
+        for oblig in obligations.into_iter() {
+            fulfill_cx.register_predicate_obligation(&infcx, oblig);
         }
+        match fulfill_cx.select_all_or_error(infcx) {
+            Err(errors) => {
+                // no dice!
+                debug!("fulfill_implication: for impls on {:?} and {:?}, \
+                        could not fulfill: {:?} given {:?}",
+                       source_trait_ref,
+                       target_trait_ref,
+                       errors,
+                       infcx.parameter_environment.caller_bounds);
+                Err(())
+            }
 
-        Ok(()) => {
-            debug!("fulfill_implication: an impl for {:?} specializes {:?}",
-                   source_trait_ref,
-                   target_trait_ref);
+            Ok(()) => {
+                debug!("fulfill_implication: an impl for {:?} specializes {:?}",
+                       source_trait_ref,
+                       target_trait_ref);
 
-            // Now resolve the *substitution* we built for the target earlier, replacing
-            // the inference variables inside with whatever we got from fulfillment.
-            Ok(infcx.resolve_type_vars_if_possible(&target_substs))
+                // Now resolve the *substitution* we built for the target earlier, replacing
+                // the inference variables inside with whatever we got from fulfillment.
+                Ok(infcx.resolve_type_vars_if_possible(&target_substs))
+            }
         }
-    }
+    })
 }
 
 pub struct SpecializesCache {