It's not straightforward to compute the size of a struct field. This works for the cases I care about, but it took me quite some head-scratching to make it usable in a const context[1], and it cannot handle nested field access (contrast offset_of!, which can, but possibly only because it expands to a compiler intrinsic; $field:expr does not work at all):
So I'm wondering whether there should be an official API for getting the size of a struct field, and if so, how it should be spelled. core::mem::size_of_field! goes naturally with the existing size_of, offset_of, etc. and I imagine could be added as an ACP. Or, it'd be a much bigger change, and there may be obstacles I am not seeing, but I feel like it might be useful for a bunch of things, not just this, if StructType::field_name meant "the type of field field_name of StructType" when it appears in a type context. What do you think?
It is not that I don't know the type but rather that I do not want to name the type anywhere besides the definition of the struct itself. Like for example if I have
struct S {
// ... other fields ...
blob: [u8; 32],
}
No, because there’s no val in a function signature.
This does seem like there’s a narrow question of “how can I get the length of an array that’s in a struct”, which in turn could be derived from “how can I get the size of a struct field”, which likewise would be trivial if we had “how can I get the type of a struct field (in a type context)”, which itself could be a specific form of “how do I get the type of an expression”. I’m not saying that we should jump to the highest abstraction here, but if we think there’ll be meaningful progress on one of the more general features, maybe we don’t need to build the specific one.
Just to be clear, I do in fact need "how can I get the size of any struct field" for my current project, and not just "how can I get the length of an array that happens to be a struct field". I do not currently need the former in const context, but it is extremely annoying whenever an intrinsic that always evaluates to a compile-time constant isn't actually usable in const context.
My use case for the general "how can I get the size of any struct field" is validation of FFI struct layout. I have a build script that parses a C header, makes a list of every field of every struct defined in that header, and generates a C source file that computes the size and offset of each field and packs them all into a table. On the Rust side, there are hand-written #[repr(C)] Rust structs for each C struct. (I can't use bindgen because of weirdnesses in the C header.)
My unit tests then compare the layout of each Rust struct with the corresponding C struct using code like this:
since noone has mentioned it yet: the ideomatic way to do this would probably be with a derive macro and a trait, although that ofc doesn't work in const contexts (yet)
I feel that I should not have to drag in all the machinery of procedural macros just to persuade the compiler to give me a piece of information that it has to carry around internally anyway.