fn find_vtable_types_for_unsizing<'tcx>(
    tcx: TyCtxtAt<'tcx>,
    source_ty: Ty<'tcx>,
    target_ty: Ty<'tcx>
) -> (Ty<'tcx>, Ty<'tcx>)
Expand description

For a given pair of source and target type that occur in an unsizing coercion, this function finds the pair of types that determines the vtable linking them.

For example, the source type might be &SomeStruct and the target type might be &dyn SomeTrait in a cast like:

let src: &SomeStruct = ...;
let target = src as &dyn SomeTrait;

Then the output of this function would be (SomeStruct, SomeTrait) since for constructing the target fat-pointer we need the vtable for that pair.

Things can get more complicated though because there’s also the case where the unsized type occurs as a field:

struct ComplexStruct<T: ?Sized> {
   a: u32,
   b: f64,
   c: T
}

In this case, if T is sized, &ComplexStruct<T> is a thin pointer. If T is unsized, &SomeStruct is a fat pointer, and the vtable it points to is for the pair of T (which is a trait) and the concrete type that T was originally coerced from:

let src: &ComplexStruct<SomeStruct> = ...;
let target = src as &ComplexStruct<dyn SomeTrait>;

Again, we want this find_vtable_types_for_unsizing() to provide the pair (SomeStruct, SomeTrait).

Finally, there is also the case of custom unsizing coercions, e.g., for smart pointers such as Rc and Arc.