Skip to content

UnsafeUnion type #371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
glaebhoerl opened this issue Oct 8, 2014 · 4 comments
Closed

UnsafeUnion type #371

glaebhoerl opened this issue Oct 8, 2014 · 4 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@glaebhoerl
Copy link
Contributor

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 both A and B. 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(). So transmute::<A, UnsafeUnion<A, B>>, transmute::<B, UnsafeUnion<A, B>>, transmute::<UnsafeUnion<A, B>, A>, and transmute::<UnsafeUnion<A, B>, B> all have well-defined behavior, in basically the same circumstances as in C. (This means that the input and output of transmute would 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 legally transmute &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 of transmute for {,de}construction is also completely impervious to this nesting. We could then also potentially provide synonyms like type 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.

@nrc
Copy link
Member

nrc commented 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
Copy link
Contributor Author

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 UnsafeUnion and CUnsafeUnion types, 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
Copy link
Contributor

mahkoh commented 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
Copy link
Contributor

Triage: fixed by #1444

@nrc nrc closed this as completed Aug 19, 2016
@nrc nrc added the T-lang Relevant to the language team, which will review and decide on the RFC. label Aug 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

4 participants