Skip to content

Commit fd046a2

Browse files
committed
bundle up "canonical instantiation" with infcx creation
1 parent 110b3b9 commit fd046a2

File tree

5 files changed

+50
-30
lines changed

5 files changed

+50
-30
lines changed

src/librustc/infer/canonical/mod.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,19 +225,26 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
225225
/// inference variables and applies it to the canonical value.
226226
/// Returns both the instantiated result *and* the substitution S.
227227
///
228-
/// This is useful at the start of a query: it basically brings
229-
/// the canonical value "into scope" within your new infcx. At the
230-
/// end of processing, the substitution S (once canonicalized)
231-
/// then represents the values that you computed for each of the
232-
/// canonical inputs to your query.
233-
pub fn instantiate_canonical_with_fresh_inference_vars<T>(
228+
/// This is only meant to be invoked as part of constructing an
229+
/// inference context at the start of a query (see
230+
/// `InferCtxtBuilder::enter_with_canonical`). It basically
231+
/// brings the canonical value "into scope" within your new infcx.
232+
///
233+
/// At the end of processing, the substitution S (once
234+
/// canonicalized) then represents the values that you computed
235+
/// for each of the canonical inputs to your query.
236+
237+
pub(in infer) fn instantiate_canonical_with_fresh_inference_vars<T>(
234238
&self,
235239
span: Span,
236240
canonical: &Canonical<'tcx, T>,
237241
) -> (T, CanonicalVarValues<'tcx>)
238242
where
239243
T: TypeFoldable<'tcx>,
240244
{
245+
assert_eq!(self.universe(), ty::UniverseIndex::ROOT, "infcx not newly created");
246+
assert_eq!(self.type_variables.borrow().num_vars(), 0, "infcx not newly created");
247+
241248
let canonical_inference_vars =
242249
self.fresh_inference_vars_for_canonical_vars(span, canonical.variables);
243250
let result = canonical.substitute(self.tcx, &canonical_inference_vars);

src/librustc/infer/canonical/query_result.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxtBuilder<'cx, 'gcx, 'tcx> {
6464
K: TypeFoldable<'tcx>,
6565
R: Debug + Lift<'gcx> + TypeFoldable<'tcx>,
6666
{
67-
self.enter(|ref infcx| {
68-
let (key, canonical_inference_vars) =
69-
infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_key);
67+
self.enter_with_canonical(DUMMY_SP, canonical_key, |ref infcx, key, canonical_inference_vars| {
7068
let fulfill_cx = &mut FulfillmentContext::new();
7169
let value = operation(infcx, fulfill_cx, key)?;
7270
infcx.make_canonicalized_query_result(canonical_inference_vars, value, fulfill_cx)

src/librustc/infer/mod.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub use ty::IntVarValue;
2020
use arena::SyncDroplessArena;
2121
use errors::DiagnosticBuilder;
2222
use hir::def_id::DefId;
23+
use infer::canonical::{Canonical, CanonicalVarValues};
2324
use middle::free_region::RegionRelations;
2425
use middle::lang_items;
2526
use middle::region;
@@ -494,9 +495,29 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
494495
self
495496
}
496497

497-
pub fn enter<F, R>(&'tcx mut self, f: F) -> R
498+
/// Given a canonical value `C` as a starting point, create an
499+
/// inference context that contains each of the bound values
500+
/// within instantiated as a fresh variable. The `f` closure is
501+
/// invoked with the new infcx, along with the instantiated value
502+
/// `V` and a substitution `S`. This substitution `S` maps from
503+
/// the bound values in `C` to their instantiated values in `V`
504+
/// (in other words, `S(C) = V`).
505+
pub fn enter_with_canonical<T, R>(
506+
&'tcx mut self,
507+
span: Span,
508+
canonical: &Canonical<'tcx, T>,
509+
f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>, T, CanonicalVarValues<'tcx>) -> R,
510+
) -> R
498511
where
499-
F: for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R,
512+
T: TypeFoldable<'tcx>,
513+
{
514+
self.enter(|infcx| {
515+
let (value, subst) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
516+
f(infcx, value, subst)
517+
})
518+
}
519+
520+
pub fn enter<R>(&'tcx mut self, f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R) -> R
500521
{
501522
let InferCtxtBuilder {
502523
global_tcx,

src/librustc_traits/dropck_outlives.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,16 @@ crate fn provide(p: &mut Providers) {
3030

3131
fn dropck_outlives<'tcx>(
3232
tcx: TyCtxt<'_, 'tcx, 'tcx>,
33-
goal: CanonicalTyGoal<'tcx>,
33+
canonical_goal: CanonicalTyGoal<'tcx>,
3434
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, DropckOutlivesResult<'tcx>>>>, NoSolution> {
35-
debug!("dropck_outlives(goal={:#?})", goal);
35+
debug!("dropck_outlives(goal={:#?})", canonical_goal);
3636

37-
tcx.infer_ctxt().enter(|ref infcx| {
37+
tcx.infer_ctxt().enter_with_canonical(DUMMY_SP, &canonical_goal, |ref infcx, goal, canonical_inference_vars| {
3838
let tcx = infcx.tcx;
39-
let (
40-
ParamEnvAnd {
41-
param_env,
42-
value: for_ty,
43-
},
44-
canonical_inference_vars,
45-
) = infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &goal);
39+
let ParamEnvAnd {
40+
param_env,
41+
value: for_ty,
42+
} = goal;
4643

4744
let mut result = DropckOutlivesResult {
4845
kinds: vec![],

src/librustc_traits/evaluate_obligation.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,13 @@ crate fn provide(p: &mut Providers) {
2424

2525
fn evaluate_obligation<'tcx>(
2626
tcx: TyCtxt<'_, 'tcx, 'tcx>,
27-
goal: CanonicalPredicateGoal<'tcx>,
27+
canonical_goal: CanonicalPredicateGoal<'tcx>,
2828
) -> Result<EvaluationResult, OverflowError> {
29-
tcx.infer_ctxt().enter(|ref infcx| {
30-
let (
31-
ParamEnvAnd {
32-
param_env,
33-
value: predicate,
34-
},
35-
_canonical_inference_vars,
36-
) = infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &goal);
29+
tcx.infer_ctxt().enter_with_canonical(DUMMY_SP, &canonical_goal, |ref infcx, goal, _canonical_inference_vars| {
30+
let ParamEnvAnd {
31+
param_env,
32+
value: predicate,
33+
} = goal;
3734

3835
let mut selcx = SelectionContext::with_query_mode(&infcx, TraitQueryMode::Canonical);
3936
let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);

0 commit comments

Comments
 (0)