[−][src]Function rustc_trait_selection::traits::object_safety::receiver_is_dispatchable

pub(in traits::object_safety) fn receiver_is_dispatchable<'tcx>(
    tcx: TyCtxt<'tcx>,
    method: &AssocItem,
    receiver_ty: Ty<'tcx>
) -> bool

Checks the method's receiver (the self argument) can be dispatched on when Self is a trait object. We require that DispatchableFromDyn be implemented for the receiver type in the following way:

Some examples of receiver types and their required obligation:

The only case where the receiver is not dispatchable, but is still a valid receiver type (just not object-safe), is when there is more than one level of pointer indirection. E.g., self: &&Self, self: &Rc<Self>, self: Box<Box<Self>>. In these cases, there is no way, or at least no inexpensive way, to coerce the receiver from the version where Self = dyn Trait to the version where Self = T, where T is the unknown erased type contained by the trait object, because the object that needs to be coerced is behind a pointer.

In practice, we cannot use dyn Trait explicitly in the obligation because it would result in a new check that Trait is object safe, creating a cycle (until object_safe_for_dispatch is stabilized, see tracking issue https://github.com/rust-lang/rust/issues/43561). Instead, we fudge a little by introducing a new type parameter U such that Self: Unsize<U> and U: Trait + ?Sized, and use U in place of dyn Trait. Written as a chalk-style query:

forall (U: Trait + ?Sized) {
    if (Self: Unsize<U>) {
        Receiver: DispatchFromDyn<Receiver[Self => U]>
    }
}

for self: &'a mut Self, this means &'a mut Self: DispatchFromDyn<&'a mut U> for self: Rc<Self>, this means Rc<Self>: DispatchFromDyn<Rc<U>> for self: Pin<Box<Self>>, this means Pin<Box<Self>>: DispatchFromDyn<Pin<Box<U>>>