Enum rustc_typeck::middle::traits::VtableUnstable
[-] [+]
[src]
pub enum Vtable<'tcx, N> { VtableImpl(VtableImplData<'tcx, N>), VtableDefaultImpl(VtableDefaultImplData<N>), VtableParam(Vec<N>), VtableObject(VtableObjectData<'tcx>), VtableBuiltin(VtableBuiltinData<N>), VtableClosure(DefId, Substs<'tcx>), VtableFnPointer(&'tcx TyS<'tcx>), }
Given the successful resolution of an obligation, the Vtable
indicates where the vtable comes from. Note that while we call this
a "vtable", it does not necessarily indicate dynamic dispatch at
runtime. Vtable
instances just tell the compiler where to find
methods, but in generic code those methods are typically statically
dispatched -- only when an object is constructed is a Vtable
instance reified into an actual vtable.
For example, the vtable may be tied to a specific impl (case A), or it may be relative to some bound that is in scope (case B).
impl<T:Clone> Clone<T> for Option<T> { ... } // Impl_1 impl<T:Clone> Clone<T> for Box<T> { ... } // Impl_2 impl Clone for int { ... } // Impl_3 fn foo<T:Clone>(concrete: Option<Box<int>>, param: T, mixed: Option<T>) { // Case A: Vtable points at a specific impl. Only possible when // type is concretely known. If the impl itself has bounded // type parameters, Vtable will carry resolutions for those as well: concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])]) // Case B: Vtable must be provided by caller. This applies when // type is a type parameter. param.clone(); // VtableParam // Case C: A mix of cases A and B. mixed.clone(); // Vtable(Impl_1, [VtableParam]) }
The type parameter N
See explanation on VtableImplData
.