diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 88527fa2e6e78..a45d4a75e178a 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -814,7 +814,7 @@ fn get_nullable_type<'tcx>( /// A type is niche-optimization candidate iff: /// - Is a zero-sized type with alignment 1 (a “1-ZST”). -/// - Has no fields. +/// - Is either a struct/tuple with no fields, or an enum with no variants. /// - Does not have the `#[non_exhaustive]` attribute. fn is_niche_optimization_candidate<'tcx>( tcx: TyCtxt<'tcx>, @@ -828,7 +828,7 @@ fn is_niche_optimization_candidate<'tcx>( match ty.kind() { ty::Adt(ty_def, _) => { let non_exhaustive = ty_def.is_variant_list_non_exhaustive(); - let empty = (ty_def.is_struct() && ty_def.all_fields().next().is_none()) + let empty = (ty_def.is_struct() && ty_def.non_enum_variant().fields.is_empty()) || (ty_def.is_enum() && ty_def.variants().is_empty()); !non_exhaustive && empty diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 198636c67d0b1..0a59bb1822838 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -119,8 +119,11 @@ //! # Representation //! //! Rust guarantees to optimize the following types `T` such that -//! [`Option`] has the same size, alignment, and [function call ABI] as `T`. In some -//! of these cases, Rust further guarantees the following: +//! [`Option`] has the same size, alignment, and [function call ABI] as `T`. +//! It is therefore sound to transmute `t: T` to `Option` (which will produce `Some(t)`), and +//! to transmute `Some(t): Option` to `T` (which will produce `t`). +//! +//! In some of these cases, Rust further guarantees the following: //! - `transmute::<_, Option>([0u8; size_of::()])` is sound and produces //! `Option::::None` //! - `transmute::<_, [u8; size_of::()]>(Option::::None)` is sound and produces diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 7dffab9b316f6..6b234bd0c496a 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -230,24 +230,26 @@ //! //! # Representation //! -//! In some cases, [`Result`] will gain the same size, alignment, and ABI -//! guarantees as [`Option`] has. One of either the `T` or `E` type must be a -//! type that qualifies for the `Option` [representation guarantees][opt-rep], -//! and the *other* type must meet all of the following conditions: -//! * Is a zero-sized type with alignment 1 (a "1-ZST"). -//! * Has no fields. -//! * Does not have the `#[non_exhaustive]` attribute. -//! -//! For example, `NonZeroI32` qualifies for the `Option` representation -//! guarantees, and `()` is a zero-sized type with alignment 1, no fields, and -//! it isn't `non_exhaustive`. This means that both `Result` and -//! `Result<(), NonZeroI32>` have the same size, alignment, and ABI guarantees -//! as `Option`. The only difference is the implied semantics: +//! In some cases, [`Result`] comes with size, alignment, and ABI guarantees. +//! Specifically, one of either the `T` or `E` type must be a type that qualifies for the `Option` +//! [representation guarantees][opt-rep] (let's call that type `I`), and the *other* type +//! is a zero-sized type with alignment 1 (a "1-ZST"). +//! +//! If that is the case, then `Result` has the same size, alignment, and [function call ABI] +//! as `I` (and therefore, as `Option`). If `I` is `T`, it is therefore sound to transmute `t: I` +//! to `Result` (which will produce `Ok(t)`), and to transmute `Ok(t): Result` to `I` +//! (which will produce `t`). If `I` is `E`, the same applies with `Ok` replaced by `Err`. +//! +//! For example, `NonZeroI32` qualifies for the `Option` representation guarantees, and `()` is a +//! zero-sized type with alignment 1. This means that both `Result` and +//! `Result<(), NonZeroI32>` have the same size, alignment, and ABI +//! as `NonZeroI32` (and `Option`). The only difference is the implied semantics: //! * `Option` is "a non-zero i32 might be present" //! * `Result` is "a non-zero i32 success result, if any" //! * `Result<(), NonZeroI32>` is "a non-zero i32 error result, if any" //! //! [opt-rep]: ../option/index.html#representation "Option Representation" +//! [function call ABI]: ../primitive.fn.html#abi-compatibility //! //! # Method overview //!