TL;DR
Rust で、トレイトをトレイトオブジェクト(dyn Trait)にするために満たすべき条件。以前はオブジェクト安全性(object safety)と呼ばれ、今の Rust Reference では dyn compatibility と呼ばれている。
仕組み
大まかには、次の 2 つのルールに従うトレイトだけがトレイトオブジェクトにできる。
- ジェネリックなメソッド(
fn some_fn<T>(t: T)など)を持たない - 戻り値や、レシーバ以外の引数の型に
Selfを使わない
Rust Reference には、さらに細かい条件がある。スーパートレイトもすべて dyn compatible であること、Sized をスーパートレイトに持たないこと、関連定数を持たないことなどである。where Self: Sized を付けたメソッドはトレイトオブジェクトから呼べなくなる代わりに、条件の対象から外れる。
例
次のトレイトは、どのメソッドも条件を破っているのでトレイトオブジェクトにできない。
trait DynIncompatible {
const CONST: i32 = 1; // 関連定数を持てない
fn foo() {} // Sized の境界がない関連関数
fn returns(&self) -> Self; // 戻り値に Self
fn typed<T>(&self, x: T) {} // ジェネリックな型パラメータ
}