Hi, I have hitting that issue as well (especially when working on shakacode/messagebus). Here is how it may look like (al least on my opinion):
TraitObject
has vtable
for each type's impl - we can add typeid and next_sibling/prev_sibling to this vtable impl block. It will be possible to iterate through all dyn implementations for given type. And dynamic_cast
function may look like (just draft):
pub unsafe fn dynamic_cast_ref<T: ?Sized + Unsized, U: ?Sized + Unsized>(tp: &T) -> Option<&U> {
let target = TypeId::of::<U>();
let to: TraitObject = mem::transmute(tp);
let mut v = to.vtable;
loop {
let td: Option<&DynDeclType> = mem::transmute(v.offset(NEXT_SIBLING_OFFSET));
let td = if let Some(val) = td {
val
} else {
break;
};
if td.type_id == target {
return Some(mem::transmute(TraitObject {data: to.data, vtable: td.vtable});
} else {
v = td.vtable;
}
}
// and same for prev_sibling as well
None
}