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

fix(ast_tools): fix miscalculation of enum layouts. #5774

Merged

Conversation

rzvxa
Copy link
Contributor

@rzvxa rzvxa commented Sep 14, 2024

Fixes a bug with how we were calculating the size of enums when there are different padding on variants and there aren't enough niches. Now it aligns the largest variant size to the largest alignment before consuming niches.

Copy link

graphite-app bot commented Sep 14, 2024

Your org has enabled the Graphite merge queue for merging into main

Add the label “0-merge” to the PR and Graphite will automatically add it to the merge queue when it’s ready to merge. Or use the label “hotfix” to add to the merge queue as a hot fix.

You must have a Graphite account and log in to Graphite in order to use the merge queue. Sign up using this link.

Copy link
Contributor Author

rzvxa commented Sep 14, 2024

@github-actions github-actions bot added the A-ast-tools Area - AST tools label Sep 14, 2024
@rzvxa rzvxa marked this pull request as ready for review September 14, 2024 20:54
@rzvxa rzvxa requested a review from overlookmotel September 14, 2024 20:54
Copy link

codspeed-hq bot commented Sep 14, 2024

CodSpeed Performance Report

Merging #5774 will not alter performance

Comparing 09-15-fix_ast_tools_fix_miscalculation_of_enum_layouts (ea1c733) with main (3230ae5)

Summary

✅ 29 untouched benchmarks

Copy link
Contributor

@overlookmotel overlookmotel left a comment

Choose a reason for hiding this comment

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

I am not familiar with the layout calculation logic in ast_tools, so I could be reading it wrong, but it looks like this is taking the niches of the variants' fields into account for niche calculation of the enum.

I don't think this is correct. e.g.: Rust playground:

  • StartNiche has an unused discriminant at start of the u8 range (0).

  • EndNiche has an unused discriminant at end of the u8 range (255).

  • NoNiche has no unused discriminants at either start or end of u8 range.

  • Option<StartNiche> and Option<EndNiche> are 2 bytes (discriminant's niche used as None).

  • Option<NoNiche> is 3 bytes (indicating NoNiche has no niche).

A couple of conclusions we can draw from this:

  1. The number of variants is not relevant, only whether there are spare discriminant values at start or end of range (not in the middle).
  2. Whether the fields have niches or not is also irrelevant. Compiler could have noticed that every variant in NoNiche has a field with 254 illegal values, and those illegal values overlap for all fields. It could have used one of those illegal values as a niche (Option<NoNiche>::None could be stored as 2 bytes [0, 2]). But it doesn't! An enum only has niches if there are available discriminant values.

You have other PRs stacked on top of this, so feel free to merge this, and then change the niche logic in a follow-up if you like.

@Boshen Boshen added the needs-discussion Requires a discussion from the core team label Oct 19, 2024
@overlookmotel
Copy link
Contributor

Am going to merge this, and then address the issues raised in my comment above in a follow-on.

@overlookmotel overlookmotel added 0-merge Merge with Graphite Merge Queue and removed needs-discussion Requires a discussion from the core team labels Oct 21, 2024
Copy link
Contributor

overlookmotel commented Oct 21, 2024

Merge activity

  • Oct 21, 8:18 AM EDT: The merge label '0-merge' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Oct 21, 8:18 AM EDT: A user added this pull request to the Graphite merge queue.
  • Oct 21, 8:25 AM EDT: A user merged this pull request with the Graphite merge queue.

Fixes a bug with how we were calculating the size of enums when there are different padding on variants and there aren't enough niches. Now it aligns the largest variant size to the largest alignment before consuming niches.
@overlookmotel overlookmotel force-pushed the 09-15-fix_ast_tools_fix_miscalculation_of_enum_layouts branch from ea1c733 to e8f8409 Compare October 21, 2024 12:19
@github-actions github-actions bot added the C-bug Category - Bug label Oct 21, 2024
@graphite-app graphite-app bot merged commit e8f8409 into main Oct 21, 2024
15 checks passed
@graphite-app graphite-app bot deleted the 09-15-fix_ast_tools_fix_miscalculation_of_enum_layouts branch October 21, 2024 12:25
@overlookmotel
Copy link
Contributor

overlookmotel commented Oct 21, 2024

Am going to merge this, and then address the issues raised in my comment above in a follow-on.

Actually, I can't understand the code at all. To calculate niches correctly, need to know the value of the variant discriminants, which isn't easily available at this stage. I think to make it exactly correct, will need quite a large refactoring. In any case, for AST transfer, we need to know not just how many niches, but their positions and values. So will need a rework for that anyway. I'll return to this later on.

Note: The usual niche optimization for Option-like enums does not apply when the enum is #[repr(C)], which all our enums are. Rust playground

overlookmotel added a commit that referenced this pull request Oct 21, 2024
Follow-on after #5774. Correct the logic for calculating niches in enums.

It's still not quite correct - number of niches depends on how many spare discriminant "slots" there are at *start or end* of the range, not in total. But this is closer to correct than it was - we now don't take into account whether enum variant payloads have niches or not, which is not relevant.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0-merge Merge with Graphite Merge Queue A-ast-tools Area - AST tools C-bug Category - Bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants