|
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