Have some thought about DST enum again.
The representation of *mut (dyn Trait) type is currently the 2-tuple (*mut (), &'static Vtable<dyn Trait>), where Vtable<_> is the struct:
#[repr(C)]
struct Vtable<D: TraitObject> {
destroy: fn(*mut ()),
size: usize,
align: usize,
methods: D::Methods,
}
IIUC @eddyb, what you mean is that for a DST enum *mut Option<dyn Trait>, it will be represented as a 3-tuple (*mut void, &'static Vtable<dyn Trait>, &'static EnumFields<1>), where EnumFields is the struct:
#[repr(C)]
struct EnumFields<const number_of_fields: usize> {
discriminant: fn(*const ()) -> u64,
field_offsets: [usize; number_of_fields],
}
As an alternative, I think it is possible to make *mut Option<dyn Trait> still a 2-tuple (*mut (), &'static Vtable<dyn Trait>) by implementing the entire niche-filling algorithm at runtime.
-
Modify the Vtable<_> struct by encoding the entire rustc::ty::LayoutDetails:
#[repr(C)]
struct Vtable<D: TraitObject> {
destroy: fn(*mut ()),
size: usize,
align: usize,
layout_details: (Variants, FieldPlacement, Abi),
//^ new.
// could store the minimal analyzed information just enough to
// compute the discriminant offset+size and field offsets
methods: D::Methods,
}
-
The DynSized trait will add a layout_details_of_val method
trait DynSized {
fn layout_details_of_val(r: &Self) -> (Variants, FieldPlacement, Abi);
//^ or maybe restrict to `Self::Meta`
// I haven't checked the implication of taking `&Self` yet
}
-
Change mem::discriminant<T> to a runtime implementation of rustc_mir::interpret::EvalContext::read_discriminant_value, based on {layout_details,size,align}_of_val() of each variant of T.
-
Similarly, the offsets in a variant is to be calculated at runtime using {layout_details,size,align}_of_val() of that variant.
We’d likely disallow customized implementation of layout_details_of_val() in a custom DST.
Cons of this approach:
- The vtables will become one-word larger even if DST enum is never used.
- Needs more space to store the layout details as well.
- Duplicating logic between compile-time and runtime.