Remove save_and_restore_in_snapshot_flag
This commit is contained in:
parent
bdced83a2e
commit
ed6a7cc228
3 changed files with 25 additions and 53 deletions
|
@ -765,7 +765,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
let expect_args = self
|
||||
.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
|
||||
// return type (likely containing type variables if the function
|
||||
|
|
|
@ -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> {
|
||||
debug!("start_snapshot()");
|
||||
|
||||
|
|
|
@ -10,10 +10,12 @@
|
|||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html
|
||||
|
||||
pub mod specialization_graph;
|
||||
use rustc_infer::traits::{TraitEngine, TraitEngineExt as _};
|
||||
use specialization_graph::GraphExt;
|
||||
|
||||
use crate::errors::NegativePositiveConflict;
|
||||
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
||||
use crate::traits::engine::TraitEngineExt as _;
|
||||
use crate::traits::select::IntercrateAmbiguityCause;
|
||||
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
|
@ -200,36 +202,32 @@ fn fulfill_implication<'tcx>(
|
|||
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
|
||||
// (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 = traits::fully_solve_obligations(&infcx, obligations.chain(more_obligations));
|
||||
match &errors[..] {
|
||||
[] => {
|
||||
debug!(
|
||||
"fulfill_implication: an impl for {:?} specializes {:?}",
|
||||
source_trait, target_trait
|
||||
);
|
||||
let errors = engine.select_all_or_error(infcx);
|
||||
if !errors.is_empty() {
|
||||
// no dice!
|
||||
debug!(
|
||||
"fulfill_implication: for impls on {:?} and {:?}, \
|
||||
could not fulfill: {:?} given {:?}",
|
||||
source_trait,
|
||||
target_trait,
|
||||
errors,
|
||||
param_env.caller_bounds()
|
||||
);
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// 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!
|
||||
debug!(
|
||||
"fulfill_implication: for impls on {:?} and {:?}, \
|
||||
could not fulfill: {:?} given {:?}",
|
||||
source_trait,
|
||||
target_trait,
|
||||
errors,
|
||||
param_env.caller_bounds()
|
||||
);
|
||||
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`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue