Get minimum size of DST?


#1

Is there any way to get the minimum possible size of a DST (analogous to mem::size_of)? E.g., [u8] has a minimum size of 0, and struct Foo { a: usize, b: [u8] } has a minimum size of size_of::<usize>().


#2

So in other words, you want the size of the fixed portion. I’m not aware of any direct way to obtain such a thing - the compiler calculates the size of the full DST value on-the-fly (naturally so). Perhaps you can create a minimally sized value and then take its std::mem::size_of_val():

struct Foo<T: ?Sized> {
    a: usize,
    b: T,
}

fn main() {
    // empty slice
    let f = Foo { a: 0, b: [0u8; 0] };
    let f: &Foo<[u8]> = &f;
    println!("{}", std::mem::size_of_val(f));
    
    // ZST for the DST as a trait object
    let f = Foo {a: 0, b: ()};
    let f: &Foo<std::fmt::Debug> = &f;
    println!("{}", std::mem::size_of_val(f));
}

#3

Unfortunately I need this for an arbitrary T that I don’t control. But it’s a good idea if I did control it!


#4

You mean the T is the DST and you somehow know it’s a DST?


#5

Concretely, what I’m trying to do is say “is this T at least as large as x?” I don’t care whether T is a DST or not. If need be, I could split what I’m doing into two functions - one for DSTs and one for sized types - but if possible, I’m trying to just have a <T: ?Sized> param.


#6

Yeah, I don’t know how to do that. It seems like you’d need compiler support (eg an intrinsic) to answer that type of question. Moreover, T: ?Sized includes things like a trait type, for which asking this question doesn’t even make sense. Perhaps once further custom DST support is being worked on, this type of thing can be kept in mind.

What’s the context for this btw? Is this for your allocator work?


#7

Nah, it’s for pre-RFC FromBits/IntoBits. The TLDR is that I’m trying to statically verify that I can safely transmute a reference of one type into a reference of another for zero-copy parsing purposes.