1
Fork 0

Remove save_and_restore_in_snapshot_flag

This commit is contained in:
Michael Goulet 2022-11-09 18:47:39 +00:00
parent bdced83a2e
commit ed6a7cc228
3 changed files with 25 additions and 53 deletions

View file

@ -765,7 +765,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let expect_args = self let expect_args = self
.fudge_inference_if_ok(|| { .fudge_inference_if_ok(|| {
let ocx = ObligationCtxt::new(self); let ocx = ObligationCtxt::new_in_snapshot(self);
// Attempt to apply a subtyping relationship between the formal // Attempt to apply a subtyping relationship between the formal
// return type (likely containing type variables if the function // return type (likely containing type variables if the function

View file

@ -778,32 +778,6 @@ impl<'tcx> InferCtxt<'tcx> {
} }
} }
/// Clear the "currently in a snapshot" flag, invoke the closure,
/// then restore the flag to its original value. This flag is a
/// debugging measure designed to detect cases where we start a
/// snapshot, create type variables, and register obligations
/// which may involve those type variables in the fulfillment cx,
/// potentially leaving "dangling type variables" behind.
/// In such cases, an assertion will fail when attempting to
/// register obligations, within a snapshot. Very useful, much
/// better than grovelling through megabytes of `RUSTC_LOG` output.
///
/// HOWEVER, in some cases the flag is unhelpful. 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. In those cases, you can
/// use this function.
pub fn save_and_restore_in_snapshot_flag<F, R>(&self, func: F) -> R
where
F: FnOnce(&Self) -> R,
{
let flag = self.in_snapshot.replace(false);
let result = func(self);
self.in_snapshot.set(flag);
result
}
fn start_snapshot(&self) -> CombinedSnapshot<'tcx> { fn start_snapshot(&self) -> CombinedSnapshot<'tcx> {
debug!("start_snapshot()"); debug!("start_snapshot()");

View file

@ -10,10 +10,12 @@
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html
pub mod specialization_graph; pub mod specialization_graph;
use rustc_infer::traits::{TraitEngine, TraitEngineExt as _};
use specialization_graph::GraphExt; use specialization_graph::GraphExt;
use crate::errors::NegativePositiveConflict; use crate::errors::NegativePositiveConflict;
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use crate::traits::engine::TraitEngineExt as _;
use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause}; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
@ -200,23 +202,15 @@ fn fulfill_implication<'tcx>(
return Err(()); return Err(());
}; };
// Needs to be `in_snapshot` because this function is used to rebase
// substitutions, which may happen inside of a select within a probe.
let mut engine = <dyn TraitEngine<'tcx>>::new_in_snapshot(infcx.tcx);
// attempt to prove all of the predicates for impl2 given those for impl1 // attempt to prove all of the predicates for impl2 given those for impl1
// (which are packed up in penv) // (which are packed up in penv)
engine.register_predicate_obligations(infcx, obligations.chain(more_obligations));
infcx.save_and_restore_in_snapshot_flag(|infcx| { let errors = engine.select_all_or_error(infcx);
let errors = traits::fully_solve_obligations(&infcx, obligations.chain(more_obligations)); if !errors.is_empty() {
match &errors[..] {
[] => {
debug!(
"fulfill_implication: an impl for {:?} specializes {:?}",
source_trait, target_trait
);
// Now resolve the *substitution* we built for the target earlier, replacing
// the inference variables inside with whatever we got from fulfillment.
Ok(infcx.resolve_vars_if_possible(target_substs))
}
errors => {
// no dice! // no dice!
debug!( debug!(
"fulfill_implication: for impls on {:?} and {:?}, \ "fulfill_implication: for impls on {:?} and {:?}, \
@ -226,10 +220,14 @@ fn fulfill_implication<'tcx>(
errors, errors,
param_env.caller_bounds() param_env.caller_bounds()
); );
Err(()) return Err(());
} }
}
}) debug!("fulfill_implication: an impl for {:?} specializes {:?}", source_trait, target_trait);
// Now resolve the *substitution* we built for the target earlier, replacing
// the inference variables inside with whatever we got from fulfillment.
Ok(infcx.resolve_vars_if_possible(target_substs))
} }
// Query provider for `specialization_graph_of`. // Query provider for `specialization_graph_of`.