Skip to content

[type-layout] Document minimum size and alignment #1482

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

Closed
wants to merge 3 commits into from
Closed
Changes from 2 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
22 changes: 22 additions & 0 deletions src/type-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,28 @@ as [dynamically sized types]. Since all values of a `Sized` type share the same
size and alignment, we refer to those shared values as the size of the type and
the alignment of the type respectively.

### Minimum Size and Alignment

Every type, including [dynamically sized types], has a "minimum size" and "minimum
alignment." Every value of a type must have a size at least as large as the type's
minimum size and an alignment at least as large as the type's minimum alignment.
Some notable cases of minimum size and alignment are:
- For [`Sized`] types, the type's minimum size and minimum alignment
are always equal to the type's size and alignment, respectively
- For a [slice type](#slice-layout), `[T]`, the minimum size is 0 bytes (corresponding
to a slice with 0 elements), and the minimum alignment is the alignment of `T`
- For a [trait object](#trait-object-layout), the minimum size is 0 and the minimum
alignment is 1
- For a struct type with a dynamically-sized field, the minimum size is taken to be
the size of the struct when the dynamically-sized field has *its* minimum size.
Copy link
Member

Choose a reason for hiding this comment

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

Alignment affects size, so discussing the two separately here doesn't quite work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are you suggesting just adjusting it to say this?

For a struct type with a dynamically-sized field, the minimum size is taken to be the size of the struct when the dynamically-sized field has its minimum size and alignment.

(Done. I can revert if I misunderstood your suggestion.)

The struct's minimum alignment is taken to be the alignment of the struct when the
dynamically-sized field has *its* minimum alignment. When relying on this property
of dynamically-sized structs, be careful not to assume too much! For example,
this property provides *no* guarantees about [`repr(Rust)`](#the-rust-representation)
types, as such a type can have arbitrarily large size and alignment regardless of
the sizes and alignments of its fields
- Every type's minimum size is less than or equal to `isize::MAX`
Copy link
Member

Choose a reason for hiding this comment

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

This bullet doesn't belong into the list of "notable cases of minimum size and alignment are", it belongs before or after the list. Also it should say what happens when one declares a type whose minimum size exceeds this limit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This bullet doesn't belong into the list of "notable cases of minimum size and alignment are", it belongs before or after the list.

Done.

Also it should say what happens when one declares a type whose minimum size exceeds this limit.

Do we need to specify that? Presumably the implication is just that such a program would not conform to the spec, and so we couldn't permit it to compile, but a) that's a logical implication of the text here and, b) I don't believe we need to specify the manner in which it fails to compile.

I'm happy to also specify that such programs won't compile - I just want to make sure I'm understanding correctly that this is just a nice-to-have rather than something that affects the semantics of this text.

Copy link
Member

@RalfJung RalfJung May 27, 2024

Choose a reason for hiding this comment

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

Do we need to specify that?

I think so, yes. If we leave it implicit it could understood to be anything from UB to a compile-time error. (We don't do "UB by omission" in Rust but people might think we do. And some sort of run-time panic does seem like a not unreasonable interpretation to me.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds reasonable. Presumably resolving #1482 (comment) is required in order for us to agree on a wording for this?

Copy link
Member

Choose a reason for hiding this comment

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

The questions of "which types are checked" and "what happens when a type fails the check" seem orthogonal to me, so I don't see an overlap with the other discussion.


## Primitive Data Layout

The size of most primitives is given in this table.
Expand Down