bundle up "canonical instantiation" with infcx creation
This commit is contained in:
parent
110b3b971e
commit
fd046a2ede
5 changed files with 50 additions and 30 deletions
|
|
@ -225,12 +225,16 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// 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>,
|
||||
|
|
@ -238,6 +242,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -64,9 +64,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxtBuilder<'cx, 'gcx, 'tcx> {
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ pub use ty::IntVarValue;
|
|||
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;
|
||||
|
|
@ -494,9 +495,29 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -30,19 +30,16 @@ crate fn provide(p: &mut Providers) {
|
|||
|
||||
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![],
|
||||
|
|
|
|||
|
|
@ -24,16 +24,13 @@ crate fn provide(p: &mut Providers) {
|
|||
|
||||
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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue