/// inference variables and applies it to the canonical value.
/// Returns both the instantiated result *and* the substitution S.
///
- /// This is useful at the start of a query: it basically brings
- /// the canonical value "into scope" within your new infcx. At the
- /// end of processing, the substitution S (once canonicalized)
- /// then represents the values that you computed for each of the
- /// canonical inputs to your query.
- pub fn instantiate_canonical_with_fresh_inference_vars<T>(
+ /// This is only meant to be invoked as part of constructing an
+ /// inference context at the start of a query (see
+ /// `InferCtxtBuilder::enter_with_canonical`). It basically
+ /// brings the canonical value "into scope" within your new infcx.
+ ///
+ /// At the end of processing, the substitution S (once
+ /// canonicalized) then represents the values that you computed
+ /// for each of the canonical inputs to your query.
+
+ pub(in infer) fn instantiate_canonical_with_fresh_inference_vars<T>(
&self,
span: Span,
canonical: &Canonical<'tcx, T>,
where
T: TypeFoldable<'tcx>,
{
+ assert_eq!(self.universe(), ty::UniverseIndex::ROOT, "infcx not newly created");
+ assert_eq!(self.type_variables.borrow().num_vars(), 0, "infcx not newly created");
+
let canonical_inference_vars =
self.fresh_inference_vars_for_canonical_vars(span, canonical.variables);
let result = canonical.substitute(self.tcx, &canonical_inference_vars);
K: TypeFoldable<'tcx>,
R: Debug + Lift<'gcx> + TypeFoldable<'tcx>,
{
- self.enter(|ref infcx| {
- let (key, canonical_inference_vars) =
- infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_key);
+ self.enter_with_canonical(DUMMY_SP, canonical_key, |ref infcx, key, canonical_inference_vars| {
let fulfill_cx = &mut FulfillmentContext::new();
let value = operation(infcx, fulfill_cx, key)?;
infcx.make_canonicalized_query_result(canonical_inference_vars, value, fulfill_cx)
use arena::SyncDroplessArena;
use errors::DiagnosticBuilder;
use hir::def_id::DefId;
+use infer::canonical::{Canonical, CanonicalVarValues};
use middle::free_region::RegionRelations;
use middle::lang_items;
use middle::region;
self
}
- pub fn enter<F, R>(&'tcx mut self, f: F) -> R
+ /// Given a canonical value `C` as a starting point, create an
+ /// inference context that contains each of the bound values
+ /// within instantiated as a fresh variable. The `f` closure is
+ /// invoked with the new infcx, along with the instantiated value
+ /// `V` and a substitution `S`. This substitution `S` maps from
+ /// the bound values in `C` to their instantiated values in `V`
+ /// (in other words, `S(C) = V`).
+ pub fn enter_with_canonical<T, R>(
+ &'tcx mut self,
+ span: Span,
+ canonical: &Canonical<'tcx, T>,
+ f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>, T, CanonicalVarValues<'tcx>) -> R,
+ ) -> R
where
- F: for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R,
+ T: TypeFoldable<'tcx>,
+ {
+ self.enter(|infcx| {
+ let (value, subst) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
+ f(infcx, value, subst)
+ })
+ }
+
+ pub fn enter<R>(&'tcx mut self, f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R) -> R
{
let InferCtxtBuilder {
global_tcx,
fn dropck_outlives<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
- goal: CanonicalTyGoal<'tcx>,
+ canonical_goal: CanonicalTyGoal<'tcx>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, DropckOutlivesResult<'tcx>>>>, NoSolution> {
- debug!("dropck_outlives(goal={:#?})", goal);
+ debug!("dropck_outlives(goal={:#?})", canonical_goal);
- tcx.infer_ctxt().enter(|ref infcx| {
+ tcx.infer_ctxt().enter_with_canonical(DUMMY_SP, &canonical_goal, |ref infcx, goal, canonical_inference_vars| {
let tcx = infcx.tcx;
- let (
- ParamEnvAnd {
- param_env,
- value: for_ty,
- },
- canonical_inference_vars,
- ) = infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &goal);
+ let ParamEnvAnd {
+ param_env,
+ value: for_ty,
+ } = goal;
let mut result = DropckOutlivesResult {
kinds: vec![],
fn evaluate_obligation<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
- goal: CanonicalPredicateGoal<'tcx>,
+ canonical_goal: CanonicalPredicateGoal<'tcx>,
) -> Result<EvaluationResult, OverflowError> {
- tcx.infer_ctxt().enter(|ref infcx| {
- let (
- ParamEnvAnd {
- param_env,
- value: predicate,
- },
- _canonical_inference_vars,
- ) = infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &goal);
+ tcx.infer_ctxt().enter_with_canonical(DUMMY_SP, &canonical_goal, |ref infcx, goal, _canonical_inference_vars| {
+ let ParamEnvAnd {
+ param_env,
+ value: predicate,
+ } = goal;
let mut selcx = SelectionContext::with_query_mode(&infcx, TraitQueryMode::Canonical);
let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);