Replies: 7 comments 3 replies
-
|
It looks like Fuchsia currently uses EDIT: My initial search was too narrow, we also do this when we generate bindings to the Linux uapi. |
Beta Was this translation helpful? Give feedback.
-
|
The ppv-lite86 crate uses |
Beta Was this translation helpful? Give feedback.
-
I have a similar usage to this one in a private project for versioned binary blobs. The classic approach #[derive(TryFromBytes, Immutable, IntoBytes)]
#[repr(C)]
pub enum Blob {
V1(BlobV1),
V2(BlobV2),
}doesn't work because enums cannot be packed so I have to rewrite them as #[derive(TryFromBytes, Immutable, IntoBytes)]
#[repr(C, packed)]
pub struct Blob {
version: BlobVersion,
blob: BlobUnion
}
#[derive(TryFromBytes, IntoBytes, Immutable)]
#[repr(u8)]
pub enum BlobVersion {
V1,
V2,
}
#[derive(TryFromBytes, IntoBytes, Immutable)]
union BlobUnion {
v1: BlobV1,
v2: BlobV2,
}with some extra code for conversions. Also, unsafe impl IntoBytes for BlobUnionmyself and there every field type is checked by |
Beta Was this translation helpful? Give feedback.
-
|
I'm using this in a device driver; the vendor supplies C header files with nested It looks something like this: struct DeviceMessage
{
uint32_t signature; // Can be DEVICE_MESSAGE_DISPLAY, DEVICE_MESSAGE_AUDIO, etc.
// […more shared fields…]
union
{
struct
{
uint8_t parameter;
uint8_t reserved[7];
} display;
struct
{
uint8_t flags;
uint8_t index;
uint8_t reserved[6];
} audio;
// […]
} message_specific;
};The ability to just import these definitions into the rust code with bindgen and emit the byte stream with In my particular case, there is no padding. Every byte is accounted for in every branch, because we don't want to send a buffer containing uninitialised bytes to the device. So I could happily live with this only working with the subset of well-defined unions. For what it's worth, I'd also be entirely fine with implementing
has led me to not pursue this approach for now. (Although I suspect I will have to do something about this soon because the |
Beta Was this translation helpful? Give feedback.
-
I agree that it probably makes sense to enforce that all branches of the union are the same size. |
Beta Was this translation helpful? Give feedback.
-
|
I would like this feature for using zerocopy with mmap'd files, whose formats are defined in C headers and can be easily generated with bindgen. My specific use case is reading and writing ELF files. It would be nice if this was a feature flag instead of a custom Another problem with |
Beta Was this translation helpful? Give feedback.
-
|
Writing in that I also use this feature. My use case is interoperability with a binary file format whose reference implementation is in C++, and relies heavily on essentially transmuting chunks of memory. One of the fields is a In my case, I think it's guaranteed to be a safe operation since both variants of the union are the exact same size. Of course it may not be valid in the sense that the interpretation of the data could be nonsense (logic error) if you don't uphold the invariants. But it is still "safe" in memory terms. (Have I understood the issue correctly? The part that's underspecified seems to be what happens to "extra" bits that are only used by a single variant.) Here is a code sample illustrating the usage. #[bitfield(u32,
repr = U32<LE>,
from = bit_twiddling_helpers::conv_u32le::from_inner,
into = bit_twiddling_helpers::conv_u32le::into_inner
)]
#[derive(FromBytes, IntoBytes, Immutable, Unaligned)]
struct StopImpact {
#[bits(24, from = bit_twiddling_helpers::conv_u32le::from_inner, into = bit_twiddling_helpers::conv_u32le::into_inner)]
impact_between_edges: U32<LE>,
#[bits(8)]
edge_to_right: u8,
}
/// Stores either the stop impact or the transit line identifier.
/// Since transit lines are schedule-based, they have no need for edge transition logic,
/// so we can freely share this field.
#[repr(C)]
#[derive(FromBytes, IntoBytes, Immutable, Unaligned, Copy, Clone)]
union StopOrLine {
stop_impact: StopImpact,
line_id: U32<LE>,
}I'll also second the concern of @m-hilgendorf above with the current approach of a config switch. I can confirm this does not work for libraries, which is also the way I'm using it. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Tracking issue: #1792
TL;DR: If you want to use
IntoByteswith union types, upvote this discussion!In 0.8, we've restricted
#[derive (IntoBytes)]so that it only supports unions when—-cfg zerocopy_derive_union_into_bytesispassed. Union bit validity is up in the air, and it's not currently guaranteed that implementing IntoBytes on unions will remain
sound on all future Rust versions.
The exact bit validity of unions is actively being discussed, and we're advocating for bit validity requirements that will permit
IntoByteson unions to be sound.If you would like to use
IntoByteswith unions, please let us know by upvoting this discussion or by commenting. We will usethis as evidence that there is demand for this feature, and try to persuade Rust to adopt the necessary union bit validity
requirements. Please do not spam other threads besides this one, especially threads in rust-lang repositories. Let's be friendly
participants in this discussion 🙂
Beta Was this translation helpful? Give feedback.
All reactions