[Sketch] Minimal pimpl-style "stable ABI"

Rust should explore "stabilizable" layout for both data types and trait objects, including cleaner type erasure, but actually stabilizing anything sounds years away.

I think https://github.com/rust-lang/rfcs/issues/600 shows that pub(dyn) makes no sense, but annotations like #[repr(redox-v1)] pub enum .. and #[repr(redox-v1)] dyn Trait or #[repr(redox-v1)] trait .. make sense.

There is much to learn from Swift ala https://gankra.github.io/blah/swift-abi/ too, especially their improved handling of unsized types on the stack, and their LLVM hacks adding return path optimizations for Result<_,SomeDynError>. Yet, I think their implicit getters and setters approach violates Rust's core objectives.

In my view, Rust should instead pursue

  • fields in traits with field offsets in trait objects eventually, including bit offsets for bools, discriminants, etc.
  • manual annotations for layout, including only partially annotated layout, and note manual enum discriminants was accepted in https://github.com/rust-lang/rfcs/pull/2363
  • improve handling of unsized types, ideally even on the stack

If you need ABI stability then you'd either specify a #[repr(..)], a layout for all pub fields, and sometimes a size, or else define an object safe trait with a #[repr(..)].

In principle one could even make traits like this object safe by adding an invisible fn process_size(&self) -> usize and fn new_size(self: &dyn(vtable_only) Foo) -> usize methods, along with some &dyn(vtable_only) Trait type.

#[repr(Rust-v2)]
pub trait Foo : ?Sized {
    x,y: f64;
    mut okay : bool;
    fn new() -> dyn Self;
    fn process(self: dyn Self) -> dyn Self;
}
1 Like