特殊化
TODO: Chalk はどこに位置付けられるか? ここで言及/議論すべきか?
specialize モジュールで定義されています。
基本戦略は、コヒーレンスチェック中に特殊化グラフを構築していくことです(コヒーレンスチェックは重複する impl を探します)。 グラフへの挿入では、特殊化階層内で impl を置くべき適切な場所を特定します。適切な場所がない場合(部分的に重複しているが包含関係がないため)、重複エラーになります。特殊化は impl を選択するときに参照されるのはもちろんですが、デフォルトを特殊化階層の下位へ伝播するときにもグラフが参照されます。
実際に特殊化を行うとき、つまり選択中に特殊化グラフが使われると予想するかもしれません。これは、次の 2 つの理由から行われていません。
-
これは単なる最適化です。適用される候補の集合が与えられた場合、グラフを参照するのではなく、それらを特殊化について直接比較することで、最も特殊化されたものを判定できます。さらに選択結果もキャッシュしていることを考えると、この最適化の利点は疑わしいものです。
-
そもそも特殊化グラフを構築するには、選択を使う必要があります(一方の impl がもう一方を特殊化しているかどうかを判定する必要があるためです)。この再入性に対処するには、選択のために何らかの追加のモード切り替えが必要になります。いずれにせよグラフを使う強い理由はないように思われるため、選択ではより単純なアプローチを採用し、グラフはデフォルト実装の伝播にのみ使用します。
トレイト impl の選択は、複数の impl が適用可能な場合でも、それらが同じ特殊化ファミリーの一部である限り成功できます。その場合、成功時には単一の impl を返します。これは、適用されることが分かっている最も特殊化された impl です。ただし、推論変数が関与している場合、返された impl はコード生成時に実際に使用する impl ではない可能性があります。したがって、(1) 関連型が default を使用しておらず、そのためオーバーライドできない場合、または (2) すべての入力型が具体的に分かっている場合のいずれかでない限り、関連型を投影しないように特別な注意を払っています。
追加リソース
@sunjay によるこの講演が役に立つかもしれません。この講演は、問題と解決策の大まかな概要を示しているだけである点に留意してください(@sunjay の作業の中間あたりで発表されたものです)。また、これは 2018 年 6 月に行われたものであり、あなたが視聴する時点ではいくつかの点が変わっている可能性があります。