Sealed inheritance


#1

Regarding cheap field access I’m actively performing internal struct inheritance in Rust and this of course uses more general pointers (Rc). One issue is that from the beginning I had to implement methods like as_element(), as_canvas() etc. to perform cast and call them miscellanous times.

Traits and enums aren’t the best solution. For retrieving coordinates from my base DisplayElement I get trait dispatch for each or, for enums, all elements have the same fixed size (i.e., sizeof::<DisplayElement::Sprite>() == sizeof::<DisplayElement::Canvas>()).

Besides variant size being an issue, enums aren’t flexible. Sealed struct inheritance is flexible and fast (allows direct access to x and y in general cases; you could even store offset-bounds like l and h for finally performing partial collision-check w/ display elements and then perform exact collision check using runtime dispatches for the actual element type).

First, of course inheritance is possible in Rust, though the language is missing flexibility with pointers such as Rc; they leak AsRc for implicit convertion. For inheritance a unsafe function such as cast is needed:

unsafe fn cast<'a, Out,  In>(r: &'a Rc<In>) -> Rc<Out> {
    Rc::from_raw(Rc::into_raw(Rc::clone(r)) as
        *const () as *const Out)
}

Then here’s a base class sealed for our crate or module:

#[repr©] pub struct DisplayElement { #[doc(hidden)] pub _kind: ElKind, pub x: Cell, }

`Fro


#2

My phone shut down like a donkey and submitted this thread accidentally. I was still writting it :confused:


#3

Given what you wrote, I’m wondering if you have tried using a trait hierarchy with specialization? I’ve been able emulate inheritance fairly well with it, so it is worth giving it a shot. It can be verbose, but probably some careful macro use could fix that.