Skip to content
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

other-reprs: do not make it sound like we are making ABI promises for repr(int) enums #461

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions src/other-reprs.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ There's also the [unsafe code guidelines] (note that it's **NOT** normative).

This is the most important `repr`. It has fairly simple intent: do what C does.
The order, size, and alignment of fields is exactly what you would expect from C
or C++. Any type you expect to pass through an FFI boundary should have
or C++. The type is also passed across `extern "C"` function call boundaries the
same way C would pass the corresponding type. Any type you expect to pass through an FFI boundary should have
`repr(C)`, as C is the lingua-franca of the programming world. This is also
necessary to soundly do more elaborate tricks with data layout such as
reinterpreting values as a different type.
Expand Down Expand Up @@ -86,10 +87,14 @@ be 0. However Rust will not allow you to create an enum where two variants have
the same discriminant.

The term "fieldless enum" only means that the enum doesn't have data in any
of its variants. A fieldless enum without a `repr(u*)` or `repr(C)` is
still a Rust native type, and does not have a stable ABI representation.
Adding a `repr` causes it to be treated exactly like the specified
integer type for ABI purposes.
of its variants. A fieldless enum without a `repr` is
still a Rust native type, and does not have a stable layout or representation.
Adding a `repr(u*)`/`repr(i*)` causes it to be treated exactly like the specified
integer type for layout purposes (except that the compiler will still exploit its
knowledge of "invalid" values at this type to optimize enum layout, such as when
this enum is wrapped in `Option`). Note that the function call ABI for these
types is still in general unspecified, except that across `extern "C"` calls they
are ABI-compatible with C enums of the same sign and size.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to point this out here as well, C has non-transitive rules that allow enum and the underlying integer type to be punned by ABI.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I saw that comment in the issue. I don't think that's something to discuss here though -- they key point is that the Rust thing matches the C thing.

Non-transitive compatibility doesn't really make sense IMO but that's a discussion for another day.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've run into problems with cfi tags on methods involving enums in the signature. You probably want to be careful about what you promise here. Unfortunately I don't know what the precise rules are CFI wise.


If the enum has fields, the effect is similar to the effect of `repr(C)`
in that there is a defined layout of the type. This makes it possible to
Expand Down