Dyn Compatible

阅读 28

05-16 12:00


Dyn Compatible

(Jin Qing’s Column, April., 2025)

A dyn-compatible trait can be the base trait of a trait object.

A trait is dyn compatible if it has the following qualities (see reference):

  • All supertraits must also be dyn compatible.
  • Sized must not be a supertrait. In other words, it must not require Self: Sized.
  • It must not have any associated constants.
  • It must not have any associated types with generics.
  • All associated functions must either be dispatchable from a trait object or be explicitly non-dispatchable.
  • The AsyncFn, AsyncFnMut, and AsyncFnOnce traits are not dyn-compatible.

These ways of violation are defined in enum DynCompatibilityViolation:

pub enum DynCompatibilityViolation {
    /// `Self: Sized` declared on the trait.
    SizedSelf(SmallVec<[Span; 1]>),

    /// Supertrait reference references `Self` an in illegal location
    /// (e.g., `trait Foo : Bar<Self>`).
    SupertraitSelf(SmallVec<[Span; 1]>),

    // Supertrait has a non-lifetime `for<T>` binder.
    SupertraitNonLifetimeBinder(SmallVec<[Span; 1]>),

    /// Method has something illegal.
    Method(Symbol, MethodViolationCode, Span),

    /// Associated const.
    AssocConst(Symbol, Span),

    /// GAT
    GAT(Symbol, Span),
}

MethodViolationCode is:

/// Reasons a method might not be dyn-compatible.
#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
pub enum MethodViolationCode {
    /// e.g., `fn foo()`
    StaticMethod(Option<(/* add &self */ (String, Span), /* add Self: Sized */ (String, Span))>),

    /// e.g., `fn foo(&self, x: Self)`
    ReferencesSelfInput(Option<Span>),

    /// e.g., `fn foo(&self) -> Self`
    ReferencesSelfOutput,

    /// e.g., `fn foo(&self) -> impl Sized`
    ReferencesImplTraitInTrait(Span),

    /// e.g., `async fn foo(&self)`
    AsyncFn,

    /// e.g., `fn foo(&self) where Self: Clone`
    WhereClauseReferencesSelf,

    /// e.g., `fn foo<A>()`
    Generic,

    /// the method's receiver (`self` argument) can't be dispatched on
    UndispatchableReceiver(Option<Span>),
}


精彩评论(0)

0 0 举报