By saying LLVM-like inheritance hierarchy, I mean the way to obtain runtime polymorphism described in this documentation: https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html.
It is easy to implement the same feature in Rust using enums, like:
enum Shape {
Square(Square),
Circle(Circle)
}
enum Square {
SquareA(SquareAData),
SquareB(SquareBData),
}
enum Circle {
CircleA(CircleAData),
CircleB(CircleBData),
}
// assume ***Data can be arbitrarily complex
However, the memory layout is inevitably different from LLVM-like inheritance hierarchy, which uses a single integer field to record the discriminant of the type. Though current rustc already has a lot of optimizations on the size of enums, there will still be two integer field to record the discriminant in a Shape
object in the above example.
I have tried some ways without success, in which the closet to LLVM-like inheritance hierarchy in my mind is to enable nightly feature arbitrary_enum_discriminant
and assign each variant of the enum an discriminant:
#![feature(arbitrary_enum_discriminant)]
enum Shape {
Square(Square),
Circle(Circle)
}
#[repr(usize)]
enum Square {
SquareA(SquareAData) = 0,
SquareB(SquareBData) = 1,
}
#[repr(usize)]
enum Circle {
CircleA(CircleAData) = 2,
CircleB(CircleBData) = 3,
}
It is perfectly possible for Shape
to go without its own discriminant, since its two variants have non-intersecting discriminant sets. However, rustc still assigns a integer discriminant to it, making it larger than Square
or Circle
. (rustc version: rustc 1.44.0-nightly (f509b26a7 2020-03-18)
)
So my question is: is it on earth possible in Rust to use enums to model LLVM-like inheritance hierarchy, with only a single integer discriminant in the top level "class"?