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;
}