CoerceUnsized
CoerceUnsized は主にデータコンテナに関係します。構造体
(通常はスマートポインター)が CoerceUnsized を実装している場合、それは
その構造体が指すデータが unsize されることを意味します。
CoerceUnsized を実装している型には、以下のようなものがあります。
&TArc<T>Box<T>
このトレイトは、(最終的には)ユーザーが作成したスマートポインターによって
実装されることが意図されており、ある型が CoerceUnsized を実装できる条件に
関するルールは、このトレイトのドキュメントで説明されています。
Unsize
対照的に、Unsize トレイトは、unsize できる実際の型に関係します。
これはユーザーが実装することを意図したものではありません。なぜなら Unsize は、
型を どのように unsize するかをコンパイラー(すなわち codegen)に指示する
ものではなく、単に unsize できるかどうかを示すだけだからです。これは、型がどのように
表現され、unsize されるかを理解していなければならない codegen とかなり密接に
組み合わされています。
プリミティブな unsize 実装
組み込み実装は以下に対して提供されています。
T: Traitの場合のT->dyn Trait + 'a(かつT: Sized + 'aであり、Traitが dyn 互換1である場合)。[T; N]->[T]
構造的実装
構造的と考えられる Unsize の実装が 1 つあります。
TailField<Pi, .., Pj>: Unsize<Ui, .. Uj>が成り立つ場合のStruct<.., Pi, .., Pj, ..>: Unsize<Struct<.., Ui, .., Uj, ..>>。これにより、 構造体のテールフィールドがジェネリックパラメーターPi, ..,Pjに言及する 唯一のフィールドである場合、そのテールフィールドを unsize できます (これらのパラメーターは連続している必要はありません)。
構造体の unsize に関するルールは少し複雑です。というのも、それらは 複数のパラメーターの変更(必ずしも unsize とは限りません)を許可する場合があり、 構造体のテールフィールドという観点で述べるのが最も適しているからです。
(タプルの unsize は以前、feature gate unsized_tuple_coercion の背後で
実装されていましたが、その実装は #137728 によって削除されました。)
アップキャスト実装
内部的には、2 つのものが「アップキャスト」と呼ばれています。
- 真のアップキャスト
dyn SubTrait->dyn SuperTrait(これは、以下のように 自動トレイトの削除とライフタイムの調整も許可します)。 - dyn trait の自動トレイトを削除し、ライフタイムを調整すること
(principal2 は変更しない):
dyn Trait + AutoTraits... + 'a->dyn Trait + NewAutoTraits... + 'bここでAutoTraits⊇NewAutoTraitsであり、'a: 'bです。
これらは異なる操作のように見えるかもしれません。なぜなら (1.) は dyn trait の vtable の調整を含む一方で、(2.) は no-op だからです。しかし、型システムにとっては、 これらはほぼ同じコードで処理されます。
この Unsize の組み込み実装は、特に関連型の複雑さをサポートするために
再設計された後、
最も入り組んだものになっています。
具体的には、アップキャストアルゴリズムには次の処理が含まれます。ソース dyn trait の principal の各 supertrait(それ自身を含む)について…
- super trait ref をターゲットの principal と単一化します(真の supertrait にのみ アップキャストし、決して impl 経由ではアップキャストしないことを確認します)。
- ターゲット内のすべての自動トレイトについて、それがソースに存在することを確認します (これにより自動トレイトを削除できますが、新しいものを得ることはできません)。
- ターゲット内のすべての射影について、それがソース内の単一の射影と単一化されることを
確認します(
trait Sub: Sup<.., A = i32> + Sup<.., A = u32>が与えられている場合のように、 複数存在する可能性があるためです)。
具体的には、(3.) は、推論を不必要に導くために射影境界を選択することを防ぎますが、 曖昧でない場合には推論を導くことがあります。