fn receiver_is_dispatchable<'tcx>(
tcx: TyCtxt<'tcx>,
method: AssocItem,
receiver_ty: Ty<'tcx>,
) -> boolExpand description
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:
-
let
Receiverbe the type of theselfargument, i.eSelf,&Self,Rc<Self>, -
require the following bound:
ⓘReceiver[Self => T]: DispatchFromDyn<Receiver[Self => dyn Trait]>where
Foo[X => Y]means “the same type asFoo, but withXreplaced withY” (instantiation notation).
Some examples of receiver types and their required obligation:
&'a mut selfrequires&'a mut Self: DispatchFromDyn<&'a mut dyn Trait>,self: Rc<Self>requiresRc<Self>: DispatchFromDyn<Rc<dyn Trait>>,self: Pin<Box<Self>>requiresPin<Box<Self>>: DispatchFromDyn<Pin<Box<dyn Trait>>>.
The only case where the receiver is not dispatchable, but is still a valid receiver
type (just not dyn compatible), 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.
If lowering already produced an error in the receiver type, we conservatively treat it as undispatchable instead of asking the solver.
In practice, we cannot use dyn Trait explicitly in the obligation because it would result in
a new check that Trait is dyn-compatible, creating a cycle.
Instead, we emulate a placeholder by introducing a new type parameter U such that
Self: Unsize<U> and U: Trait + MetaSized, and use U in place of dyn Trait.
Written as a chalk-style query:
forall (U: Trait + MetaSized) {
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>>>