Repository navigation
Closed
Labels
T-langRelevant to the language team, which will review and decide on the RFC.Relevant to the language team, which will review and decide on the RFC.
Description
Splicing in my comment from a related RFC:
- Add a built-in type
UnsafeUnion<A, B>. - This is essentially like
unions in C: a type compatible with the size and alignment of bothAandB. So sizeof(UnsafeUnion<A, B>) = max(sizeof(A), sizeof(B)), and alignof(UnsafeUnion<A, B>) = lcm(alignof(A), alignof(B)). - Unlike C, it doesn't have fields, rather "construction" and "deconstruction" both simply happen using
transmute(). Sotransmute::<A, UnsafeUnion<A, B>>,transmute::<B, UnsafeUnion<A, B>>,transmute::<UnsafeUnion<A, B>, A>, andtransmute::<UnsafeUnion<A, B>, B>all have well-defined behavior, in basically the same circumstances as in C. (This means that the input and output oftransmutewould not have the same size/alignment in these cases. I don't know whether this is an issue, provided that they are both known.) transmutes of pointers/references, on the other hand, should only be valid in one direction: e.g. you can legallytransmute&UnsafeUnion<A, B>to&A, but not vice versa.- Because the representation of
UnsafeUnions is idempotent: repr(UnsafeUnion<A, A>) = repr(A), commutative: repr(UnsafeUnion<A, B>) = repr(UnsafeUnion<B, A>), and associative: repr(UnsafeUnion<A, UnsafeUnion<B, C>>) = repr(UnsafeUnion<UnsafeUnion<A, B>, C>), larger unions can simply be composed from the binary one. The use oftransmutefor {,de}construction is also completely impervious to this nesting. We could then also potentially provide synonyms liketype UnsafeUnion3<A, B, C> = UnsafeUnion<A, UnsafeUnion<B, C>>for convenience. - It should also be layout-compatible with C, and so should be usable to represent C unions in the FFI.
This would primarily be for (a) unsafe code and (b) interfacing with C.
Metadata
Metadata
Assignees
Labels
T-langRelevant to the language team, which will review and decide on the RFC.Relevant to the language team, which will review and decide on the RFC.
Activity
nrc commentedon Oct 8, 2014
re the last point - we have been moving in the direction of leaving layouts undefined and requiring an annotation to get a specific (C-compatible) layout, which I think is a good thing. I would recommend the same here.
glaebhoerl commentedon Oct 8, 2014
I agree with that in general, but in this particular case, where would you put the annotation? This is a type, not a language construct -- seems like that would require separate
UnsafeUnionandCUnsafeUniontypes, which seems a bit excessive. I'm also not sure how much room there is for different representations at all, though I'm also not familiar with how C defines it.(The minimum size/alignment are dictated by size and alignment constraints of the contained types - and I guess you could make it even larger or more loosely aligned, but why?)
mahkoh commentedon Oct 8, 2014
As in the other RFC, this should be possible in Rust without special cases in the compiler. Instead of making one RFC per type, one should try to find out what features are necessary to implement this in a library.
Stebalien commentedon Aug 19, 2016
Triage: fixed by #1444