-
Notifications
You must be signed in to change notification settings - Fork 447
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
[type-layout] Document minimum size and alignment #1482
base: master
Are you sure you want to change the base?
Conversation
src/type-layout.md
Outdated
- 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. |
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.
Alignment affects size, so discussing the two separately here doesn't quite work.
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.
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.)
src/type-layout.md
Outdated
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` |
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.
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.
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.
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.
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.
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.)
There's a potential issue here -- not all types mentioned in the source code actually make it to codegen, so sometimes types that are "too big" do not lead to errors. This example fails to build in a debug build but succeeds as a release build: #![crate_type = "lib"]
pub fn f() {
g::<u16>();
}
pub fn g<T>() -> std::mem::MaybeUninit<[T; 1 << 47]> {
std::mem::MaybeUninit::uninit()
} |
Good call. This shouldn't be a problem in our motivating use case, but obviously we need to be careful with what we promise. Intuitively, the guarantee is something like "a type which you can do anything with" or "a type which you can create a pointer to". But I'm not sure how to formalize that idea. For the motivating use case, we need to guarantee that this holds of |
The new wording sounds good to me. However, the issue with "which types actually end up being size-checked" remains. I don't have a good idea for how to express that. @rust-lang/opsem @rust-lang/lang: any thoughts? There's tow questions; the easy one is what you think about the text of the PR, but the harder one is this concern. Specifically, the question is for which types we guarantee that their size is less than I don't have a good idea for how to even say which types are guaranteed to be size-checked in the current implementation. Similar to what we did for const-eval failures, we could try to have a notion of "required types" such that if a function runs, these types are definitely size-checked -- but given the huge number of types in a typical program, that sounds like it could be quite expensive. |
This is a draft implementation of rust-lang/rust#117474 (comment). I'm happy to make any suggested edits.
cc @RalfJung