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

Guarantee repr(C) enum discriminants are stable within a compilation #1454

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

joshlf
Copy link
Contributor

@joshlf joshlf commented Jan 25, 2024

No description provided.

@joshlf joshlf changed the title type-layout.md: Guarantee that repr(C) enum discriminants are stable … Guarantee repr(C) enum discriminants are stable within a compilation Jan 25, 2024
@joshlf
Copy link
Contributor Author

joshlf commented Jan 25, 2024

cc @djkoloski @jswrenn

@joshlf
Copy link
Contributor Author

joshlf commented Mar 2, 2024

Friendly ping 🙂

1 similar comment
@joshlf
Copy link
Contributor Author

joshlf commented May 20, 2024

Friendly ping 🙂

@ehuss
Copy link
Contributor

ehuss commented May 20, 2024

Is there some context for this change? Has it been discussed by the lang team?

Comment on lines +309 to +311
> discriminants will have the same size and alignment *within a given
> compilation of the program.* This is true for both field-less enums and
> for enums with fields.
Copy link
Contributor

Choose a reason for hiding this comment

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

"within a given compilation of the program" doesn't seem clear to me what that means. Certainly all types have the same size and alignment during compilation. I'm not sure I can guess what this is trying to say, can you clarify?

Copy link
Contributor Author

@joshlf joshlf May 20, 2024

Choose a reason for hiding this comment

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

Maybe I should phrase this differently. The idea is that, whatever choice rustc makes about the size and alignment of the discriminant of a repr(C) enum, it makes the same choice for all repr(C) enums within a program.

The reason this is important is that the size and alignment aren't guaranteed in any way other than to say "rustc will choose some size and alignment." This puts unsafe code in a bind: how do you know what the size and alignment of the discriminant is if you're trying to work with the layout of an enum type? With this added text, you can construct a "dummy" field-less repr(C) enum, query for its size and alignment using size_of and align_of, and take these to be equal to the size and alignment of the discriminant of the enum you're working with.

The specific context is that zerocopy's TryFromBytes trait can currently be derived on field-less enums, and we want to add support for data-ful enums, but we can't without this guarantee (or some other way of querying for the size and alignment of repr(C) enum discriminants).

Copy link
Contributor

Choose a reason for hiding this comment

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

@joshlf: We discussed this in the rustdocs call today. This is going to need to be lang nominated, but before we do that, we'd like this language to be as clear as possible. Do you want to take another pass at stating this more clearly as discussed?

@joshlf
Copy link
Contributor Author

joshlf commented May 20, 2024

Has it been discussed by the lang team?

No, but I figured it'd be pretty uncontroversial. Happy to CC them here if you'd like.

@traviscross
Copy link
Contributor

traviscross commented Jul 9, 2024

@joshlf: Before we lang nominate it, could you update the PR description with a summary of the change being proposed here and describe in some detail the motivations for this change. E.g., if you could go into more detail about the situation you have with the zerocopy library and what the possible solutions for that problem are (especially if there are any other ones than the one proposed here), that would be helpful.

If you have any ideas for how we would actually encode this as a test in our test suite, that would be good to detail also.

> However, it is guaranteed that, for any two `repr(C)` enum types, their
> discriminants will have the same size and alignment *within a given
> compilation of the program.* This is true for both field-less enums and
> for enums with fields.
Copy link
Member

Choose a reason for hiding this comment

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

You probably mean the tag, not the discriminant. The discriminant is the value you get when you cast an enum to an integer or call std::mem::discriminant on it. The tag is the actual representation in memory. It may be smaller or larger than the discriminant. Without repr(C) or repr(iN) the tag may be a different integer than the discriminant or the discriminant may be represented using niches instead.

@ehuss ehuss added the S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author. label Aug 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants