Skip to content
Open
Show file tree
Hide file tree
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
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand All @@ -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
Expand Down
7 changes: 5 additions & 2 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,11 @@
//! # Representation
//!
//! Rust guarantees to optimize the following types `T` such that
//! [`Option<T>`] has the same size, alignment, and [function call ABI] as `T`. In some
//! of these cases, Rust further guarantees the following:
//! [`Option<T>`] has the same size, alignment, and [function call ABI] as `T`.
//! It is therefore sound to transmute `t: T` to `Option<T>` (which will produce `Some(t)`), and
//! to transmute `Some(t): Option<T>` to `T` (which will produce `t`).
//!
//! In some of these cases, Rust further guarantees the following:
//! - `transmute::<_, Option<T>>([0u8; size_of::<T>()])` is sound and produces
//! `Option::<T>::None`
//! - `transmute::<_, [u8; size_of::<T>()]>(Option::<T>::None)` is sound and produces
Expand Down
28 changes: 15 additions & 13 deletions library/core/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,24 +230,26 @@
//!
//! # Representation
//!
//! In some cases, [`Result<T, E>`] will gain the same size, alignment, and ABI
//! guarantees as [`Option<U>`] 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<NonZeroI32, ()>` and
//! `Result<(), NonZeroI32>` have the same size, alignment, and ABI guarantees
//! as `Option<NonZeroI32>`. The only difference is the implied semantics:
//! In some cases, [`Result<T, E>`] 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<T, E>` has the same size, alignment, and [function call ABI]
//! as `I` (and therefore, as `Option<I>`). If `I` is `T`, it is therefore sound to transmute `t: I`
//! to `Result<T, E>` (which will produce `Ok(t)`), and to transmute `Ok(t): Result<T, E>` 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<NonZeroI32, ()>` and
//! `Result<(), NonZeroI32>` have the same size, alignment, and ABI
//! as `NonZeroI32` (and `Option<NonZeroI32>`). The only difference is the implied semantics:
//! * `Option<NonZeroI32>` is "a non-zero i32 might be present"
//! * `Result<NonZeroI32, ()>` 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
//!
Expand Down
Loading