Casting TraitObject to Super Trait

I want the following work:

trait Foo {
    fn method_foo(&self) -> String;
}

trait Bar : Foo
{
    fn method_bar(&self)->String;
}

impl  Foo for u8{
    fn method_foo(&self) -> String { format!("u8: {}", *self) }
}

impl Bar for u8{
    fn method_bar(&self) -> String { format!("string: {}", *self) }
}


fn main()
{
    let x= 5u8;
    let b:&Bar=&x as &Bar; //ok
    let f:&Foo=&x as &Foo; //ok
    let fb:&Foo=b as &Foo; //not ok
}

The compiler is throwing the following error:

error[E0605]: non-primitive cast: &dyn Bar as &dyn Foo

Is it possible to cast an trait object to an super trait?

Why do we need an explicit as cast when trait Bar is known to be a suptype of trait Foo?

You can't, see this thread for a work around

But wasn't this solution for downcasting a super trait object to an subtrait object, in my case it is the opposite direction or doesn't matter?

Initially, I thought that the vtable of a trait contains also the methods of the super traits such that a conversion to the super trait can also reuse this vtable, but I'm not sure if this is the case.

If the vtable of a trait does only contain the current trait method pointers it doesn't make sense at all to cast trait object to super traits.

True, but you can do the same thing, provide a method which converts to the super trait and put it in the sub trait.

They do contain the methods, but not in the same order (meaning they have a different in memory layout). So there is no way to perform the conversion automatically.

1 Like

They do contain the methods, but not in the same order (meaning they have a different in memory layout). So there is no way to perform the conversion automatically.

So, say trait T has methods m2, m3 an expect these methods in the same order in the vtable.
Super trait S has methods m1.
As I understand correctly, if a create a trait object O of type T, the methods m2,m3,m1 in the same order will be provided in the vtable of O which is not problem for Trait T, but for S as S expects m1 at position of m2.
So in the end, I need to remove the first two methods in the vtable in order to provide m1 at first or I put them at the end of the vtable.

How can I do that? Is this safe or is there some RTTI information available about the method signatures in the vtable of some trait object? What happened if I'm doing it wrong.

Thanks for your patience.

Trait objects have an unspecified layout, so you can't know the order that the methods show up in the vtable. If you try to rely on the layout, you will invoke UB.

The only way to do this conversion safely is to provide methods that convert to the super trait

You could even extract the conversion functions into their own trait like so.