You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/type-layout.md
+30-15Lines changed: 30 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -144,21 +144,26 @@ Closures have no layout guarantees.
144
144
145
145
r[layout.aggregate]
146
146
147
-
r[layout.aggregate.intro] Aggregate types, `struct`s and `union`s, determine the layout based on its fields, and the [repr][layout.repr] attribute. Each field is categorized by its alignment and size, and an offset within that struct which, by default, is a multiple of its alignment.
147
+
r[layout.aggregate.intro]
148
+
Aggregate types, `struct`s and `union`s, determine the layout based on its fields, and the [repr][layout.repr] attribute. Each field is categorized by its alignment and size, and an offset within that struct which, by default, is a multiple of its alignment.
148
149
149
-
r[layout.aggregate.struct-offsets] The fields of a `struct` have offsets such that none of the fields overlap within the `struct`.
150
+
r[layout.aggregate.struct-offsets]
151
+
The fields of a `struct` have offsets such that none of the fields overlap within the `struct`.
150
152
151
153
r[layout.aggregate.struct-size-align]
152
154
The size of a `struct` is at least such that each field can be placed within the struct's storage, and the size is a multiple of its alignment. The alignment of a `struct`, unless modified by the [`repr(packed)`][layout.repr.alignment.packed] attribute, is at least the largest alignment of all fields.
153
155
154
-
r[layout.aggregate.union-offsets] The fields of a `union` may have any offset within the `union`. In particular, `union` fields are permitted to overlap within the `union`.
156
+
r[layout.aggregate.union-offsets]
157
+
The fields of a `union` may have any offset within the `union`. In particular, `union` fields are permitted to overlap within the `union`.
155
158
156
159
> [!NOTE]
157
160
> Typically, union fields are all given offset 0 and are all allocated in the same storage. This is not necessarily guaranteed, however, for [The Rust Representation][layout.repr.rust]
158
161
159
-
r[layout.aggregate.union-size-align] The size of a `union` is at least such that the largest field, and the size is a multiple of the alignment. The alignment of a `union`, unless modified by the [`repr(packed)`][layout.repr.alignment.packed] attribute, is at least the largest alignment of all fields.
162
+
r[layout.aggregate.union-size-align]
163
+
The size of a `union` is at least such that the largest field, and the size is a multiple of the alignment. The alignment of a `union`, unless modified by the [`repr(packed)`][layout.repr.alignment.packed] attribute, is at least the largest alignment of all fields.
160
164
161
-
r[layout.aggregate.repr] The [`repr`][layout.repr] attribute may restrict the valid offsets for each field, as well as the size and alignment of the aggregate type. By [default][layout.repr.rust], the offsets of fields are unspecified.
165
+
r[layout.aggregate.repr]
166
+
The [`repr`][layout.repr] attribute may restrict the valid offsets for each field, as well as the size and alignment of the aggregate type. By [default][layout.repr.rust], the offsets of fields are unspecified.
162
167
163
168
> [!NOTE]
164
169
> The choices of the offsets of fields are made per-struct. Two `struct`s or two `union`s with the same fields using [`repr(Rust)`][layout.repr.rust] are not necessarily layed out the same
@@ -236,7 +241,8 @@ without a `repr` attribute. Using this representation explicitly through a
236
241
`repr` attribute is guaranteed to be the same as omitting the attribute
237
242
entirely.
238
243
239
-
r[layout.repr.rust.aggregate] The layout of aggregate types with this repr is unspecified, such that the guarantees of all `struct` and `union` types are upheld.
244
+
r[layout.repr.rust.aggregate]
245
+
The layout of aggregate types with this repr is unspecified, such that the guarantees of all `struct` and `union` types are upheld.
240
246
241
247
> [!NOTE]
242
248
> `repr(Rust)` does not provide any guarantees other than the default constraints.
@@ -245,11 +251,14 @@ r[layout.repr.rust.aggregate] The layout of aggregate types with this repr is un
245
251
246
252
r[layout.repr.rust.enum]
247
253
248
-
r[layout.repr.rust.enum.intro] Like `struct`s and `union`s with the `Rust` representation, `enum`s typically have no guarantees. The fields of individual variants are layed out with the same rules as a `repr(Rust)` struct, and the `enum` contains sufficient information to determine which variant is being represented.
254
+
r[layout.repr.rust.enum.intro]
255
+
Like `struct`s and `union`s with the `Rust` representation, `enum`s typically have no guarantees. The fields of individual variants are layed out with the same rules as a `repr(Rust)` struct, and the `enum` contains sufficient information to determine which variant is being represented.
249
256
250
-
r[layout.repr.rust.enum.variant-fields] Each field of a variant has an offset within the `enum`, such that no two fields of the same variant overlap, and each field of each variant is aligned, unless modified by the [`repr(packed)`][layout.repr.alignment.packed] attribute. Fields of different variants are allowed to overlap, as though each variant appears within a `union` definition.
257
+
r[layout.repr.rust.enum.variant-fields]
258
+
Each field of a variant has an offset within the `enum`, such that no two fields of the same variant overlap, and each field of each variant is aligned, unless modified by the [`repr(packed)`][layout.repr.alignment.packed] attribute. Fields of different variants are allowed to overlap, as though each variant appears within a `union` definition.
251
259
252
-
r[layout.repr.rust.enum.size-align] The size of an enum is such that each field of each variant that is not uninhabited can be allocated within the enum at its given offset. The alignment of an enum, unless modified by the [`repr(packed)`][layout.repr.alignment.packed] attribute, is at least the largest alignment of all fields in variants that are inhabited.
260
+
r[layout.repr.rust.enum.size-align]
261
+
The size of an enum is such that each field of each variant that is not uninhabited can be allocated within the enum at its given offset. The alignment of an enum, unless modified by the [`repr(packed)`][layout.repr.alignment.packed] attribute, is at least the largest alignment of all fields in variants that are inhabited.
253
262
254
263
> [!NOTE]
255
264
> A Rough approximation of a `repr(Rust)` enum is a `repr(Rust)` union containing `repr(Rust)` structs for each variant, with a discriminant field present in each struct.
@@ -263,9 +272,11 @@ r[layout.repr.rust.enum.size-align] The size of an enum is such that each field
263
272
264
273
r[layout.repr.rust.option]
265
274
266
-
r[layout.repr.rust.option.intro] Certain `repr(Rust)` enums are specially layed out when used with certain types. This layout process is known as discriminant elision.
275
+
r[layout.repr.rust.option.intro]
276
+
Certain `repr(Rust)` enums are specially layed out when used with certain types. This layout process is known as discriminant elision.
267
277
268
-
r[layout.repr.rust.option.elligible] An `enum` type is a *discriminant elision eligible* enum if:
278
+
r[layout.repr.rust.option.elligible]
279
+
An `enum` type is a *discriminant elision eligible* enum if:
269
280
* It has exactly two variants,
270
281
* One variant has exactly one field, known as the *elision candidate field*, and
271
282
* The other variant has no fields that have size greater than 0 or alignment greater than 1, known as the *elided variant*.
@@ -274,7 +285,8 @@ r[layout.repr.rust.option.elligible] An `enum` type is a *discriminant elision e
274
285
> The determination of whether an `enum` type is *discriminant elision eligible* applies after mono-morphization.
275
286
> In particular, a type like [`core::result::Result<T,E>`] is *discriminant elision eligible* if either `T` or `E` is instantiated with a 1-ZST type, and [`core::option::Option<T>`] is *discriminant elision eligible* always (due to its `None` variant).
276
287
277
-
r[layout.repr.rust.option.candidates] The following types are *elision candidate types*:
288
+
r[layout.repr.rust.option.candidates]
289
+
The following types are *elision candidate types*:
278
290
*[`&U`][type.pointer.reference.shared], if `U` is a `Sized` type
279
291
*[`&mut U`][type.pointer.reference.mut], if `U` is a `Sized` type
280
292
*[`core::ptr::NonNull<U>`], if `U` is a `Sized` type
@@ -283,7 +295,8 @@ r[layout.repr.rust.option.candidates] The following types are *elision candidate
283
295
* A [function pointer][type.fn-pointer] type
284
296
* A `struct`, defined using [`repr(transparent)`][layout.repr.transparent], which has a field that is an *elision candidate*, and all other fields have size 0 and alignment 1.
285
297
286
-
r[layout.repr.rust.option.elision] If the *elision candidate field* of a *discriminant elision eligible*`enum` has an *elision candidate type*, then the `enum` has the same layout as that field, except that the value consisting of all `0` bytes represents the *elided variant* of the `enum`.
298
+
r[layout.repr.rust.option.elision]
299
+
If the *elision candidate field* of a *discriminant elision eligible*`enum` has an *elision candidate type*, then the `enum` has the same layout as that field, except that the value consisting of all `0` bytes represents the *elided variant* of the `enum`.
287
300
288
301
> [!NOTE]
289
302
> It is valid for this optimization to be performed for types an `enum`s other than those mentioned above, however, it is only guaranteed for these types and `enum`s.
@@ -305,9 +318,11 @@ r[layout.repr.c.constraint]
305
318
This representation can be applied to structs, unions, and enums. The exception
306
319
is [zero-variant enums] for which the `C` representation is an error.
307
320
308
-
r[layout.repr.c.aggregate] An aggregate type (`struct` or `union`) with the `C` representation is laid out by each field being given by the smallest valid offset for that field that is ascending in declaration order. That is, for a `union`, each field is at offset `0`, and for a struct, the first field is at offset `0`, then the second is at the next offset aligned to the field type. The size of such an aggregate type is the minimum value valid for the type.
321
+
r[layout.repr.c.aggregate]
322
+
An aggregate type (`struct` or `union`) with the `C` representation is laid out by each field being given by the smallest valid offset for that field that is ascending in declaration order. That is, for a `union`, each field is at offset `0`, and for a struct, the first field is at offset `0`, then the second is at the next offset aligned to the field type. The size of such an aggregate type is the minimum value valid for the type.
309
323
310
-
r[layout.repr.c.align] An aggregate type with the `C` representation has an alignment equal to the maximum alignment of each of its fields, unless an [alignment modifier][layout.repr.alignment] is present.
324
+
r[layout.repr.c.align]
325
+
An aggregate type with the `C` representation has an alignment equal to the maximum alignment of each of its fields, unless an [alignment modifier][layout.repr.alignment] is present.
311
326
312
327
> [!NOTE]
313
328
> The layout of unions in particular is maximally compact - the size of a `C` representation `union` is the size of its largest field, rounded up to the alignment of the `union`
0 commit comments