• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 //!
5 //! For an overview of what canonicalization is and how it fits into
6 //! rustc, check out the [chapter in the rustc dev guide][c].
7 //!
8 //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html
9 
10 use crate::infer::canonical::substitute::{substitute_value, CanonicalExt};
11 use crate::infer::canonical::{
12     Canonical, CanonicalQueryResponse, CanonicalVarValues, Certainty, OriginalQueryValues,
13     QueryOutlivesConstraint, QueryRegionConstraints, QueryResponse,
14 };
15 use crate::infer::nll_relate::{TypeRelating, TypeRelatingDelegate};
16 use crate::infer::region_constraints::{Constraint, RegionConstraintData};
17 use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult, NllRegionVariableOrigin};
18 use crate::traits::query::NoSolution;
19 use crate::traits::{Obligation, ObligationCause, PredicateObligation};
20 use crate::traits::{PredicateObligations, TraitEngine, TraitEngineExt};
21 use rustc_data_structures::captures::Captures;
22 use rustc_index::Idx;
23 use rustc_index::IndexVec;
24 use rustc_middle::arena::ArenaAllocatable;
25 use rustc_middle::mir::ConstraintCategory;
26 use rustc_middle::ty::fold::TypeFoldable;
27 use rustc_middle::ty::relate::TypeRelation;
28 use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
29 use rustc_middle::ty::{self, BoundVar, ToPredicate, Ty, TyCtxt};
30 use rustc_span::{Span, Symbol};
31 use std::fmt::Debug;
32 use std::iter;
33 
34 impl<'tcx> InferCtxt<'tcx> {
35     /// This method is meant to be invoked as the final step of a canonical query
36     /// implementation. It is given:
37     ///
38     /// - the instantiated variables `inference_vars` created from the query key
39     /// - the result `answer` of the query
40     /// - a fulfillment context `fulfill_cx` that may contain various obligations which
41     ///   have yet to be proven.
42     ///
43     /// Given this, the function will process the obligations pending
44     /// in `fulfill_cx`:
45     ///
46     /// - If all the obligations can be proven successfully, it will
47     ///   package up any resulting region obligations (extracted from
48     ///   `infcx`) along with the fully resolved value `answer` into a
49     ///   query result (which is then itself canonicalized).
50     /// - If some obligations can be neither proven nor disproven, then
51     ///   the same thing happens, but the resulting query is marked as ambiguous.
52     /// - Finally, if any of the obligations result in a hard error,
53     ///   then `Err(NoSolution)` is returned.
54     #[instrument(skip(self, inference_vars, answer, fulfill_cx), level = "trace")]
make_canonicalized_query_response<T>( &self, inference_vars: CanonicalVarValues<'tcx>, answer: T, fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Result<CanonicalQueryResponse<'tcx, T>, NoSolution> where T: Debug + TypeFoldable<TyCtxt<'tcx>>, Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,55     pub fn make_canonicalized_query_response<T>(
56         &self,
57         inference_vars: CanonicalVarValues<'tcx>,
58         answer: T,
59         fulfill_cx: &mut dyn TraitEngine<'tcx>,
60     ) -> Result<CanonicalQueryResponse<'tcx, T>, NoSolution>
61     where
62         T: Debug + TypeFoldable<TyCtxt<'tcx>>,
63         Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,
64     {
65         let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?;
66         debug!("query_response = {:#?}", query_response);
67         let canonical_result = self.canonicalize_response(query_response);
68         debug!("canonical_result = {:#?}", canonical_result);
69 
70         Ok(self.tcx.arena.alloc(canonical_result))
71     }
72 
73     /// A version of `make_canonicalized_query_response` that does
74     /// not pack in obligations, for contexts that want to drop
75     /// pending obligations instead of treating them as an ambiguity (e.g.
76     /// typeck "probing" contexts).
77     ///
78     /// If you DO want to keep track of pending obligations (which
79     /// include all region obligations, so this includes all cases
80     /// that care about regions) with this function, you have to
81     /// do it yourself, by e.g., having them be a part of the answer.
make_query_response_ignoring_pending_obligations<T>( &self, inference_vars: CanonicalVarValues<'tcx>, answer: T, ) -> Canonical<'tcx, QueryResponse<'tcx, T>> where T: Debug + TypeFoldable<TyCtxt<'tcx>>,82     pub fn make_query_response_ignoring_pending_obligations<T>(
83         &self,
84         inference_vars: CanonicalVarValues<'tcx>,
85         answer: T,
86     ) -> Canonical<'tcx, QueryResponse<'tcx, T>>
87     where
88         T: Debug + TypeFoldable<TyCtxt<'tcx>>,
89     {
90         self.canonicalize_response(QueryResponse {
91             var_values: inference_vars,
92             region_constraints: QueryRegionConstraints::default(),
93             certainty: Certainty::Proven, // Ambiguities are OK!
94             opaque_types: vec![],
95             value: answer,
96         })
97     }
98 
99     /// Helper for `make_canonicalized_query_response` that does
100     /// everything up until the final canonicalization.
101     #[instrument(skip(self, fulfill_cx), level = "debug")]
make_query_response<T>( &self, inference_vars: CanonicalVarValues<'tcx>, answer: T, fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Result<QueryResponse<'tcx, T>, NoSolution> where T: Debug + TypeFoldable<TyCtxt<'tcx>>,102     fn make_query_response<T>(
103         &self,
104         inference_vars: CanonicalVarValues<'tcx>,
105         answer: T,
106         fulfill_cx: &mut dyn TraitEngine<'tcx>,
107     ) -> Result<QueryResponse<'tcx, T>, NoSolution>
108     where
109         T: Debug + TypeFoldable<TyCtxt<'tcx>>,
110     {
111         let tcx = self.tcx;
112 
113         // Select everything, returning errors.
114         let true_errors = fulfill_cx.select_where_possible(self);
115         debug!("true_errors = {:#?}", true_errors);
116 
117         if !true_errors.is_empty() {
118             // FIXME -- we don't indicate *why* we failed to solve
119             debug!("make_query_response: true_errors={:#?}", true_errors);
120             return Err(NoSolution);
121         }
122 
123         // Anything left unselected *now* must be an ambiguity.
124         let ambig_errors = fulfill_cx.select_all_or_error(self);
125         debug!("ambig_errors = {:#?}", ambig_errors);
126 
127         let region_obligations = self.take_registered_region_obligations();
128         debug!(?region_obligations);
129         let region_constraints = self.with_region_constraints(|region_constraints| {
130             make_query_region_constraints(
131                 tcx,
132                 region_obligations
133                     .iter()
134                     .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())),
135                 region_constraints,
136             )
137         });
138         debug!(?region_constraints);
139 
140         let certainty =
141             if ambig_errors.is_empty() { Certainty::Proven } else { Certainty::Ambiguous };
142 
143         let opaque_types = self.take_opaque_types_for_query_response();
144 
145         Ok(QueryResponse {
146             var_values: inference_vars,
147             region_constraints,
148             certainty,
149             value: answer,
150             opaque_types,
151         })
152     }
153 
154     /// Used by the new solver as that one takes the opaque types at the end of a probe
155     /// to deal with multiple candidates without having to recompute them.
clone_opaque_types_for_query_response( &self, ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>156     pub fn clone_opaque_types_for_query_response(
157         &self,
158     ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
159         self.inner
160             .borrow()
161             .opaque_type_storage
162             .opaque_types
163             .iter()
164             .map(|(k, v)| (*k, v.hidden_type.ty))
165             .collect()
166     }
167 
take_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>168     fn take_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
169         std::mem::take(&mut self.inner.borrow_mut().opaque_type_storage.opaque_types)
170             .into_iter()
171             .map(|(k, v)| (k, v.hidden_type.ty))
172             .collect()
173     }
174 
175     /// Given the (canonicalized) result to a canonical query,
176     /// instantiates the result so it can be used, plugging in the
177     /// values from the canonical query. (Note that the result may
178     /// have been ambiguous; you should check the certainty level of
179     /// the query before applying this function.)
180     ///
181     /// To get a good understanding of what is happening here, check
182     /// out the [chapter in the rustc dev guide][c].
183     ///
184     /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html#processing-the-canonicalized-query-result
instantiate_query_response_and_region_obligations<R>( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, R> where R: Debug + TypeFoldable<TyCtxt<'tcx>>,185     pub fn instantiate_query_response_and_region_obligations<R>(
186         &self,
187         cause: &ObligationCause<'tcx>,
188         param_env: ty::ParamEnv<'tcx>,
189         original_values: &OriginalQueryValues<'tcx>,
190         query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
191     ) -> InferResult<'tcx, R>
192     where
193         R: Debug + TypeFoldable<TyCtxt<'tcx>>,
194     {
195         let InferOk { value: result_subst, mut obligations } =
196             self.query_response_substitution(cause, param_env, original_values, query_response)?;
197 
198         obligations.extend(self.query_outlives_constraints_into_obligations(
199             cause,
200             param_env,
201             &query_response.value.region_constraints.outlives,
202             &result_subst,
203         ));
204 
205         let user_result: R =
206             query_response.substitute_projected(self.tcx, &result_subst, |q_r| q_r.value.clone());
207 
208         Ok(InferOk { value: user_result, obligations })
209     }
210 
211     /// An alternative to
212     /// `instantiate_query_response_and_region_obligations` that is more
213     /// efficient for NLL. NLL is a bit more advanced in the
214     /// "transition to chalk" than the rest of the compiler. During
215     /// the NLL type check, all of the "processing" of types and
216     /// things happens in queries -- the NLL checker itself is only
217     /// interested in the region obligations (`'a: 'b` or `T: 'b`)
218     /// that come out of these queries, which it wants to convert into
219     /// MIR-based constraints and solve. Therefore, it is most
220     /// convenient for the NLL Type Checker to **directly consume**
221     /// the `QueryOutlivesConstraint` values that arise from doing a
222     /// query. This is contrast to other parts of the compiler, which
223     /// would prefer for those `QueryOutlivesConstraint` to be converted
224     /// into the older infcx-style constraints (e.g., calls to
225     /// `sub_regions` or `register_region_obligation`).
226     ///
227     /// Therefore, `instantiate_nll_query_response_and_region_obligations` performs the same
228     /// basic operations as `instantiate_query_response_and_region_obligations` but
229     /// it returns its result differently:
230     ///
231     /// - It creates a substitution `S` that maps from the original
232     ///   query variables to the values computed in the query
233     ///   result. If any errors arise, they are propagated back as an
234     ///   `Err` result.
235     /// - In the case of a successful substitution, we will append
236     ///   `QueryOutlivesConstraint` values onto the
237     ///   `output_query_region_constraints` vector for the solver to
238     ///   use (if an error arises, some values may also be pushed, but
239     ///   they should be ignored).
240     /// - It **can happen** (though it rarely does currently) that
241     ///   equating types and things will give rise to subobligations
242     ///   that must be processed. In this case, those subobligations
243     ///   are propagated back in the return value.
244     /// - Finally, the query result (of type `R`) is propagated back,
245     ///   after applying the substitution `S`.
instantiate_nll_query_response_and_region_obligations<R>( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, output_query_region_constraints: &mut QueryRegionConstraints<'tcx>, ) -> InferResult<'tcx, R> where R: Debug + TypeFoldable<TyCtxt<'tcx>>,246     pub fn instantiate_nll_query_response_and_region_obligations<R>(
247         &self,
248         cause: &ObligationCause<'tcx>,
249         param_env: ty::ParamEnv<'tcx>,
250         original_values: &OriginalQueryValues<'tcx>,
251         query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
252         output_query_region_constraints: &mut QueryRegionConstraints<'tcx>,
253     ) -> InferResult<'tcx, R>
254     where
255         R: Debug + TypeFoldable<TyCtxt<'tcx>>,
256     {
257         let InferOk { value: result_subst, mut obligations } = self
258             .query_response_substitution_guess(cause, param_env, original_values, query_response)?;
259 
260         // Compute `QueryOutlivesConstraint` values that unify each of
261         // the original values `v_o` that was canonicalized into a
262         // variable...
263 
264         let constraint_category = cause.to_constraint_category();
265 
266         for (index, original_value) in original_values.var_values.iter().enumerate() {
267             // ...with the value `v_r` of that variable from the query.
268             let result_value = query_response.substitute_projected(self.tcx, &result_subst, |v| {
269                 v.var_values[BoundVar::new(index)]
270             });
271             match (original_value.unpack(), result_value.unpack()) {
272                 (GenericArgKind::Lifetime(re1), GenericArgKind::Lifetime(re2))
273                     if re1.is_erased() && re2.is_erased() =>
274                 {
275                     // No action needed.
276                 }
277 
278                 (GenericArgKind::Lifetime(v_o), GenericArgKind::Lifetime(v_r)) => {
279                     // To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`.
280                     if v_o != v_r {
281                         output_query_region_constraints
282                             .outlives
283                             .push((ty::OutlivesPredicate(v_o.into(), v_r), constraint_category));
284                         output_query_region_constraints
285                             .outlives
286                             .push((ty::OutlivesPredicate(v_r.into(), v_o), constraint_category));
287                     }
288                 }
289 
290                 (GenericArgKind::Type(v1), GenericArgKind::Type(v2)) => {
291                     TypeRelating::new(
292                         self,
293                         QueryTypeRelatingDelegate {
294                             infcx: self,
295                             param_env,
296                             cause,
297                             obligations: &mut obligations,
298                         },
299                         ty::Variance::Invariant,
300                     )
301                     .relate(v1, v2)?;
302                 }
303 
304                 (GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => {
305                     TypeRelating::new(
306                         self,
307                         QueryTypeRelatingDelegate {
308                             infcx: self,
309                             param_env,
310                             cause,
311                             obligations: &mut obligations,
312                         },
313                         ty::Variance::Invariant,
314                     )
315                     .relate(v1, v2)?;
316                 }
317 
318                 _ => {
319                     bug!("kind mismatch, cannot unify {:?} and {:?}", original_value, result_value);
320                 }
321             }
322         }
323 
324         // ...also include the other query region constraints from the query.
325         output_query_region_constraints.outlives.extend(
326             query_response.value.region_constraints.outlives.iter().filter_map(|&r_c| {
327                 let r_c = substitute_value(self.tcx, &result_subst, r_c);
328 
329                 // Screen out `'a: 'a` cases.
330                 let ty::OutlivesPredicate(k1, r2) = r_c.0;
331                 if k1 != r2.into() { Some(r_c) } else { None }
332             }),
333         );
334 
335         // ...also include the query member constraints.
336         output_query_region_constraints.member_constraints.extend(
337             query_response
338                 .value
339                 .region_constraints
340                 .member_constraints
341                 .iter()
342                 .map(|p_c| substitute_value(self.tcx, &result_subst, p_c.clone())),
343         );
344 
345         let user_result: R =
346             query_response.substitute_projected(self.tcx, &result_subst, |q_r| q_r.value.clone());
347 
348         Ok(InferOk { value: user_result, obligations })
349     }
350 
351     /// Given the original values and the (canonicalized) result from
352     /// computing a query, returns a substitution that can be applied
353     /// to the query result to convert the result back into the
354     /// original namespace.
355     ///
356     /// The substitution also comes accompanied with subobligations
357     /// that arose from unification; these might occur if (for
358     /// example) we are doing lazy normalization and the value
359     /// assigned to a type variable is unified with an unnormalized
360     /// projection.
query_response_substitution<R>( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, CanonicalVarValues<'tcx>> where R: Debug + TypeFoldable<TyCtxt<'tcx>>,361     fn query_response_substitution<R>(
362         &self,
363         cause: &ObligationCause<'tcx>,
364         param_env: ty::ParamEnv<'tcx>,
365         original_values: &OriginalQueryValues<'tcx>,
366         query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
367     ) -> InferResult<'tcx, CanonicalVarValues<'tcx>>
368     where
369         R: Debug + TypeFoldable<TyCtxt<'tcx>>,
370     {
371         debug!(
372             "query_response_substitution(original_values={:#?}, query_response={:#?})",
373             original_values, query_response,
374         );
375 
376         let mut value = self.query_response_substitution_guess(
377             cause,
378             param_env,
379             original_values,
380             query_response,
381         )?;
382 
383         value.obligations.extend(
384             self.unify_query_response_substitution_guess(
385                 cause,
386                 param_env,
387                 original_values,
388                 &value.value,
389                 query_response,
390             )?
391             .into_obligations(),
392         );
393 
394         Ok(value)
395     }
396 
397     /// Given the original values and the (canonicalized) result from
398     /// computing a query, returns a **guess** at a substitution that
399     /// can be applied to the query result to convert the result back
400     /// into the original namespace. This is called a **guess**
401     /// because it uses a quick heuristic to find the values for each
402     /// canonical variable; if that quick heuristic fails, then we
403     /// will instantiate fresh inference variables for each canonical
404     /// variable instead. Therefore, the result of this method must be
405     /// properly unified
406     #[instrument(level = "debug", skip(self, cause, param_env))]
query_response_substitution_guess<R>( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, CanonicalVarValues<'tcx>> where R: Debug + TypeFoldable<TyCtxt<'tcx>>,407     fn query_response_substitution_guess<R>(
408         &self,
409         cause: &ObligationCause<'tcx>,
410         param_env: ty::ParamEnv<'tcx>,
411         original_values: &OriginalQueryValues<'tcx>,
412         query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
413     ) -> InferResult<'tcx, CanonicalVarValues<'tcx>>
414     where
415         R: Debug + TypeFoldable<TyCtxt<'tcx>>,
416     {
417         // For each new universe created in the query result that did
418         // not appear in the original query, create a local
419         // superuniverse.
420         let mut universe_map = original_values.universe_map.clone();
421         let num_universes_in_query = original_values.universe_map.len();
422         let num_universes_in_response = query_response.max_universe.as_usize() + 1;
423         for _ in num_universes_in_query..num_universes_in_response {
424             universe_map.push(self.create_next_universe());
425         }
426         assert!(!universe_map.is_empty()); // always have the root universe
427         assert_eq!(universe_map[ty::UniverseIndex::ROOT.as_usize()], ty::UniverseIndex::ROOT);
428 
429         // Every canonical query result includes values for each of
430         // the inputs to the query. Therefore, we begin by unifying
431         // these values with the original inputs that were
432         // canonicalized.
433         let result_values = &query_response.value.var_values;
434         assert_eq!(original_values.var_values.len(), result_values.len());
435 
436         // Quickly try to find initial values for the canonical
437         // variables in the result in terms of the query. We do this
438         // by iterating down the values that the query gave to each of
439         // the canonical inputs. If we find that one of those values
440         // is directly equal to one of the canonical variables in the
441         // result, then we can type the corresponding value from the
442         // input. See the example above.
443         let mut opt_values: IndexVec<BoundVar, Option<GenericArg<'tcx>>> =
444             IndexVec::from_elem_n(None, query_response.variables.len());
445 
446         // In terms of our example above, we are iterating over pairs like:
447         // [(?A, Vec<?0>), ('static, '?1), (?B, ?0)]
448         for (original_value, result_value) in iter::zip(&original_values.var_values, result_values)
449         {
450             match result_value.unpack() {
451                 GenericArgKind::Type(result_value) => {
452                     // e.g., here `result_value` might be `?0` in the example above...
453                     if let ty::Bound(debruijn, b) = *result_value.kind() {
454                         // ...in which case we would set `canonical_vars[0]` to `Some(?U)`.
455 
456                         // We only allow a `ty::INNERMOST` index in substitutions.
457                         assert_eq!(debruijn, ty::INNERMOST);
458                         opt_values[b.var] = Some(*original_value);
459                     }
460                 }
461                 GenericArgKind::Lifetime(result_value) => {
462                     // e.g., here `result_value` might be `'?1` in the example above...
463                     if let ty::ReLateBound(debruijn, br) = *result_value {
464                         // ... in which case we would set `canonical_vars[0]` to `Some('static)`.
465 
466                         // We only allow a `ty::INNERMOST` index in substitutions.
467                         assert_eq!(debruijn, ty::INNERMOST);
468                         opt_values[br.var] = Some(*original_value);
469                     }
470                 }
471                 GenericArgKind::Const(result_value) => {
472                     if let ty::ConstKind::Bound(debruijn, b) = result_value.kind() {
473                         // ...in which case we would set `canonical_vars[0]` to `Some(const X)`.
474 
475                         // We only allow a `ty::INNERMOST` index in substitutions.
476                         assert_eq!(debruijn, ty::INNERMOST);
477                         opt_values[b] = Some(*original_value);
478                     }
479                 }
480             }
481         }
482 
483         // Create a result substitution: if we found a value for a
484         // given variable in the loop above, use that. Otherwise, use
485         // a fresh inference variable.
486         let result_subst = CanonicalVarValues {
487             var_values: self.tcx.mk_substs_from_iter(
488                 query_response.variables.iter().enumerate().map(|(index, info)| {
489                     if info.is_existential() {
490                         match opt_values[BoundVar::new(index)] {
491                             Some(k) => k,
492                             None => self.instantiate_canonical_var(cause.span, info, |u| {
493                                 universe_map[u.as_usize()]
494                             }),
495                         }
496                     } else {
497                         self.instantiate_canonical_var(cause.span, info, |u| {
498                             universe_map[u.as_usize()]
499                         })
500                     }
501                 }),
502             ),
503         };
504 
505         let mut obligations = vec![];
506 
507         // Carry all newly resolved opaque types to the caller's scope
508         for &(a, b) in &query_response.value.opaque_types {
509             let a = substitute_value(self.tcx, &result_subst, a);
510             let b = substitute_value(self.tcx, &result_subst, b);
511             debug!(?a, ?b, "constrain opaque type");
512             // We use equate here instead of, for example, just registering the
513             // opaque type's hidden value directly, because we may be instantiating
514             // a query response that was canonicalized in an InferCtxt that had
515             // a different defining anchor. In that case, we may have inferred
516             // `NonLocalOpaque := LocalOpaque` but can only instantiate it in
517             // the other direction as `LocalOpaque := NonLocalOpaque`. Using eq
518             // here allows us to try both directions (in `InferCtxt::handle_opaque_type`).
519             obligations.extend(
520                 self.at(cause, param_env)
521                     .eq(
522                         DefineOpaqueTypes::Yes,
523                         Ty::new_opaque(self.tcx, a.def_id.to_def_id(), a.substs),
524                         b,
525                     )?
526                     .obligations,
527             );
528         }
529 
530         Ok(InferOk { value: result_subst, obligations })
531     }
532 
533     /// Given a "guess" at the values for the canonical variables in
534     /// the input, try to unify with the *actual* values found in the
535     /// query result. Often, but not always, this is a no-op, because
536     /// we already found the mapping in the "guessing" step.
537     ///
538     /// See also: `query_response_substitution_guess`
unify_query_response_substitution_guess<R>( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, result_subst: &CanonicalVarValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, ()> where R: Debug + TypeFoldable<TyCtxt<'tcx>>,539     fn unify_query_response_substitution_guess<R>(
540         &self,
541         cause: &ObligationCause<'tcx>,
542         param_env: ty::ParamEnv<'tcx>,
543         original_values: &OriginalQueryValues<'tcx>,
544         result_subst: &CanonicalVarValues<'tcx>,
545         query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
546     ) -> InferResult<'tcx, ()>
547     where
548         R: Debug + TypeFoldable<TyCtxt<'tcx>>,
549     {
550         // A closure that yields the result value for the given
551         // canonical variable; this is taken from
552         // `query_response.var_values` after applying the substitution
553         // `result_subst`.
554         let substituted_query_response = |index: BoundVar| -> GenericArg<'tcx> {
555             query_response.substitute_projected(self.tcx, &result_subst, |v| v.var_values[index])
556         };
557 
558         // Unify the original value for each variable with the value
559         // taken from `query_response` (after applying `result_subst`).
560         self.unify_canonical_vars(cause, param_env, original_values, substituted_query_response)
561     }
562 
563     /// Converts the region constraints resulting from a query into an
564     /// iterator of obligations.
query_outlives_constraints_into_obligations<'a>( &'a self, cause: &'a ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, unsubstituted_region_constraints: &'a [QueryOutlivesConstraint<'tcx>], result_subst: &'a CanonicalVarValues<'tcx>, ) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a + Captures<'tcx>565     fn query_outlives_constraints_into_obligations<'a>(
566         &'a self,
567         cause: &'a ObligationCause<'tcx>,
568         param_env: ty::ParamEnv<'tcx>,
569         unsubstituted_region_constraints: &'a [QueryOutlivesConstraint<'tcx>],
570         result_subst: &'a CanonicalVarValues<'tcx>,
571     ) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a + Captures<'tcx> {
572         unsubstituted_region_constraints.iter().map(move |&constraint| {
573             let predicate = substitute_value(self.tcx, result_subst, constraint);
574             self.query_outlives_constraint_to_obligation(predicate, cause.clone(), param_env)
575         })
576     }
577 
query_outlives_constraint_to_obligation( &self, (predicate, _): QueryOutlivesConstraint<'tcx>, cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Obligation<'tcx, ty::Predicate<'tcx>>578     pub fn query_outlives_constraint_to_obligation(
579         &self,
580         (predicate, _): QueryOutlivesConstraint<'tcx>,
581         cause: ObligationCause<'tcx>,
582         param_env: ty::ParamEnv<'tcx>,
583     ) -> Obligation<'tcx, ty::Predicate<'tcx>> {
584         let ty::OutlivesPredicate(k1, r2) = predicate;
585 
586         let atom = match k1.unpack() {
587             GenericArgKind::Lifetime(r1) => ty::PredicateKind::Clause(
588                 ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2)),
589             ),
590             GenericArgKind::Type(t1) => ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
591                 ty::OutlivesPredicate(t1, r2),
592             )),
593             GenericArgKind::Const(..) => {
594                 // Consts cannot outlive one another, so we don't expect to
595                 // encounter this branch.
596                 span_bug!(cause.span, "unexpected const outlives {:?}", predicate);
597             }
598         };
599         let predicate = ty::Binder::dummy(atom);
600 
601         Obligation::new(self.tcx, cause, param_env, predicate)
602     }
603 
604     /// Given two sets of values for the same set of canonical variables, unify them.
605     /// The second set is produced lazily by supplying indices from the first set.
unify_canonical_vars( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, variables1: &OriginalQueryValues<'tcx>, variables2: impl Fn(BoundVar) -> GenericArg<'tcx>, ) -> InferResult<'tcx, ()>606     fn unify_canonical_vars(
607         &self,
608         cause: &ObligationCause<'tcx>,
609         param_env: ty::ParamEnv<'tcx>,
610         variables1: &OriginalQueryValues<'tcx>,
611         variables2: impl Fn(BoundVar) -> GenericArg<'tcx>,
612     ) -> InferResult<'tcx, ()> {
613         self.commit_if_ok(|_| {
614             let mut obligations = vec![];
615             for (index, value1) in variables1.var_values.iter().enumerate() {
616                 let value2 = variables2(BoundVar::new(index));
617 
618                 match (value1.unpack(), value2.unpack()) {
619                     (GenericArgKind::Type(v1), GenericArgKind::Type(v2)) => {
620                         obligations.extend(
621                             self.at(cause, param_env)
622                                 .eq(DefineOpaqueTypes::Yes, v1, v2)?
623                                 .into_obligations(),
624                         );
625                     }
626                     (GenericArgKind::Lifetime(re1), GenericArgKind::Lifetime(re2))
627                         if re1.is_erased() && re2.is_erased() =>
628                     {
629                         // no action needed
630                     }
631                     (GenericArgKind::Lifetime(v1), GenericArgKind::Lifetime(v2)) => {
632                         obligations.extend(
633                             self.at(cause, param_env)
634                                 .eq(DefineOpaqueTypes::Yes, v1, v2)?
635                                 .into_obligations(),
636                         );
637                     }
638                     (GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => {
639                         let ok = self.at(cause, param_env).eq(DefineOpaqueTypes::Yes, v1, v2)?;
640                         obligations.extend(ok.into_obligations());
641                     }
642                     _ => {
643                         bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,);
644                     }
645                 }
646             }
647             Ok(InferOk { value: (), obligations })
648         })
649     }
650 }
651 
652 /// Given the region obligations and constraints scraped from the infcx,
653 /// creates query region constraints.
make_query_region_constraints<'tcx>( tcx: TyCtxt<'tcx>, outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>, ConstraintCategory<'tcx>)>, region_constraints: &RegionConstraintData<'tcx>, ) -> QueryRegionConstraints<'tcx>654 pub fn make_query_region_constraints<'tcx>(
655     tcx: TyCtxt<'tcx>,
656     outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>, ConstraintCategory<'tcx>)>,
657     region_constraints: &RegionConstraintData<'tcx>,
658 ) -> QueryRegionConstraints<'tcx> {
659     let RegionConstraintData { constraints, verifys, member_constraints } = region_constraints;
660 
661     assert!(verifys.is_empty());
662 
663     debug!(?constraints);
664 
665     let outlives: Vec<_> = constraints
666         .iter()
667         .map(|(k, origin)| {
668             let constraint = match *k {
669                 // Swap regions because we are going from sub (<=) to outlives
670                 // (>=).
671                 Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
672                     ty::Region::new_var(tcx, v2).into(),
673                     ty::Region::new_var(tcx, v1),
674                 ),
675                 Constraint::VarSubReg(v1, r2) => {
676                     ty::OutlivesPredicate(r2.into(), ty::Region::new_var(tcx, v1))
677                 }
678                 Constraint::RegSubVar(r1, v2) => {
679                     ty::OutlivesPredicate(ty::Region::new_var(tcx, v2).into(), r1)
680                 }
681                 Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
682             };
683             (constraint, origin.to_constraint_category())
684         })
685         .chain(outlives_obligations.map(|(ty, r, constraint_category)| {
686             (ty::OutlivesPredicate(ty.into(), r), constraint_category)
687         }))
688         .collect();
689 
690     QueryRegionConstraints { outlives, member_constraints: member_constraints.clone() }
691 }
692 
693 struct QueryTypeRelatingDelegate<'a, 'tcx> {
694     infcx: &'a InferCtxt<'tcx>,
695     obligations: &'a mut Vec<PredicateObligation<'tcx>>,
696     param_env: ty::ParamEnv<'tcx>,
697     cause: &'a ObligationCause<'tcx>,
698 }
699 
700 impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
span(&self) -> Span701     fn span(&self) -> Span {
702         self.cause.span
703     }
704 
param_env(&self) -> ty::ParamEnv<'tcx>705     fn param_env(&self) -> ty::ParamEnv<'tcx> {
706         self.param_env
707     }
708 
create_next_universe(&mut self) -> ty::UniverseIndex709     fn create_next_universe(&mut self) -> ty::UniverseIndex {
710         self.infcx.create_next_universe()
711     }
712 
next_existential_region_var( &mut self, from_forall: bool, _name: Option<Symbol>, ) -> ty::Region<'tcx>713     fn next_existential_region_var(
714         &mut self,
715         from_forall: bool,
716         _name: Option<Symbol>,
717     ) -> ty::Region<'tcx> {
718         let origin = NllRegionVariableOrigin::Existential { from_forall };
719         self.infcx.next_nll_region_var(origin)
720     }
721 
next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx>722     fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
723         ty::Region::new_placeholder(self.infcx.tcx, placeholder)
724     }
725 
generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>726     fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
727         self.infcx.next_nll_region_var_in_universe(
728             NllRegionVariableOrigin::Existential { from_forall: false },
729             universe,
730         )
731     }
732 
push_outlives( &mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>, _info: ty::VarianceDiagInfo<'tcx>, )733     fn push_outlives(
734         &mut self,
735         sup: ty::Region<'tcx>,
736         sub: ty::Region<'tcx>,
737         _info: ty::VarianceDiagInfo<'tcx>,
738     ) {
739         self.obligations.push(Obligation {
740             cause: self.cause.clone(),
741             param_env: self.param_env,
742             predicate: ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(sup, sub))
743                 .to_predicate(self.infcx.tcx),
744             recursion_depth: 0,
745         });
746     }
747 
forbid_inference_vars() -> bool748     fn forbid_inference_vars() -> bool {
749         true
750     }
751 
register_obligations(&mut self, obligations: PredicateObligations<'tcx>)752     fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
753         self.obligations.extend(obligations);
754     }
755 }
756