Skip to content

New rule layout.repr.c.struct.align-empty#2264

Open
DanielEScherzer wants to merge 1 commit into
rust-lang:masterfrom
DanielEScherzer:repr-c-no-fields
Open

New rule layout.repr.c.struct.align-empty#2264
DanielEScherzer wants to merge 1 commit into
rust-lang:masterfrom
DanielEScherzer:repr-c-no-fields

Conversation

@DanielEScherzer
Copy link
Copy Markdown
Contributor

No description provided.

@rustbot rustbot added the S-waiting-on-review Status: The marked PR is awaiting review from a maintainer label May 5, 2026
@traviscross traviscross added I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. I-lang-easy-decision The decision needed by lang is conjectured to be easy; this dose not imply nomination. labels May 5, 2026
Comment thread src/type-layout.md
The alignment of the struct is the alignment of the most-aligned field in it.

r[layout.repr.c.struct.align-empty]
The alignment of a struct with no fields is 1.
Copy link
Copy Markdown
Member

@RalfJung RalfJung May 6, 2026

Choose a reason for hiding this comment

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

We are moving towards repr(C) being defined entirely by the platform ABI (rust-lang/rfcs#3845). So I'm not sure we should add any such promises.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We talked about this in today's @rust-lang/lang call. Our understanding of the migration plan is that that we'll be adding a today's-edition name for repr(C) (whatever that ends up being named), adding repr(ordered_fields) which will be the same (but indicates that the user explicitly wants that rather than being auto-migrated), and then adding a new repr(C) for the new edition.

Given that transition plan, our understanding is that all the current documentation of repr(C) will move to be documentation of the today's-edition repr(C) and repr(ordered_fields), and then we'll add new documentation for the new repr(C) that largely says we do whatever the platform C ABI does.

Given that transition plan, do you see an issue with this proposal as ongoing documentation of what will end up being the old repr(C) rather than the new one, assuming that all this documentation moves to being for the old one?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For what might eventually be called repr(ordered_fields), this new clause is indeed correct.

It's also redundant though, it follows from the definition of the layout algorithm.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This rule was proposed in the context of discussing #2243 on the t-lang-docs call yesterday where it was concluded that it does not actually follow from the definition of the layout algorithm - the size and offsets algorithm doesn't describe how to identify the alignment of the type, and the layout.repr.c.struct.align rule says

The alignment of the struct is the alignment of the most-aligned field in it.

but if there are no fields then there is no most-aligned field

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Our understanding of the migration plan is that that we'll be adding a today's-edition name for repr(C) (whatever that ends up being named), adding repr(ordered_fields) which will be the same

FWIW, I don't think that end state is set in stone. E.g. to resolve rust-lang/rust#112480, we might potentially end up at a state where all 3 of old repr(C), new repr(C), and repr(ordered_fields) are different.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

the layout.repr.c.struct.align rule says

The alignment of the struct is the alignment of the most-aligned field in it.

Then I would suggest that it makes more sense to edit that rule than add a new one. A single rule should suffice to define the alignment of the type.

Something lie:
The alignment of the struct is the maximum of the alignments of all fields, or 1 if there are no fields.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We can combine the rules, no objection to that, just need T-lang to sign off on the new guarantee being added

@traviscross traviscross removed the I-lang-easy-decision The decision needed by lang is conjectured to be easy; this dose not imply nomination. label May 6, 2026
@traviscross
Copy link
Copy Markdown
Contributor

@rfcbot fcp merge lang

@rust-rfcbot
Copy link
Copy Markdown
Collaborator

rust-rfcbot commented May 13, 2026

Team member @traviscross has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns.
See this document for info about what commands tagged team members can give me.

@tmandry
Copy link
Copy Markdown
Member

tmandry commented May 13, 2026

I'm fine with adding this as a guarantee. The suggestion to edit the existing rules makes sense, but I think we should leave that as an editorial question for the reference.

@rfcbot reviewed

@rust-rfcbot
Copy link
Copy Markdown
Collaborator

🔔 This is now entering its final comment period, as per the review above. 🔔

@traviscross traviscross added I-lang-radar Items that are on lang's radar and will need eventual work or consideration. and removed I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. labels May 13, 2026
@nikomatsakis
Copy link
Copy Markdown
Contributor

nikomatsakis commented May 13, 2026

@rfcbot reviewed

I agree with making this guarantee. I don't have an opinion about whether we add it as a separate clause or as part of another clause -- @RalfJung's suggestion here made sense to me.

Comment thread src/type-layout.md
Comment on lines 218 to 247
```rust,ignore
/// Returns the amount of padding needed after `offset` to ensure that the
/// following address will be aligned to `alignment`.
fn padding_needed_for(offset: usize, alignment: usize) -> usize {
let misalignment = offset % alignment;
if misalignment > 0 {
// round up to next multiple of `alignment`
alignment - misalignment
} else {
// already a multiple of `alignment`
0
}
}

struct.alignment = struct.fields().map(|field| field.alignment).max();

let current_offset = 0;

for field in struct.fields_in_declaration_order() {
// Increase the current offset so that it's a multiple of the alignment
// of this field. For the first field, this will always be zero.
// The skipped bytes are called padding bytes.
current_offset += padding_needed_for(current_offset, field.alignment);

struct[field].offset = current_offset;

current_offset += field.size;
}

struct.size = current_offset + padding_needed_for(current_offset, struct.alignment);
Copy link
Copy Markdown
Member

@steffahn steffahn May 13, 2026

Choose a reason for hiding this comment

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

you might also want to update this algorithm. Currently the line

struct.alignment = struct.fields().map(|field| field.alignment).max();

is kinda bugged anyway, since the real max() method returns an Option. So:

struct.alignment = struct.fields().map(|field| field.alignment).max().unwrap_or(1);

would be better ^^

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

already working on that in #2243 but we couldn't updated the algorithm with unwrap_or(1) since that adds a new guarantee that isn't in the text, after this is approved I'll rebase that PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-merge final-comment-period I-lang-radar Items that are on lang's radar and will need eventual work or consideration. S-waiting-on-review Status: The marked PR is awaiting review from a maintainer T-lang Relevant to the language team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants