Trait core::ops::DispatchFromDyn
source · pub trait DispatchFromDyn<T> { }
dispatch_from_dyn
)Expand description
DispatchFromDyn
is used in the implementation of object safety checks (specifically allowing
arbitrary self types), to guarantee that a method’s receiver type can be dispatched on.
Note: DispatchFromDyn
was briefly named CoerceSized
(and had a slightly different
interpretation).
Imagine we have a trait object t
with type &dyn Tr
, where Tr
is some trait with a method
m
defined as fn m(&self);
. When calling t.m()
, the receiver t
is a wide pointer, but an
implementation of m
will expect a narrow pointer as &self
(a reference to the concrete
type). The compiler must generate an implicit conversion from the trait object/wide pointer to
the concrete reference/narrow pointer. Implementing DispatchFromDyn
indicates that that
conversion is allowed and thus that the type implementing DispatchFromDyn
is safe to use as
the self type in an object-safe method. (in the above example, the compiler will require
DispatchFromDyn
is implemented for &'a U
).
DispatchFromDyn
does not specify the conversion from wide pointer to narrow pointer; the
conversion is hard-wired into the compiler. For the conversion to work, the following
properties must hold (i.e., it is only safe to implement DispatchFromDyn
for types which have
these properties, these are also checked by the compiler):
- EITHER
Self
andT
are either both references or both raw pointers; in either case, with the same mutability. - OR, all of the following hold
Self
andT
must have the same type constructor, and only vary in a single type parameter formal (the coerced type, e.g.,impl DispatchFromDyn<Rc<T>> for Rc<U>
is ok and the single type parameter (instantiated withT
orU
) is the coerced type,impl DispatchFromDyn<Arc<T>> for Rc<U>
is not ok).- The definition for
Self
must be a struct. - The definition for
Self
must not be#[repr(packed)]
or#[repr(C)]
. - Other than one-aligned, zero-sized fields, the definition for
Self
must have exactly one field and that field’s type must be the coerced type. Furthermore,Self
’s field type must implementDispatchFromDyn<F>
whereF
is the type ofT
’s field type.
An example implementation of the trait:
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T>
where
T: Unsize<U>,
{}
Run