From f9bcda904cc94b1f65513b1db213a1c3b6f59159 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 4 Sep 2023 11:39:58 +0200 Subject: [PATCH] wording improvements --- library/core/src/option.rs | 5 +++-- library/core/src/primitive_docs.rs | 21 ++++++++++++++------- library/std/src/primitive_docs.rs | 21 ++++++++++++++------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index f2909a81d4920..5f981a5577b04 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -119,7 +119,7 @@ //! # Representation //! //! Rust guarantees to optimize the following types `T` such that -//! [`Option`] has the same size and alignment as `T`: +//! [`Option`] has the same size, alignment, and [function call ABI] as `T`: //! //! * [`Box`] //! * `&U` @@ -129,11 +129,12 @@ //! * [`ptr::NonNull`] //! * `#[repr(transparent)]` struct around one of the types in this list. //! -//! [^extern_fn]: this remains true for any other ABI: `extern "abi" fn` (_e.g._, `extern "system" fn`) +//! [^extern_fn]: this remains true for any argument/return types and any other ABI: `extern "abi" fn` (_e.g._, `extern "system" fn`) //! //! [`Box`]: ../../std/boxed/struct.Box.html //! [`num::NonZero*`]: crate::num //! [`ptr::NonNull`]: crate::ptr::NonNull +//! [function call ABI]: ../primitive.fn.html#abi-compatibility //! //! This is called the "null pointer optimization" or NPO. //! diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 1a5d5c73213d9..0ff45be963bea 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1544,20 +1544,27 @@ mod prim_ref {} /// /// The following types are guaranteed to be ABI-compatible: /// -/// - Every type is ABI-compatible with itself. /// - `*const T`, `*mut T`, `&T`, `&mut T`, `Box`, `NonNull` are all ABI-compatible with each /// other for all `T`. -/// - Any two `fn()` types with the same `extern` ABI string are ABI-compatible with each other. -/// - Any two 1-ZST types (types with size 0 and alignment 1) are ABI-compatible. -/// - A `repr(transparent)` type `T` is ABI-compatible with its unique non-1-ZST field (if there is -/// such a field). +/// - Any two `fn`/`extern "ABI" fn` types with the same call ABI are ABI-compatible with each +/// other, independent of the rest of their signature. +/// - Any two types with size 0 and alignment 1 are ABI-compatible. +/// - A `repr(transparent)` type `T` is ABI-compatible with its unique non-trivial field, i.e., the +/// unique field that doesn't have size 0 and alignment 1 (if there is such a field). /// - `i32` is ABI-compatible with `NonZeroI32`, and similar for all other integer types with their /// matching `NonZero*` type. /// - If `T` is guaranteed to be subject to the [null pointer /// optimization](option/index.html#representation), then `T` and `Option` are ABI-compatible. +/// +/// Furthermore, ABI compatibility satisfies the following general properties: +/// +/// - Every type is ABI-compatible with itself. /// - If `T1` and `T2` are ABI-compatible, then two `repr(C)` types that only differ because one /// field type was changed from `T1` to `T2` are ABI-compatible. -/// - ABI-compatibility is symmetric and transitive. +/// - If `T1` and `T2` are ABI-compatible and `T2` and `T3` are ABI-compatible, then so are `T1` and +/// `T3` (i.e., ABI-compatibility is transitive). +/// - If `T1` and `T2` are ABI-compatible, then so are `T2` and `T1` (i.e., ABI-compatibility is +/// symmetric). /// /// More signatures can be ABI-compatible on specific targets, but that should not be relied upon /// since it is not portable and not a stable guarantee. @@ -1565,7 +1572,7 @@ mod prim_ref {} /// Noteworthy cases of types *not* being ABI-compatible in general are `bool` vs `u8`, and `i32` vs /// `u32`: on some targets, the calling conventions for these types differ in terms of what they /// guarantee for the remaining bits in the register that are not used by the value. `i32` vs `f32` -/// has already been mentioned above. +/// are not compatible either, as has already been mentioned above. /// /// Note that these rules describe when two completely known types are ABI-compatible. When /// considering ABI compatibility of a type declared in another crate (including the standard diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 1a5d5c73213d9..0ff45be963bea 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -1544,20 +1544,27 @@ mod prim_ref {} /// /// The following types are guaranteed to be ABI-compatible: /// -/// - Every type is ABI-compatible with itself. /// - `*const T`, `*mut T`, `&T`, `&mut T`, `Box`, `NonNull` are all ABI-compatible with each /// other for all `T`. -/// - Any two `fn()` types with the same `extern` ABI string are ABI-compatible with each other. -/// - Any two 1-ZST types (types with size 0 and alignment 1) are ABI-compatible. -/// - A `repr(transparent)` type `T` is ABI-compatible with its unique non-1-ZST field (if there is -/// such a field). +/// - Any two `fn`/`extern "ABI" fn` types with the same call ABI are ABI-compatible with each +/// other, independent of the rest of their signature. +/// - Any two types with size 0 and alignment 1 are ABI-compatible. +/// - A `repr(transparent)` type `T` is ABI-compatible with its unique non-trivial field, i.e., the +/// unique field that doesn't have size 0 and alignment 1 (if there is such a field). /// - `i32` is ABI-compatible with `NonZeroI32`, and similar for all other integer types with their /// matching `NonZero*` type. /// - If `T` is guaranteed to be subject to the [null pointer /// optimization](option/index.html#representation), then `T` and `Option` are ABI-compatible. +/// +/// Furthermore, ABI compatibility satisfies the following general properties: +/// +/// - Every type is ABI-compatible with itself. /// - If `T1` and `T2` are ABI-compatible, then two `repr(C)` types that only differ because one /// field type was changed from `T1` to `T2` are ABI-compatible. -/// - ABI-compatibility is symmetric and transitive. +/// - If `T1` and `T2` are ABI-compatible and `T2` and `T3` are ABI-compatible, then so are `T1` and +/// `T3` (i.e., ABI-compatibility is transitive). +/// - If `T1` and `T2` are ABI-compatible, then so are `T2` and `T1` (i.e., ABI-compatibility is +/// symmetric). /// /// More signatures can be ABI-compatible on specific targets, but that should not be relied upon /// since it is not portable and not a stable guarantee. @@ -1565,7 +1572,7 @@ mod prim_ref {} /// Noteworthy cases of types *not* being ABI-compatible in general are `bool` vs `u8`, and `i32` vs /// `u32`: on some targets, the calling conventions for these types differ in terms of what they /// guarantee for the remaining bits in the register that are not used by the value. `i32` vs `f32` -/// has already been mentioned above. +/// are not compatible either, as has already been mentioned above. /// /// Note that these rules describe when two completely known types are ABI-compatible. When /// considering ABI compatibility of a type declared in another crate (including the standard