Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
20 changes: 13 additions & 7 deletions library/core/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,24 +230,30 @@
//!
//! # 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:
//! 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 must meet
//! all of the following conditions:
//! * 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.
//!
//! 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, 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:
//! `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