[Solved] Trait object vtables and the Any trait

fn is_same_type(x: &dyn Trait + 'static, y: &dyn Trait + 'static) -> bool {
    let x_vtable = get_vtable(x); // get_vtable: fn(*const Trait) -> *const ()
    let y_vtable = get_vtable(y); // currently we can achieve this in nightly via std::raw::TraitObject
    
    x_vtable == y_vtable
}

Would this function be valid? This works off of this assumption: two trait objects refer to the same type if and only if the v-tables inside the trait object are the same (ignoring lifetimes).

If it is valid, could we change the implementation of <dyn Any:>:is::<T>() to work based off of this.

impl dyn Any + 'static {
    pub fn is<T: Any>(&self) -> bool {
        let self_vtable = get_vtable(self);
        
        // this is fine because vtables of fat pointers (from trait objects) are always
        // well-formed and this is guaranteed, even for null pointers
        let t_vtable = get_vtable(std::ptr::null::<T>() as *const dyn Any);
        
        self_vtable == t_vtable
    }
}

That way you can use TypeId as a way to get a coarse measurement of whether the types are the same, but you can check them for sure with <dyn Any>::is::<T>.

We could even go one step further and add

impl dyn Any + 'static {
    pub fn is_same_type(&self, other: &Self) -> bool {
        let self_vtable = get_vtable(self);
        let other_vtable = get_vtable(other);
        
        self_vtable == other_vtable
    }
}

And this would provide some functionality that is missing. Checking if two types are the same without loss of precision due to using TypeId.

We could guarantee that this always works. But that would require the assumption at the beginning to be true.

Two trait objects refer to the same type if and only if the v-tables inside the trait object are the same (ignoring lifetimes)

No - vtables are not guaranteed to be unique, and can in practice be duplicated across codegen units.

4 Likes

Ok, thank you!

In practice they can also be duplicated because one vtable might be generated during CTFE and another one from a run-time coercion.

1 Like