|
25 | 25 | //! M, into constraints in our source context. This process of
|
26 | 26 | //! translating the results back is done by the
|
27 | 27 | //! `instantiate_query_result` method.
|
| 28 | +//! |
| 29 | +//! For a more detailed look at what is happening here, check |
| 30 | +//! out the [chapter in the rustc guide][c]. |
| 31 | +//! |
| 32 | +//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html |
28 | 33 |
|
29 | 34 | use infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TypeVariableOrigin};
|
30 | 35 | use rustc_data_structures::indexed_vec::Idx;
|
@@ -270,64 +275,10 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
270 | 275 | /// have been ambiguous; you should check the certainty level of
|
271 | 276 | /// the query before applying this function.)
|
272 | 277 | ///
|
273 |
| - /// It's easiest to explain what is happening here by |
274 |
| - /// example. Imagine we start out with the query `?A: Foo<'static, |
275 |
| - /// ?B>`. We would canonicalize that by introducing two variables: |
276 |
| - /// |
277 |
| - /// ?0: Foo<'?1, ?2> |
278 |
| - /// |
279 |
| - /// (Note that all regions get replaced with variables always, |
280 |
| - /// even "known" regions like `'static`.) After canonicalization, |
281 |
| - /// we also get back an array with the "original values" for each |
282 |
| - /// canonicalized variable: |
283 |
| - /// |
284 |
| - /// [?A, 'static, ?B] |
285 |
| - /// |
286 |
| - /// Now we do the query and get back some result R. As part of that |
287 |
| - /// result, we'll have an array of values for the canonical inputs. |
288 |
| - /// For example, the canonical result might be: |
289 |
| - /// |
290 |
| - /// ``` |
291 |
| - /// for<2> { |
292 |
| - /// values = [ Vec<?0>, '1, ?0 ] |
293 |
| - /// ^^ ^^ ^^ these are variables in the result! |
294 |
| - /// ... |
295 |
| - /// } |
296 |
| - /// ``` |
297 |
| - /// |
298 |
| - /// Note that this result is itself canonical and may include some |
299 |
| - /// variables (in this case, `?0`). |
| 278 | + /// To get a good understanding of what is happening here, check |
| 279 | + /// out the [chapter in the rustc guide][c]. |
300 | 280 | ///
|
301 |
| - /// What we want to do conceptually is to (a) instantiate each of the |
302 |
| - /// canonical variables in the result with a fresh inference variable |
303 |
| - /// and then (b) unify the values in the result with the original values. |
304 |
| - /// Doing step (a) would yield a result of |
305 |
| - /// |
306 |
| - /// ``` |
307 |
| - /// { |
308 |
| - /// values = [ Vec<?C>, '?X, ?C ] |
309 |
| - /// ^^ ^^^ fresh inference variables in `self` |
310 |
| - /// .. |
311 |
| - /// } |
312 |
| - /// ``` |
313 |
| - /// |
314 |
| - /// Step (b) would then unify: |
315 |
| - /// |
316 |
| - /// ``` |
317 |
| - /// ?A with Vec<?C> |
318 |
| - /// 'static with '?X |
319 |
| - /// ?B with ?C |
320 |
| - /// ``` |
321 |
| - /// |
322 |
| - /// But what we actually do is a mildly optimized variant of |
323 |
| - /// that. Rather than eagerly instantiating all of the canonical |
324 |
| - /// values in the result with variables, we instead walk the |
325 |
| - /// vector of values, looking for cases where the value is just a |
326 |
| - /// canonical variable. In our example, `values[2]` is `?C`, so |
327 |
| - /// that we means we can deduce that `?C := ?B and `'?X := |
328 |
| - /// 'static`. This gives us a partial set of values. Anything for |
329 |
| - /// which we do not find a value, we create an inference variable |
330 |
| - /// for. **Then** we unify. |
| 281 | + /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#processing-the-canonicalized-query-result |
331 | 282 | pub fn instantiate_query_result<R>(
|
332 | 283 | &self,
|
333 | 284 | cause: &ObligationCause<'tcx>,
|
@@ -509,6 +460,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
509 | 460 | /// T: Trait<'?0>
|
510 | 461 | ///
|
511 | 462 | /// with a mapping M that maps `'?0` to `'static`.
|
| 463 | + /// |
| 464 | + /// To get a good understanding of what is happening here, check |
| 465 | + /// out the [chapter in the rustc guide][c]. |
| 466 | + /// |
| 467 | + /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#canonicalizing-the-query |
512 | 468 | pub fn canonicalize_query<V>(&self, value: &V) -> (V::Canonicalized, CanonicalVarValues<'tcx>)
|
513 | 469 | where
|
514 | 470 | V: Canonicalize<'gcx, 'tcx>,
|
@@ -541,6 +497,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
541 | 497 | /// things) includes a mapping to `'?0 := 'static`. When
|
542 | 498 | /// canonicalizing this query result R, we would leave this
|
543 | 499 | /// reference to `'static` alone.
|
| 500 | + /// |
| 501 | + /// To get a good understanding of what is happening here, check |
| 502 | + /// out the [chapter in the rustc guide][c]. |
| 503 | + /// |
| 504 | + /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#canonicalizing-the-query-result |
544 | 505 | pub fn canonicalize_response<V>(
|
545 | 506 | &self,
|
546 | 507 | value: &V,
|
|
0 commit comments