@@ -206,16 +206,44 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
206
206
} )
207
207
}
208
208
209
- /// NLL does a lot of queries that have a particular form that we
210
- /// can take advantage of to be more efficient. These queries do
211
- /// not have any *type* inference variables, only region inference
212
- /// variables. Therefore, when we instantiate the query result, we
213
- /// only ever produce new *region constraints* and never other
214
- /// forms of obligations (moreover, since we only determine
215
- /// satisfiability modulo region constraints, instantiation is
216
- /// infallible). Therefore, the return value need only be a larger
217
- /// set of query region constraints. These constraints can then be
218
- /// added directly to the NLL inference context.
209
+ /// An alternative to
210
+ /// `instantiate_query_result_and_region_obligations` that is more
211
+ /// efficient for NLL. NLL is a bit more advanced in the
212
+ /// "transition to chalk" than the rest of the compiler. During
213
+ /// the NLL type check, all of the "processing" of types and
214
+ /// things happens in queries -- the NLL checker itself is only
215
+ /// interested in the region obligations (`'a: 'b` or `T: 'b`)
216
+ /// that come out of these queries, which it wants to convert into
217
+ /// MIR-based constraints and solve. Therefore, it is most
218
+ /// convenient for the NLL Type Checker to **directly consume**
219
+ /// the `QueryRegionConstraint` values that arise from doing a
220
+ /// query. This is contrast to other parts of the compiler, which
221
+ /// would prefer for those `QueryRegionConstraint` to be converted
222
+ /// into the older infcx-style constraints (e.g., calls to
223
+ /// [`sub_regions()`] or [`register_region_obligation()`]).
224
+ ///
225
+ /// Therefore, `instantiate_nll_query_result_and_region_obligations` performs the same
226
+ /// basic operations as `instantiate_query_result_and_region_obligations` but
227
+ /// it returns its result differently:
228
+ ///
229
+ /// - It creates a substitution `S` that maps from the original
230
+ /// query variables to the values computed in the query
231
+ /// result. If any errors arise, they are propagated back as an
232
+ /// `Err` result.
233
+ /// - In the case of a successful substitution, we will append
234
+ /// `QueryRegionConstraint` values onto the
235
+ /// `output_query_region_constraints` vector for the solver to
236
+ /// use (if an error arises, some values may also be pushed, but
237
+ /// they should be ignored).
238
+ /// - It **can happen** (though it rarely does currently) that
239
+ /// equating types and things will give rise to subobligations
240
+ /// that must be processed. In this case, those subobligations
241
+ /// are propagated back in the return value.
242
+ /// - Finally, the query result (of type `R`) is propagated back,
243
+ /// after applying the substitution `S`.
244
+ ///
245
+ /// [`register_region_obligation()`: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/infer/struct.InferCtxt.html#method.register_region_obligation
246
+ /// [`sub_regions()`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/infer/struct.InferCtxt.html#method.sub_regions
219
247
pub fn instantiate_nll_query_result_and_region_obligations < R > (
220
248
& self ,
221
249
cause : & ObligationCause < ' tcx > ,
0 commit comments