@@ -84,15 +84,17 @@ Structs can have various `#[repr]` flags that influence their layout:
8484
8585### Default layout ("repr rust")
8686
87- ** The default layout of structs is not specified.** As of this
88- writing, we have not reached a full consensus on what limitations
89- should exist on possible field struct layouts, so effectively one must
90- assume that the compiler can select any layout it likes for each
91- struct on each compilation, and it is not required to select the same
92- layout across two compilations. This implies that (among other things)
93- two structs with the same field types may not be laid out in the same
94- way (for example, the hypothetical struct representing tuples may be
95- laid out differently from user-declared structs).
87+ With the exception of the guarantees provided below, ** the default layout of
88+ structs is not specified.**
89+
90+ As of this writing, we have not reached a full consensus on what limitations
91+ should exist on possible field struct layouts, so effectively one must assume
92+ that the compiler can select any layout it likes for each struct on each
93+ compilation, and it is not required to select the same layout across two
94+ compilations. This implies that (among other things) two structs with the same
95+ field types may not be laid out in the same way (for example, the hypothetical
96+ struct representing tuples may be laid out differently from user-declared
97+ structs).
9698
9799Known things that can influence layout (non-exhaustive):
98100
@@ -123,9 +125,10 @@ unsizing. E.g., `struct Foo { x: u16, y: u32 }` and `struct Foo<T> {
123125x: u16, y: T }` where ` T = u32` are not guaranteed to be identical.
124126
125127#### Zero-sized structs
128+ [ zero-sized structs ] : #zero-sized-structs
126129
127- For ` repr(Rust) ` , ` repr(packed(N)) ` , ` repr(align(N)) ` , and ` repr(C) `
128- structs: if all fields of a struct have size 0, then the struct has size 0.
130+ For ` repr(Rust) ` , ` repr(packed(N)) ` , ` repr(align(N)) ` , and ` repr(C) ` structs: if
131+ all fields of a struct have size 0, then the struct has size 0.
129132
130133For example, all these types are zero-sized:
131134
@@ -141,6 +144,37 @@ struct Zst2(Zst1, Zst0);
141144# }
142145```
143146
147+ In particular, a struct with no fields is a ZST, and if it has no repr attribute
148+ it is moreover a 1-ZST as it also has no alignment requirements.
149+
150+ #### Single-field structs
151+ [ single-field structs ] : #single-field-structs
152+
153+ A struct with only one field has the same layout as that field.
154+
155+ #### Structs with 1-ZST fields
156+
157+ For the purposes of struct layout [ 1-ZST] fields are ignored.
158+
159+ In particular, if all but one field are 1-ZST, then the struct is equivalent to
160+ a [ single-field struct] [ single-field structs ] . In other words, if all but one
161+ field is a 1-ZST, then the entire struct has the same layout as that one field.
162+
163+ Similarly, if all fields are 1-ZST, then the struct has the same layout as a
164+ [ struct with no fields] [ zero-sized structs ] , and is itself a 1-ZST.
165+
166+ For example:
167+
168+ ``` rust
169+ type Zst1 = ();
170+ struct S1 (i32 , Zst1 ); // same layout as i32
171+
172+ type Zst2 = [u16 ; 0 ];
173+ struct S2 (Zst2 , Zst1 ); // same layout as Zst2
174+
175+ struct S3 (Zst1 ); // same layout as Zst1
176+ ```
177+
144178#### Unresolved questions
145179
146180During the course of the discussion in [ #11 ] and [ #12 ] , various
@@ -150,15 +184,6 @@ issue has been opened for further discussion on the repository. This
150184section documents the questions and gives a few light details, but the
151185reader is referred to the issues for further discussion.
152186
153- ** Single-field structs ([ #34 ] ).** If you have a struct with single field
154- (` struct Foo { x: T } ` ), should we guarantee that the memory layout of
155- ` Foo ` is identical to the memory layout of ` T ` (note that ABI details
156- around function calls may still draw a distinction, which is why
157- ` #[repr(transparent)] ` is needed). What about zero-sized types like
158- ` PhantomData ` ?
159-
160- [ #34 ] : https://github.com/rust-rfcs/unsafe-code-guidelines/issues/34
161-
162187** Homogeneous structs ([ #36 ] ).** If you have homogeneous structs, where all
163188the ` N ` fields are of a single type ` T ` , can we guarantee a mapping to
164189the memory layout of ` [T; N] ` ? How do we map between the field names
@@ -400,3 +425,5 @@ proposal (and -- further -- it does not match our existing behavior):
400425 thread] ( https://github.com/rust-rfcs/unsafe-code-guidelines/pull/31#discussion_r224955817 ) ).
401426- Many people would prefer the name ordering to be chosen for
402427 "readability" and not optimal layout.
428+
429+ [ 1-ZST ] : ../glossary.md#zero-sized-type--zst
0 commit comments