Skip to content

separate ABI from Layout #457

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 27, 2023
Merged
Changes from all 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
20 changes: 17 additions & 3 deletions reference/src/glossary.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
## Glossary

### ABI (of a type)
[abi]: #abi-of-a-type

The *function call ABI* or short *ABI* of a type defines how it is passed *by-value* across a function boundary.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe call this "calling convention" instead? The ABI is the combination of the memory layout, calling convention, linkage model and every other part of the interface between compiled object files, dynamic libraries or the kernel.

Copy link
Member Author

Choose a reason for hiding this comment

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

"ABI" is the term used in existing documents such as this one. I wouldn't mind a different term but that might be fighting windmills...

Copy link
Contributor

Choose a reason for hiding this comment

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

Calling convention isn't quite correct either, because two types can have the same calling convention but not the same layout, and what's meant when discussing a type's function call ABI is the exact set of properties needed to ensure two function signatures are ABI compatible, which includes both calling convention and layout.

Possible ABIs include passing the value directly in zero or more registers, or passing it indirectly as a pointer to the actual data.
The space of all possible ABIs is huge and extremely target-dependent.
Rust therefore does generally not clearly define the ABI of any type, it only defines when two types are *ABI-compatible*,
which means that it is legal to call a function declared with an argument or return type `T` using a declaration or function pointer with argument or return type `U`.

Note that ABI compatibility is stricter than layout compatibility.
For instance `#[repr(C)] struct S(i32)` is (guaranteed to be) layout-compatible with `i32`, but it is *not* ABI-compatible.

### Abstract Byte
[abstract byte]: #abstract-byte

Expand Down Expand Up @@ -100,13 +112,15 @@ All interior mutation in Rust has to happen inside an [`UnsafeCell`](https://doc
### Layout
[layout]: #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 and alignment as well as the offsets of its subobjects (e.g. fields of structs/unions/enums/... or elements of arrays, and the discriminant of enums).

Note that layout does not capture everything that there is to say about how a type is represented on the machine; it notably does not include [ABI][abi] or [Niches][niche].

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.
In this document, *layout* and [*representation*][representation relation] are not synonyms.

### Niche
[niche]: #niche

The *niche* of a type determines invalid bit-patterns that will be used by layout optimizations.

Expand Down