I'm currently working on a custom DSTs. In my opinion, std lacks some APIs for working with fat pointers which makes coding DSTs hard.
e.g. the one way to create *const Dst
from the data
part (*const ()
) and the meta
(vtable/length) part (usize
) is to use core::slice::from_raw_parts
and then cast it's result (the idea is stolen from dtolnay):
let slice = unsafe { core::slice::from_raw_parts(data, meta) };
slice as *const [()] as *const Dst
This works, though
- using slice seems like a hack
- while the layout of
*const [T]
seems to be defined, the layout of*const Dst
doesn't seem to be defined, so the code doesn't seem right - it doesn't allow to construct ptr to DST which contain
dyn Trait
Another thing that I personally miss is extracting meta
from a fat pointer.
More precisely I'm looking for similar APIs:
impl<T: ?Sized> *const T {
// I'm bad at naming but hopefully you've got the idea :)
/// ignores meta field for `T: Sized`
pub fn fat_from_parts(data: *const (), meta: usize) -> Self;
/// returns None for `T: Sized`
pub fn meta(self) -> Option<usize>;
}
This could make my code a lot clearer
Though, design like this has some downsides:
- this more or less disallows fat pointers with meta that is not an
usize
(or pointer) - this approach is much simpler/more dump/less typed than RFC for custom DSTs that I could find:
Is it worth creating an RFC? Or this is too restrictive?