Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CoerceUnsized

CoerceUnsized は主にデータコンテナに関係します。構造体 (通常はスマートポインター)が CoerceUnsized を実装している場合、それは その構造体が指すデータが unsize されることを意味します。

CoerceUnsized を実装している型には、以下のようなものがあります。

  • &T
  • Arc<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 つのものが「アップキャスト」と呼ばれています。

  1. 真のアップキャスト dyn SubTrait -> dyn SuperTrait(これは、以下のように 自動トレイトの削除とライフタイムの調整も許可します)。
  2. dyn trait の自動トレイトを削除し、ライフタイムを調整すること (principal2 は変更しない): dyn Trait + AutoTraits... + 'a -> dyn Trait + NewAutoTraits... + 'b ここで AutoTraitsNewAutoTraits であり、'a: 'b です。

これらは異なる操作のように見えるかもしれません。なぜなら (1.) は dyn trait の vtable の調整を含む一方で、(2.) は no-op だからです。しかし、型システムにとっては、 これらはほぼ同じコードで処理されます。

この Unsize の組み込み実装は、特に関連型の複雑さをサポートするために 再設計された後、 最も入り組んだものになっています。

具体的には、アップキャストアルゴリズムには次の処理が含まれます。ソース dyn trait の principal の各 supertrait(それ自身を含む)について…

  1. super trait ref をターゲットの principal と単一化します(真の supertrait にのみ アップキャストし、決して impl 経由ではアップキャストしないことを確認します)。
  2. ターゲット内のすべての自動トレイトについて、それがソースに存在することを確認します (これにより自動トレイトを削除できますが、新しいものを得ることはできません)。
  3. ターゲット内のすべての射影について、それがソース内の単一の射影と単一化されることを 確認します(trait Sub: Sup<.., A = i32> + Sup<.., A = u32> が与えられている場合のように、 複数存在する可能性があるためです)。

具体的には、(3.) は、推論を不必要に導くために射影境界を選択することを防ぎますが、 曖昧でない場合には推論を導くことがあります。


  1. 以前は「object safe」として知られていました。

  2. principal は、dyn Trait の 1 つの非自動トレイトです。