-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Relaxed DST field ordering #3713
base: master
Are you sure you want to change the base?
Relaxed DST field ordering #3713
Conversation
Also going to pre-empt this because, while it's not mentioned in the RFC because I genuinely could not find any info in the reference about it, it will probably come up: What do we do about references to ZST fields after the DST in If people actually use references to ZST fields in But I had been effectively treating this RFC as if every reference to a ZST doesn't matter, and if people use |
I don't think we should allow putting fields after the DST tail in a
I'm not sure what you mean here, but I don't think it is reasonable to assume that Footnotes
|
You're right that you can make ZST pointers just fine (and indeed, Like, since ZST boxes all point to the same dangling value and ZST statics all point to the same dangling value, it doesn't seem to unreasonable that all ZST references would just be the same pointer (modulo alignment) by default unless dereferenced. |
|
||
However, `repr(Rust)` allows reordering fields, and this is not not reflected in this rule for dynamically sized fields: no matter what you do, the dynamically sized field must be at the end. This is inconsistent with the rest of the language and limits the ability of authors to reorder the fields in a more natural way, like they can for statically sized structs. | ||
|
||
Additionally, Rust has fully committed to zero-sized fields being truly invisible to struct layout, encoding this in the definition of `repr(transparent)`. So, why are dynamically sized fields unable to be followed by zero-sized fields, or reordered among statically sized fields in a `repr(Rust)` struct? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pretty sure the alignment of a ZST is part of the layout and is visible (and using it in #[repr(transparent)]
will indeed raise E0690 "transparent struct needs at most one field with non-trivial size or alignment")
given that the Ref-level explanation assumed #[repr(transparent)]
and #[repr(C)]
will be using the same logic i think you just need to mention "ZST" in this RFC is restricted to (size 0, align 1) only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hopefully the reworded explanation is better: the new rules apply to both repr(Rust)
and repr(transparent)
, but the restrictions on what ZSTs are allowed for repr(transparent)
remain.
Yes,
Formally, you can't assume that
While this would be valid, this is not how rustc currently works AFAICT. Currently For more info: see rust-lang/unsafe-code-guidelines#503 Footnotes |
I don't really understand the motivation for this change. In general, it's nice that I don't have to worry about what's the most space-efficient field order in my types (especially if it depends on type parameters) unless I already care about their layout and therefore add I don't want to rule out that there's code where this RFC might be nice to have. But is a "nice to have" feature worth the can of worms w.r.t. ZST addresses and the |
I guess that my biggest motivation for this change is specifically for the ZST change: it's extremely common to put For |
Since it seems too contentious, I've removed I do apologise for kind of rushing this RFC out— it's been something that has come up a few times as being inconsistent (imho), and I kind of just wanted to start a discussion on it rather than opening a pre-RFC on internals, since it feels like said discussion wouldn't substantially impact the RFC contents. I probably should have thought about |
I've not read the RFC in detail, just skimmed the OP, but I do think the rules regarding field ordering are somewhat silly given that (apart from That said, I'd have to review, I seem to recall that rustc at least took advantage of this rule for a much more optimized sized check -- and maybe there are other details I've forgotten about. |
Would love to know how those checks work, since my impression of how |
What about tuples? We often treat them like The RFC should probably state explicitly that tuples still only support the last field to be unsized, and explain why -- or explain whatever else is needed to keep tuple unsizing coercions working. This RFC also makes error reporting harder, since currently we can simply fire off a trait query ensuring all but the last field are sized. But with this RFC we'll have to somehow fire off a query for all fields, process the results, and if more than 1 returns "might not be sized" we have to figure out a good way to report the error. That should maybe be listed as a drawback. |
Summary
Relax the requirements on struct field ordering for dynamically sized fields for
repr(Rust)
andrepr(transparent)
, such that?Sized
fields can be anywhere in the field list, as long as there is only one.Note that this RFC previously added changes to
repr(C)
, but these have since been removed.Rendered