重要な変更点と癖
以下の項目の一部はすでに個別に言及されていますが、このページでは古いトレイトシステム実装からの主な変更点を追跡します。また、ソルバーが理想化された実装から大きく逸脱しているいくつかの点についても言及します。このドキュメントは単純化しており、エッジケースを無視しています。各文に暗黙の「ほとんどの場合」を加えて読むことを推奨します。
正準化
新しいソルバーは、ネストされたゴールを評価するときに正準化を使用します。複数の候補が存在する可能性がある場合、各候補は即座に正準化されます。その後、それらの正準応答のマージを試みます。これは、トレイトシステムの内部で正準化を使用しない古い実装とは異なります。
これは、両方のソルバーの設計にいくつかの大きな影響を与えます。候補の制約を退避するために正準化を使用しない場合、候補選択では各候補の制約を破棄する必要があり、選択後に候補を再評価することでのみ制約を適用します: source。正準化を使用しない場合、ゴールの評価から得られる推論制約をキャッシュすることもできません。そのため、古い実装には evaluate と fulfill という 2 つのシステムがあります。Evaluation はキャッシュされ、推論制約を適用せず、候補選択時に使用されます。Fulfillment は推論制約とリージョン制約を適用し、キャッシュされず、推論制約を適用します。
正準化を使用することで、新しい実装は evaluation と fulfillment をマージでき、複雑さや挙動の微妙な違いを避けられます。これによりキャッシュが大幅に単純化され、追跡されていない情報に誤って依存することを防げます。選択後に候補を再評価することを避けられ、複数の候補の応答をマージできるようになります。しかし、評価中にゴールを正準化するため、新しい実装ではトレイト解決中にサイクルに遭遇したときに不動点アルゴリズムを使用する必要があります: source。
遅延されたエイリアス等価性
新しい実装は、エイリアスを関連付けるときに AliasRelate ゴールを発行しますが、古い実装は代わりにエイリアスを構造的に関連付けます。これにより、新しいソルバーは関連付けられたエイリアスを正規化できるようになるまで等価性を停止できます。
古いソルバーの挙動は不完全で、曖昧なエイリアスを推論変数に置き換える即時正規化に依存しています。これは束縛変数を含むエイリアスでは不可能であるため、古い実装はバインダー内のエイリアスを正しく処理しません。例: #102048。詳細については、正規化の章を参照してください。
ネストされたゴールの即時評価
新しい実装は、ネストされたゴールを呼び出し元に返すのではなく即座に処理します。古い実装はその両方を行います。評価ではネストされたゴールは即座に処理されますが、フルフィルメントでは単に後で処理するために返されます。
新しい実装は候補選択のためにネストされたゴールを即座に処理できる必要があるため、常にそうすることで複雑さが軽減されます。また、将来的により多くの候補をマージできるようになる可能性もあります。
ネストされたゴールは不動点に達するまで評価される
新しい実装は、常に不動点に達するまでループ内でゴールを評価します。古い実装は fulfillment ではこれを行いますが、evaluation では行いません。常にそうすることで推論が強化され、トレイトソルバーの順序依存性が低減されます。trait-system-refactor-initiative#102 を参照してください。
証明木と診断情報の提供
新しい実装は診断情報を直接追跡せず、代わりに関連情報を遅延計算するために使用される証明木を提供します。これはまだ完全には具体化されておらず、ややハック的です。目的は、パフォーマンスを向上させるために正常系でこの情報を追跡することを避け、挙動のために診断データへ誤って依存することを避けることです。
新しい実装の主な癖
env 候補が存在する場合に impl を隠す
ある Trait ゴールを証明するための ParamEnv または AliasBound 候補が少なくとも 1 つ存在する場合、Trait と Projection の両方のゴールについて、すべての impl 候補を破棄します: source。これにより、ユーザーが where 境界によって完全に覆われている impl を使用することを防ぎ、古い実装の挙動に一致させ、いくつかの奇妙なエラーを回避します。例: trait-system-refactor-initiative#76。
NormalizesTo ゴールは関数である
正規化の章を参照してください。正規化に影響を与えないように、NormalizesTo ゴールを計算する前に、期待される項を制約のない推論変数に置き換えます。これは、NormalizesTo ゴールが他のすべてのゴール種別とは多少異なる方法で処理され、追加のソルバーサポートが必要であることを意味します。特に、その曖昧なネストされたゴールは呼び出し元に返され、呼び出し元がそれらを評価します。詳細については #122687 を参照してください。