Skip to content
Closed
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions reference/src/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,16 @@ For some more information, see [this blog post](https://www.ralfj.de/blog/2018/0

#### Layout

The *layout* of a type defines its size and alignment as well as the offsets of its subobjects (e.g. fields of structs/unions/enum/... or elements of arrays).
Moreover, the layout of a type records its *function call ABI* (or just *ABI* for short): how the type is passed *by value* across a function boundary.
The *layout* of a type defines:

* its size,
* its alignment,
* its field offsets (e.g. fields of structs, union, enums, arrays, ...)
* its [niches][Niche],
* its call abi.

Note: due to discriminant-elision optimizations, niches are required to compute
the layout of, e.g., `Option<T>`, from the layout of `T`.

Note: Originally, *layout* and *representation* were treated as synonyms, and Rust language features like the `#[repr]` attribute reflect this.
In this document, *layout* and *representation* are not synonyms.
Expand All @@ -73,6 +81,43 @@ niches. For example, the "all bits uninitialized" is an invalid bit-pattern for
`&mut T`, but this bit-pattern cannot be used by layout optimizations, and is not a
niche.

#### Call ABI

The *call ABI* determines how a type is passed *by value* across a function boundary.

Note: The set of possible call ABIs is not stable. Currently, it consists of:

```rust,ignore
enum Abi {
Uninhabited,
Scalar(Scalar),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ScalarPair is missing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's intentional. ScalarPair is an implementation detail useful for some optimizations that we don't want to guarantee it exists - right @eddyb ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's just an aggregate that we pass around as two scalars only in Rust ABIs and within functions.

Vector {
element: Scalar,
count: u64
},
Aggregate {
// If true, the layout size of the aggregate is exact.
// Otherwise, the layout size of the aggregate is
// a lower bound.
sized: bool,
}
}
```

where a `Scalar` is either a primitive integer, floating point, or a pointer to
a sized type.

For example, the call ABI of:

* `i32` is `Scalar(I32)`,
* `#[repr(C)] struct Wrapper(i32);` is `Aggregate { sized: true }`.
* `#[repr(transparent)] struct Wrapper(i32);` is `Scalar(I32)`.

The call ABI of `repr(Rust)` types is unspecified. The following is not
guaranteed, but right now the call ABI of:

* `/*#[repr(Rust)]*/ struct Wrapper(i32);` (without `repr(transparent)`) is also
`Scalar(I32)` - only larger `struct`s are aggregates.

### TODO

Expand Down