| # Specialization | |
| **TODO**: where does Chalk fit in? Should we mention/discuss it here? | |
| Defined in the `specialize` module. | |
| The basic strategy is to build up a *specialization graph* during | |
| coherence checking (coherence checking looks for [overlapping impls](../coherence.md)). | |
| Insertion into the graph locates the right place | |
| to put an impl in the specialization hierarchy; if there is no right | |
| place (due to partial overlap but no containment), you get an overlap | |
| error. Specialization is consulted when selecting an impl (of course), | |
| and the graph is consulted when propagating defaults down the | |
| specialization hierarchy. | |
| You might expect that the specialization graph would be used during | |
| selection – i.e. when actually performing specialization. This is | |
| not done for two reasons: | |
| - It's merely an optimization: given a set of candidates that apply, | |
| we can determine the most specialized one by comparing them directly | |
| for specialization, rather than consulting the graph. Given that we | |
| also cache the results of selection, the benefit of this | |
| optimization is questionable. | |
| - To build the specialization graph in the first place, we need to use | |
| selection (because we need to determine whether one impl specializes | |
| another). Dealing with this reentrancy would require some additional | |
| mode switch for selection. Given that there seems to be no strong | |
| reason to use the graph anyway, we stick with a simpler approach in | |
| selection, and use the graph only for propagating default | |
| implementations. | |
| Trait impl selection can succeed even when multiple impls can apply, | |
| as long as they are part of the same specialization family. In that | |
| case, it returns a *single* impl on success – this is the most | |
| specialized impl *known* to apply. However, if there are any inference | |
| variables in play, the returned impl may not be the actual impl we | |
| will use at codegen time. Thus, we take special care to avoid projecting | |
| associated types unless either (1) the associated type does not use | |
| `default` and thus cannot be overridden or (2) all input types are | |
| known concretely. | |
| ## Additional Resources | |
| [This talk][talk] by @sunjay may be useful. Keep in mind that the talk only | |
| gives a broad overview of the problem and the solution (it was presented about | |
| halfway through @sunjay's work). Also, it was given in June 2018, and some | |
| things may have changed by the time you watch it. | |
| [talk]: https://www.youtube.com/watch?v=rZqS4bLPL24 |