DST Structs construction

Hi! I' currently trying to implement a struct where the last field is a DST (dynamic sized type) type, causing the struct to be a DST too. The code looks like

struct Foo {
  bar: u32,
  baz: [i8],
}
impl Foo {
  fn new(bar: u32, baz: &[i8]) -> Arc<Self> {
    todo!();
  }
}

I want to be able to construct this struct with a function new, that given a bar: u33 and a baz: &[i8] returns an Arc. The only solution I've currently found is by manually allocating memory with std::alloc::alloc and doing some unsafe ptr calls, finally casting the pointer to a Box and then the Box to an Arc.
So my questions are:

  1. Is there a better, more safe, way to do this?
  2. If not, can you show me how to correctly construct this with std::alloc::alloc?
  3. Do I need to mark this struct as #[repr(C)] or it can be constructed with #[repr(Rust)]?

Is there any particular reason a Vec doesn't work for you? AFAIK that would be the de-facto safe DST array-like.

Yea I've thought about using a Vec but what's the point of using more space if I don't ever need to reallocate (I don't need to store the capacity)? Also allocating a Vec inside an Arc will make the struct have 2 different allocations with 2 metadatas, while using a DST inside an Arc will just allocate once.
Another reason i would prefer using a DST struct is that I would just like to learn how this rust feature works.

Anyway, maybe this isn't a big deal and I can just implement it as a Vec, but it seems a little strange to me that it is so much difficult to construct a DST struct.

Unfortunately, “custom DSTs are a largely half-baked feature for now” — there is no fully safe way to construct them except via unsizing coercions from arrays (i.e. statically known lengths). The slice-dst library can help with that, but not fully safely for fully custom types. Just today I happened to contribute to a Stack Overflow post which contains information about how both options work.

1 Like