1 //! This module contains the code to instantiate a "query result", and
2 //! in particular to extract out the resulting region obligations and
3 //! encode them therein.
5 //! For an overview of what canonicaliation is and how it fits into
6 //! rustc, check out the [chapter in the rustc dev guide][c].
8 //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html
10 use crate::infer
::canonical
::substitute
::{substitute_value, CanonicalExt}
;
11 use crate::infer
::canonical
::{
12 Canonical
, CanonicalVarValues
, CanonicalizedQueryResponse
, Certainty
, OriginalQueryValues
,
13 QueryOutlivesConstraint
, QueryRegionConstraints
, QueryResponse
,
15 use crate::infer
::nll_relate
::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate}
;
16 use crate::infer
::region_constraints
::{Constraint, RegionConstraintData}
;
17 use crate::infer
::{InferCtxt, InferOk, InferResult, NllRegionVariableOrigin}
;
18 use crate::traits
::query
::{Fallible, NoSolution}
;
19 use crate::traits
::TraitEngine
;
20 use crate::traits
::{Obligation, ObligationCause, PredicateObligation}
;
21 use rustc_data_structures
::captures
::Captures
;
22 use rustc_index
::vec
::Idx
;
23 use rustc_index
::vec
::IndexVec
;
24 use rustc_middle
::arena
::ArenaAllocatable
;
25 use rustc_middle
::ty
::fold
::TypeFoldable
;
26 use rustc_middle
::ty
::relate
::TypeRelation
;
27 use rustc_middle
::ty
::subst
::{GenericArg, GenericArgKind}
;
28 use rustc_middle
::ty
::{self, BoundVar, Const, ToPredicate, Ty, TyCtxt}
;
32 impl<'cx
, 'tcx
> InferCtxt
<'cx
, 'tcx
> {
33 /// This method is meant to be invoked as the final step of a canonical query
34 /// implementation. It is given:
36 /// - the instantiated variables `inference_vars` created from the query key
37 /// - the result `answer` of the query
38 /// - a fulfillment context `fulfill_cx` that may contain various obligations which
39 /// have yet to be proven.
41 /// Given this, the function will process the obligations pending
44 /// - If all the obligations can be proven successfully, it will
45 /// package up any resulting region obligations (extracted from
46 /// `infcx`) along with the fully resolved value `answer` into a
47 /// query result (which is then itself canonicalized).
48 /// - If some obligations can be neither proven nor disproven, then
49 /// the same thing happens, but the resulting query is marked as ambiguous.
50 /// - Finally, if any of the obligations result in a hard error,
51 /// then `Err(NoSolution)` is returned.
52 pub fn make_canonicalized_query_response
<T
>(
54 inference_vars
: CanonicalVarValues
<'tcx
>,
56 fulfill_cx
: &mut dyn TraitEngine
<'tcx
>,
57 ) -> Fallible
<CanonicalizedQueryResponse
<'tcx
, T
>>
59 T
: Debug
+ TypeFoldable
<'tcx
>,
60 Canonical
<'tcx
, QueryResponse
<'tcx
, T
>>: ArenaAllocatable
<'tcx
>,
62 let query_response
= self.make_query_response(inference_vars
, answer
, fulfill_cx
)?
;
63 let canonical_result
= self.canonicalize_response(query_response
);
65 debug
!("make_canonicalized_query_response: canonical_result = {:#?}", canonical_result
);
67 Ok(self.tcx
.arena
.alloc(canonical_result
))
70 /// A version of `make_canonicalized_query_response` that does
71 /// not pack in obligations, for contexts that want to drop
72 /// pending obligations instead of treating them as an ambiguity (e.g.
73 /// typeck "probing" contexts).
75 /// If you DO want to keep track of pending obligations (which
76 /// include all region obligations, so this includes all cases
77 /// that care about regions) with this function, you have to
78 /// do it yourself, by e.g., having them be a part of the answer.
79 pub fn make_query_response_ignoring_pending_obligations
<T
>(
81 inference_vars
: CanonicalVarValues
<'tcx
>,
83 ) -> Canonical
<'tcx
, QueryResponse
<'tcx
, T
>>
85 T
: Debug
+ TypeFoldable
<'tcx
>,
87 self.canonicalize_response(QueryResponse
{
88 var_values
: inference_vars
,
89 region_constraints
: QueryRegionConstraints
::default(),
90 certainty
: Certainty
::Proven
, // Ambiguities are OK!
95 /// Helper for `make_canonicalized_query_response` that does
96 /// everything up until the final canonicalization.
97 fn make_query_response
<T
>(
99 inference_vars
: CanonicalVarValues
<'tcx
>,
101 fulfill_cx
: &mut dyn TraitEngine
<'tcx
>,
102 ) -> Result
<QueryResponse
<'tcx
, T
>, NoSolution
>
104 T
: Debug
+ TypeFoldable
<'tcx
>,
109 "make_query_response(\
110 inference_vars={:?}, \
112 inference_vars
, answer
,
115 // Select everything, returning errors.
116 let true_errors
= fulfill_cx
.select_where_possible(self).err().unwrap_or_else(Vec
::new
);
117 debug
!("true_errors = {:#?}", true_errors
);
119 if !true_errors
.is_empty() {
120 // FIXME -- we don't indicate *why* we failed to solve
121 debug
!("make_query_response: true_errors={:#?}", true_errors
);
122 return Err(NoSolution
);
125 // Anything left unselected *now* must be an ambiguity.
126 let ambig_errors
= fulfill_cx
.select_all_or_error(self).err().unwrap_or_else(Vec
::new
);
127 debug
!("ambig_errors = {:#?}", ambig_errors
);
129 let region_obligations
= self.take_registered_region_obligations();
130 let region_constraints
= self.with_region_constraints(|region_constraints
| {
131 make_query_region_constraints(
133 region_obligations
.iter().map(|(_
, r_o
)| (r_o
.sup_type
, r_o
.sub_region
)),
139 if ambig_errors
.is_empty() { Certainty::Proven }
else { Certainty::Ambiguous }
;
142 var_values
: inference_vars
,
149 /// Given the (canonicalized) result to a canonical query,
150 /// instantiates the result so it can be used, plugging in the
151 /// values from the canonical query. (Note that the result may
152 /// have been ambiguous; you should check the certainty level of
153 /// the query before applying this function.)
155 /// To get a good understanding of what is happening here, check
156 /// out the [chapter in the rustc dev guide][c].
158 /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html#processing-the-canonicalized-query-result
159 pub fn instantiate_query_response_and_region_obligations
<R
>(
161 cause
: &ObligationCause
<'tcx
>,
162 param_env
: ty
::ParamEnv
<'tcx
>,
163 original_values
: &OriginalQueryValues
<'tcx
>,
164 query_response
: &Canonical
<'tcx
, QueryResponse
<'tcx
, R
>>,
165 ) -> InferResult
<'tcx
, R
>
167 R
: Debug
+ TypeFoldable
<'tcx
>,
169 let InferOk { value: result_subst, mut obligations }
=
170 self.query_response_substitution(cause
, param_env
, original_values
, query_response
)?
;
172 obligations
.extend(self.query_outlives_constraints_into_obligations(
175 &query_response
.value
.region_constraints
.outlives
,
180 query_response
.substitute_projected(self.tcx
, &result_subst
, |q_r
| q_r
.value
.clone());
182 Ok(InferOk { value: user_result, obligations }
)
185 /// An alternative to
186 /// `instantiate_query_response_and_region_obligations` that is more
187 /// efficient for NLL. NLL is a bit more advanced in the
188 /// "transition to chalk" than the rest of the compiler. During
189 /// the NLL type check, all of the "processing" of types and
190 /// things happens in queries -- the NLL checker itself is only
191 /// interested in the region obligations (`'a: 'b` or `T: 'b`)
192 /// that come out of these queries, which it wants to convert into
193 /// MIR-based constraints and solve. Therefore, it is most
194 /// convenient for the NLL Type Checker to **directly consume**
195 /// the `QueryOutlivesConstraint` values that arise from doing a
196 /// query. This is contrast to other parts of the compiler, which
197 /// would prefer for those `QueryOutlivesConstraint` to be converted
198 /// into the older infcx-style constraints (e.g., calls to
199 /// `sub_regions` or `register_region_obligation`).
201 /// Therefore, `instantiate_nll_query_response_and_region_obligations` performs the same
202 /// basic operations as `instantiate_query_response_and_region_obligations` but
203 /// it returns its result differently:
205 /// - It creates a substitution `S` that maps from the original
206 /// query variables to the values computed in the query
207 /// result. If any errors arise, they are propagated back as an
209 /// - In the case of a successful substitution, we will append
210 /// `QueryOutlivesConstraint` values onto the
211 /// `output_query_region_constraints` vector for the solver to
212 /// use (if an error arises, some values may also be pushed, but
213 /// they should be ignored).
214 /// - It **can happen** (though it rarely does currently) that
215 /// equating types and things will give rise to subobligations
216 /// that must be processed. In this case, those subobligations
217 /// are propagated back in the return value.
218 /// - Finally, the query result (of type `R`) is propagated back,
219 /// after applying the substitution `S`.
220 pub fn instantiate_nll_query_response_and_region_obligations
<R
>(
222 cause
: &ObligationCause
<'tcx
>,
223 param_env
: ty
::ParamEnv
<'tcx
>,
224 original_values
: &OriginalQueryValues
<'tcx
>,
225 query_response
: &Canonical
<'tcx
, QueryResponse
<'tcx
, R
>>,
226 output_query_region_constraints
: &mut QueryRegionConstraints
<'tcx
>,
227 ) -> InferResult
<'tcx
, R
>
229 R
: Debug
+ TypeFoldable
<'tcx
>,
232 self.query_response_substitution_guess(cause
, original_values
, query_response
);
234 // Compute `QueryOutlivesConstraint` values that unify each of
235 // the original values `v_o` that was canonicalized into a
237 let mut obligations
= vec
![];
239 for (index
, original_value
) in original_values
.var_values
.iter().enumerate() {
240 // ...with the value `v_r` of that variable from the query.
241 let result_value
= query_response
.substitute_projected(self.tcx
, &result_subst
, |v
| {
242 v
.var_values
[BoundVar
::new(index
)]
244 match (original_value
.unpack(), result_value
.unpack()) {
246 GenericArgKind
::Lifetime(ty
::ReErased
),
247 GenericArgKind
::Lifetime(ty
::ReErased
),
252 (GenericArgKind
::Lifetime(v_o
), GenericArgKind
::Lifetime(v_r
)) => {
253 // To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`.
255 output_query_region_constraints
257 .push(ty
::Binder
::dummy(ty
::OutlivesPredicate(v_o
.into(), v_r
)));
258 output_query_region_constraints
260 .push(ty
::Binder
::dummy(ty
::OutlivesPredicate(v_r
.into(), v_o
)));
264 (GenericArgKind
::Type(v1
), GenericArgKind
::Type(v2
)) => {
267 QueryTypeRelatingDelegate
{
271 obligations
: &mut obligations
,
273 ty
::Variance
::Invariant
,
278 (GenericArgKind
::Const(v1
), GenericArgKind
::Const(v2
)) => {
281 QueryTypeRelatingDelegate
{
285 obligations
: &mut obligations
,
287 ty
::Variance
::Invariant
,
293 bug
!("kind mismatch, cannot unify {:?} and {:?}", original_value
, result_value
);
298 // ...also include the other query region constraints from the query.
299 output_query_region_constraints
.outlives
.extend(
300 query_response
.value
.region_constraints
.outlives
.iter().filter_map(|&r_c
| {
301 let r_c
= substitute_value(self.tcx
, &result_subst
, r_c
);
303 // Screen out `'a: 'a` cases -- we skip the binder here but
304 // only compare the inner values to one another, so they are still at
305 // consistent binding levels.
306 let ty
::OutlivesPredicate(k1
, r2
) = r_c
.skip_binder();
307 if k1
!= r2
.into() { Some(r_c) }
else { None }
311 // ...also include the query member constraints.
312 output_query_region_constraints
.member_constraints
.extend(
318 .map(|p_c
| substitute_value(self.tcx
, &result_subst
, p_c
.clone())),
322 query_response
.substitute_projected(self.tcx
, &result_subst
, |q_r
| q_r
.value
.clone());
324 Ok(InferOk { value: user_result, obligations }
)
327 /// Given the original values and the (canonicalized) result from
328 /// computing a query, returns a substitution that can be applied
329 /// to the query result to convert the result back into the
330 /// original namespace.
332 /// The substitution also comes accompanied with subobligations
333 /// that arose from unification; these might occur if (for
334 /// example) we are doing lazy normalization and the value
335 /// assigned to a type variable is unified with an unnormalized
337 fn query_response_substitution
<R
>(
339 cause
: &ObligationCause
<'tcx
>,
340 param_env
: ty
::ParamEnv
<'tcx
>,
341 original_values
: &OriginalQueryValues
<'tcx
>,
342 query_response
: &Canonical
<'tcx
, QueryResponse
<'tcx
, R
>>,
343 ) -> InferResult
<'tcx
, CanonicalVarValues
<'tcx
>>
345 R
: Debug
+ TypeFoldable
<'tcx
>,
348 "query_response_substitution(original_values={:#?}, query_response={:#?})",
349 original_values
, query_response
,
353 self.query_response_substitution_guess(cause
, original_values
, query_response
);
355 let obligations
= self
356 .unify_query_response_substitution_guess(
365 Ok(InferOk { value: result_subst, obligations }
)
368 /// Given the original values and the (canonicalized) result from
369 /// computing a query, returns a **guess** at a substitution that
370 /// can be applied to the query result to convert the result back
371 /// into the original namespace. This is called a **guess**
372 /// because it uses a quick heuristic to find the values for each
373 /// canonical variable; if that quick heuristic fails, then we
374 /// will instantiate fresh inference variables for each canonical
375 /// variable instead. Therefore, the result of this method must be
377 fn query_response_substitution_guess
<R
>(
379 cause
: &ObligationCause
<'tcx
>,
380 original_values
: &OriginalQueryValues
<'tcx
>,
381 query_response
: &Canonical
<'tcx
, QueryResponse
<'tcx
, R
>>,
382 ) -> CanonicalVarValues
<'tcx
>
384 R
: Debug
+ TypeFoldable
<'tcx
>,
387 "query_response_substitution_guess(original_values={:#?}, query_response={:#?})",
388 original_values
, query_response
,
391 // For each new universe created in the query result that did
392 // not appear in the original query, create a local
394 let mut universe_map
= original_values
.universe_map
.clone();
395 let num_universes_in_query
= original_values
.universe_map
.len();
396 let num_universes_in_response
= query_response
.max_universe
.as_usize() + 1;
397 for _
in num_universes_in_query
..num_universes_in_response
{
398 universe_map
.push(self.create_next_universe());
400 assert
!(!universe_map
.is_empty()); // always have the root universe
401 assert_eq
!(universe_map
[ty
::UniverseIndex
::ROOT
.as_usize()], ty
::UniverseIndex
::ROOT
);
403 // Every canonical query result includes values for each of
404 // the inputs to the query. Therefore, we begin by unifying
405 // these values with the original inputs that were
407 let result_values
= &query_response
.value
.var_values
;
408 assert_eq
!(original_values
.var_values
.len(), result_values
.len());
410 // Quickly try to find initial values for the canonical
411 // variables in the result in terms of the query. We do this
412 // by iterating down the values that the query gave to each of
413 // the canonical inputs. If we find that one of those values
414 // is directly equal to one of the canonical variables in the
415 // result, then we can type the corresponding value from the
416 // input. See the example above.
417 let mut opt_values
: IndexVec
<BoundVar
, Option
<GenericArg
<'tcx
>>> =
418 IndexVec
::from_elem_n(None
, query_response
.variables
.len());
420 // In terms of our example above, we are iterating over pairs like:
421 // [(?A, Vec<?0>), ('static, '?1), (?B, ?0)]
422 for (original_value
, result_value
) in iter
::zip(&original_values
.var_values
, result_values
)
424 match result_value
.unpack() {
425 GenericArgKind
::Type(result_value
) => {
426 // e.g., here `result_value` might be `?0` in the example above...
427 if let ty
::Bound(debruijn
, b
) = *result_value
.kind() {
428 // ...in which case we would set `canonical_vars[0]` to `Some(?U)`.
430 // We only allow a `ty::INNERMOST` index in substitutions.
431 assert_eq
!(debruijn
, ty
::INNERMOST
);
432 opt_values
[b
.var
] = Some(*original_value
);
435 GenericArgKind
::Lifetime(result_value
) => {
436 // e.g., here `result_value` might be `'?1` in the example above...
437 if let &ty
::RegionKind
::ReLateBound(debruijn
, br
) = result_value
{
438 // ... in which case we would set `canonical_vars[0]` to `Some('static)`.
440 // We only allow a `ty::INNERMOST` index in substitutions.
441 assert_eq
!(debruijn
, ty
::INNERMOST
);
442 opt_values
[br
.var
] = Some(*original_value
);
445 GenericArgKind
::Const(result_value
) => {
446 if let ty
::Const { val: ty::ConstKind::Bound(debrujin, b), .. }
= result_value
{
447 // ...in which case we would set `canonical_vars[0]` to `Some(const X)`.
449 // We only allow a `ty::INNERMOST` index in substitutions.
450 assert_eq
!(*debrujin
, ty
::INNERMOST
);
451 opt_values
[*b
] = Some(*original_value
);
457 // Create a result substitution: if we found a value for a
458 // given variable in the loop above, use that. Otherwise, use
459 // a fresh inference variable.
460 let result_subst
= CanonicalVarValues
{
461 var_values
: query_response
465 .map(|(index
, info
)| {
466 if info
.is_existential() {
467 match opt_values
[BoundVar
::new(index
)] {
469 None
=> self.instantiate_canonical_var(cause
.span
, info
, |u
| {
470 universe_map
[u
.as_usize()]
474 self.instantiate_canonical_var(cause
.span
, info
, |u
| {
475 universe_map
[u
.as_usize()]
485 /// Given a "guess" at the values for the canonical variables in
486 /// the input, try to unify with the *actual* values found in the
487 /// query result. Often, but not always, this is a no-op, because
488 /// we already found the mapping in the "guessing" step.
490 /// See also: `query_response_substitution_guess`
491 fn unify_query_response_substitution_guess
<R
>(
493 cause
: &ObligationCause
<'tcx
>,
494 param_env
: ty
::ParamEnv
<'tcx
>,
495 original_values
: &OriginalQueryValues
<'tcx
>,
496 result_subst
: &CanonicalVarValues
<'tcx
>,
497 query_response
: &Canonical
<'tcx
, QueryResponse
<'tcx
, R
>>,
498 ) -> InferResult
<'tcx
, ()>
500 R
: Debug
+ TypeFoldable
<'tcx
>,
502 // A closure that yields the result value for the given
503 // canonical variable; this is taken from
504 // `query_response.var_values` after applying the substitution
506 let substituted_query_response
= |index
: BoundVar
| -> GenericArg
<'tcx
> {
507 query_response
.substitute_projected(self.tcx
, &result_subst
, |v
| v
.var_values
[index
])
510 // Unify the original value for each variable with the value
511 // taken from `query_response` (after applying `result_subst`).
512 self.unify_canonical_vars(cause
, param_env
, original_values
, substituted_query_response
)
515 /// Converts the region constraints resulting from a query into an
516 /// iterator of obligations.
517 fn query_outlives_constraints_into_obligations
<'a
>(
519 cause
: &'a ObligationCause
<'tcx
>,
520 param_env
: ty
::ParamEnv
<'tcx
>,
521 unsubstituted_region_constraints
: &'a
[QueryOutlivesConstraint
<'tcx
>],
522 result_subst
: &'a CanonicalVarValues
<'tcx
>,
523 ) -> impl Iterator
<Item
= PredicateObligation
<'tcx
>> + 'a
+ Captures
<'tcx
> {
524 unsubstituted_region_constraints
.iter().map(move |&constraint
| {
525 let predicate
= substitute_value(self.tcx
, result_subst
, constraint
);
526 let ty
::OutlivesPredicate(k1
, r2
) = predicate
.skip_binder();
528 let atom
= match k1
.unpack() {
529 GenericArgKind
::Lifetime(r1
) => {
530 ty
::PredicateKind
::RegionOutlives(ty
::OutlivesPredicate(r1
, r2
))
532 GenericArgKind
::Type(t1
) => {
533 ty
::PredicateKind
::TypeOutlives(ty
::OutlivesPredicate(t1
, r2
))
535 GenericArgKind
::Const(..) => {
536 // Consts cannot outlive one another, so we don't expect to
537 // encounter this branch.
538 span_bug
!(cause
.span
, "unexpected const outlives {:?}", constraint
);
541 let predicate
= predicate
.rebind(atom
).to_predicate(self.tcx
);
543 Obligation
::new(cause
.clone(), param_env
, predicate
)
547 /// Given two sets of values for the same set of canonical variables, unify them.
548 /// The second set is produced lazily by supplying indices from the first set.
549 fn unify_canonical_vars(
551 cause
: &ObligationCause
<'tcx
>,
552 param_env
: ty
::ParamEnv
<'tcx
>,
553 variables1
: &OriginalQueryValues
<'tcx
>,
554 variables2
: impl Fn(BoundVar
) -> GenericArg
<'tcx
>,
555 ) -> InferResult
<'tcx
, ()> {
556 self.commit_if_ok(|_
| {
557 let mut obligations
= vec
![];
558 for (index
, value1
) in variables1
.var_values
.iter().enumerate() {
559 let value2
= variables2(BoundVar
::new(index
));
561 match (value1
.unpack(), value2
.unpack()) {
562 (GenericArgKind
::Type(v1
), GenericArgKind
::Type(v2
)) => {
564 .extend(self.at(cause
, param_env
).eq(v1
, v2
)?
.into_obligations());
567 GenericArgKind
::Lifetime(ty
::ReErased
),
568 GenericArgKind
::Lifetime(ty
::ReErased
),
572 (GenericArgKind
::Lifetime(v1
), GenericArgKind
::Lifetime(v2
)) => {
574 .extend(self.at(cause
, param_env
).eq(v1
, v2
)?
.into_obligations());
576 (GenericArgKind
::Const(v1
), GenericArgKind
::Const(v2
)) => {
577 let ok
= self.at(cause
, param_env
).eq(v1
, v2
)?
;
578 obligations
.extend(ok
.into_obligations());
581 bug
!("kind mismatch, cannot unify {:?} and {:?}", value1
, value2
,);
585 Ok(InferOk { value: (), obligations }
)
590 /// Given the region obligations and constraints scraped from the infcx,
591 /// creates query region constraints.
592 pub fn make_query_region_constraints
<'tcx
>(
594 outlives_obligations
: impl Iterator
<Item
= (Ty
<'tcx
>, ty
::Region
<'tcx
>)>,
595 region_constraints
: &RegionConstraintData
<'tcx
>,
596 ) -> QueryRegionConstraints
<'tcx
> {
597 let RegionConstraintData { constraints, verifys, givens, member_constraints }
=
600 assert
!(verifys
.is_empty());
601 assert
!(givens
.is_empty());
603 let outlives
: Vec
<_
> = constraints
605 .map(|(k
, _
)| match *k
{
606 // Swap regions because we are going from sub (<=) to outlives
608 Constraint
::VarSubVar(v1
, v2
) => ty
::OutlivesPredicate(
609 tcx
.mk_region(ty
::ReVar(v2
)).into(),
610 tcx
.mk_region(ty
::ReVar(v1
)),
612 Constraint
::VarSubReg(v1
, r2
) => {
613 ty
::OutlivesPredicate(r2
.into(), tcx
.mk_region(ty
::ReVar(v1
)))
615 Constraint
::RegSubVar(r1
, v2
) => {
616 ty
::OutlivesPredicate(tcx
.mk_region(ty
::ReVar(v2
)).into(), r1
)
618 Constraint
::RegSubReg(r1
, r2
) => ty
::OutlivesPredicate(r2
.into(), r1
),
620 .map(ty
::Binder
::dummy
) // no bound vars in the code above
623 .map(|(ty
, r
)| ty
::OutlivesPredicate(ty
.into(), r
))
624 .map(ty
::Binder
::dummy
), // no bound vars in the code above
628 QueryRegionConstraints { outlives, member_constraints: member_constraints.clone() }
631 struct QueryTypeRelatingDelegate
<'a
, 'tcx
> {
632 infcx
: &'a InferCtxt
<'a
, 'tcx
>,
633 obligations
: &'a
mut Vec
<PredicateObligation
<'tcx
>>,
634 param_env
: ty
::ParamEnv
<'tcx
>,
635 cause
: &'a ObligationCause
<'tcx
>,
638 impl<'tcx
> TypeRelatingDelegate
<'tcx
> for QueryTypeRelatingDelegate
<'_
, 'tcx
> {
639 fn param_env(&self) -> ty
::ParamEnv
<'tcx
> {
643 fn create_next_universe(&mut self) -> ty
::UniverseIndex
{
644 self.infcx
.create_next_universe()
647 fn next_existential_region_var(&mut self, from_forall
: bool
) -> ty
::Region
<'tcx
> {
648 let origin
= NllRegionVariableOrigin
::Existential { from_forall }
;
649 self.infcx
.next_nll_region_var(origin
)
652 fn next_placeholder_region(&mut self, placeholder
: ty
::PlaceholderRegion
) -> ty
::Region
<'tcx
> {
653 self.infcx
.tcx
.mk_region(ty
::RePlaceholder(placeholder
))
656 fn generalize_existential(&mut self, universe
: ty
::UniverseIndex
) -> ty
::Region
<'tcx
> {
657 self.infcx
.next_nll_region_var_in_universe(
658 NllRegionVariableOrigin
::Existential { from_forall: false }
,
663 fn push_outlives(&mut self, sup
: ty
::Region
<'tcx
>, sub
: ty
::Region
<'tcx
>) {
664 self.obligations
.push(Obligation
{
665 cause
: self.cause
.clone(),
666 param_env
: self.param_env
,
667 predicate
: ty
::PredicateKind
::RegionOutlives(ty
::OutlivesPredicate(sup
, sub
))
668 .to_predicate(self.infcx
.tcx
),
673 fn const_equate(&mut self, _a
: &'tcx Const
<'tcx
>, _b
: &'tcx Const
<'tcx
>) {
675 self.cause
.span(self.infcx
.tcx
),
676 "lazy_normalization_consts: unreachable `const_equate`"
680 fn normalization() -> NormalizationStrategy
{
681 NormalizationStrategy
::Eager
684 fn forbid_inference_vars() -> bool
{