@@ -84,15 +84,17 @@ Structs can have various `#[repr]` flags that influence their layout:
84
84
85
85
### Default layout ("repr rust")
86
86
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).
96
98
97
99
Known things that can influence layout (non-exhaustive):
98
100
@@ -123,9 +125,10 @@ unsizing. E.g., `struct Foo { x: u16, y: u32 }` and `struct Foo<T> {
123
125
x: u16, y: T }` where ` T = u32` are not guaranteed to be identical.
124
126
125
127
#### Zero-sized structs
128
+ [ zero-sized structs ] : #zero-sized-structs
126
129
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.
129
132
130
133
For example, all these types are zero-sized:
131
134
@@ -141,6 +144,37 @@ struct Zst2(Zst1, Zst0);
141
144
# }
142
145
```
143
146
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
+
144
178
#### Unresolved questions
145
179
146
180
During 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
150
184
section documents the questions and gives a few light details, but the
151
185
reader is referred to the issues for further discussion.
152
186
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
-
162
187
** Homogeneous structs ([ #36 ] ).** If you have homogeneous structs, where all
163
188
the ` N ` fields are of a single type ` T ` , can we guarantee a mapping to
164
189
the 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):
400
425
thread] ( https://github.com/rust-rfcs/unsafe-code-guidelines/pull/31#discussion_r224955817 ) ).
401
426
- Many people would prefer the name ordering to be chosen for
402
427
"readability" and not optimal layout.
428
+
429
+ [ 1-ZST ] : ../glossary.md#zero-sized-type--zst
0 commit comments