diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2016-09-13 18:31:26 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2016-09-14 11:04:39 -0400 |
| commit | 6353e30bb2d7968332217c04ac25e0800500fb33 (patch) | |
| tree | cb7e73aa0816f4ad143ccf54adf1cbe4e74e3830 /src/librustc/traits | |
| parent | c87ba3f1222ba20d491e8ed76a04977283280742 (diff) | |
| download | rust-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.rs | 46 |
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 { |
