From 5ef11d911ebdacd00189131c90d2624c36955d5c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 21 Oct 2019 18:17:52 +0200 Subject: [PATCH 1/2] note on uninhabited structs --- reference/src/layout/structs-and-tuples.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/reference/src/layout/structs-and-tuples.md b/reference/src/layout/structs-and-tuples.md index aa5178f5..bbffcb82 100644 --- a/reference/src/layout/structs-and-tuples.md +++ b/reference/src/layout/structs-and-tuples.md @@ -79,6 +79,11 @@ themselves is already entirely determined by their types, and since we intend to allow creating references to fields (`&s.f1`), structs do not have any wiggle-room there. +**Note:** This is only true if the struct is inhabited. For structs like `(i32, +!)` that do not have a valid inhabitant, the compiler has more freedom. After +all, no references to fields can ever be taken. For example, such structs might +be zero-sized. + This can be visualized as follows: ```text [ <--> [field 3] <-----> [field 1] <-> [ field 2 ] <--> ] From 2f06a6ec295e679dfd24b05fa91a78b547187a10 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 21 Oct 2019 18:53:56 +0200 Subject: [PATCH 2/2] not just a note --- reference/src/layout/structs-and-tuples.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/reference/src/layout/structs-and-tuples.md b/reference/src/layout/structs-and-tuples.md index bbffcb82..53bcee3d 100644 --- a/reference/src/layout/structs-and-tuples.md +++ b/reference/src/layout/structs-and-tuples.md @@ -72,17 +72,12 @@ struct Foo { (In fact, one may use such field names in patterns or in accessor expressions like `foo.0`.) -The degrees of freedom the compiler has when computing the layout of a struct or -tuple is to determine the order of the fields, and the "gaps" (often called -*padding*) before, between, and after the fields. The layout of these fields -themselves is already entirely determined by their types, and since we intend to -allow creating references to fields (`&s.f1`), structs do not have any -wiggle-room there. - -**Note:** This is only true if the struct is inhabited. For structs like `(i32, -!)` that do not have a valid inhabitant, the compiler has more freedom. After -all, no references to fields can ever be taken. For example, such structs might -be zero-sized. +The degrees of freedom the compiler has when computing the layout of an +*inhabited* struct or tuple is to determine the order of the fields, and the +"gaps" (often called *padding*) before, between, and after the fields. The +layout of these fields themselves is already entirely determined by their types, +and since we intend to allow creating references to fields (`&s.f1`), structs do +not have any wiggle-room there. This can be visualized as follows: ```text @@ -95,6 +90,10 @@ layout). The compiler freely picks an order for the fields to be in (this does not have to be the order of declaration in the source), and it picks the gaps between the fields (under some constraints, such as alignment). +For *uninhabited* structs or tuples like `(i32, !)` that do not have a valid +inhabitant, the compiler has more freedom. After all, no references to fields +can ever be taken. For example, such structs might be zero-sized. + How exactly the compiler picks order and gaps, as well as other aspects of layout beyond size and field offset, can be controlled by a `#[repr]` attribute: