Можно ли смоделировать LLVM-подобную иерархию наследования в Rust, используя перечисления? - PullRequest
0 голосов
/ 10 апреля 2020

Говоря об иерархии, подобной LLVM, я имею в виду способ получения полиморфизма во время выполнения, описанный в этой документации: https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html.

Легко реализовать то же самое функция в Rust с использованием перечислений, например:

enum Shape {
  Square(Square),
  Circle(Circle)
}

enum Square {
  SquareA(SquareAData),
  SquareB(SquareBData),
}

enum Circle {
  CircleA(CircleAData),
  CircleB(CircleBData),
}
// assume ***Data can be arbitrarily complex

Однако макет памяти неизбежно отличается от иерархии наследования, подобной LLVM, которая использует одно целочисленное поле для записи дискриминант типа. Хотя текущая ржавчина c уже имеет много оптимизаций по размеру перечислений, все равно будет два целочисленных поля для записи дискриминанта в Shape объекте в приведенном выше примере.

Я пробовал несколько пути без успеха, в которых у меня на уме скрытность от LLVM-подобной иерархии наследования - включить ночные функции arbitrary_enum_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,
}

Это вполне возможно для * От 1020 * до go без собственного дискриминанта, так как два его варианта имеют непересекающиеся множества дискриминантов. Однако ржавчина c все еще присваивает ему целочисленный дискриминант, делая его больше, чем Square или Circle. (rust c версия: rustc 1.44.0-nightly (f509b26a7 2020-03-18))

Поэтому мой вопрос: возможно ли в Rust использование enum для моделирования иерархии, подобной LLVM, с единственным целочисленным дискриминантом на верхнем уровне? "класс"?

...