diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index eaec0c9857d28..7c66559269580 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 430ee3470ac3f..e3c4758bc6af5 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -118,9 +118,14 @@ //! //! # 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: +//! Rust guarantees to optimize the following types `T` such that [`Option`] +//! has the same size, alignment, and [function call ABI] as `T`. It is +//! therefore sound, when `T` is one of these types, to transmute a value `t` of +//! type `T` to type `Option` (producing the value `Some(t)`) and to +//! transmute a value `Some(t)` of type `Option` to type `T` (producing the +//! value `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 c69762a728598..6fee7febde38d 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -230,24 +230,31 @@ //! //! # 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. +//! 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 a value `t` of type `I` to type +//! `Result` (producing the value `Ok(t)`) and to transmute a value +//! `Ok(t)` of type `Result` to type `I` (producing the value `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, 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: +//! 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 between these is in 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 //!