# Function rustc_monomorphize::collector::find_vtable_types_for_unsizing

source ·

    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`.