Skip to content

Commit a8e5377

Browse files
committed
Result/Option layout guarantee clarifications
1 parent 408eacf commit a8e5377

File tree

2 files changed

+17
-8
lines changed

2 files changed

+17
-8
lines changed

library/core/src/option.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,11 @@
119119
//! # Representation
120120
//!
121121
//! Rust guarantees to optimize the following types `T` such that
122-
//! [`Option<T>`] has the same size, alignment, and [function call ABI] as `T`. In some
123-
//! of these cases, Rust further guarantees the following:
122+
//! [`Option<T>`] has the same size, alignment, and [function call ABI] as `T`.
123+
//! It is therefore sound to transmute `t: T` to `Option<T>` (which will produce `Some(t)`), and
124+
//! to transmute `Some(t): Option<T>` to `T` (which will produce `t`).
125+
//!
126+
//! In some of these cases, Rust further guarantees the following:
124127
//! - `transmute::<_, Option<T>>([0u8; size_of::<T>()])` is sound and produces
125128
//! `Option::<T>::None`
126129
//! - `transmute::<_, [u8; size_of::<T>()]>(Option::<T>::None)` is sound and produces

library/core/src/result.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,24 +230,30 @@
230230
//!
231231
//! # Representation
232232
//!
233-
//! In some cases, [`Result<T, E>`] will gain the same size, alignment, and ABI
234-
//! guarantees as [`Option<U>`] has. One of either the `T` or `E` type must be a
235-
//! type that qualifies for the `Option` [representation guarantees][opt-rep],
236-
//! and the *other* type must meet all of the following conditions:
233+
//! In some cases, [`Result<T, E>`] comes with size, alignment, and ABI guarantees.
234+
//! Specifically, one of either the `T` or `E` type must be a type that qualifies for the `Option`
235+
//! [representation guarantees][opt-rep] (let's call that type `I`), and the *other* type must meet
236+
//! all of the following conditions:
237237
//! * Is a zero-sized type with alignment 1 (a "1-ZST").
238238
//! * Has no fields.
239239
//! * Does not have the `#[non_exhaustive]` attribute.
240240
//!
241+
//! If that is the case, then `Result<T, E>` has the same size, alignment, and [function call ABI]
242+
//! as `I` (and therefore, as `Option<I>`). If `I` is `T`, it is therefore sound to transmute `t: I`
243+
//! to `Result<T, E>` (which will produce `Ok(t)`), and to transmute `Ok(t): Result<T, E>` to `I`
244+
//! (which will produce `t`). If `I` is `E`, the same applies with `Ok` replaced by `Err`.
245+
//!
241246
//! For example, `NonZeroI32` qualifies for the `Option` representation
242247
//! guarantees, and `()` is a zero-sized type with alignment 1, no fields, and
243248
//! it isn't `non_exhaustive`. This means that both `Result<NonZeroI32, ()>` and
244-
//! `Result<(), NonZeroI32>` have the same size, alignment, and ABI guarantees
245-
//! as `Option<NonZeroI32>`. The only difference is the implied semantics:
249+
//! `Result<(), NonZeroI32>` have the same size, alignment, and ABI
250+
//! as `NonZeroI32` (and `Option<NonZeroI32>`). The only difference is the implied semantics:
246251
//! * `Option<NonZeroI32>` is "a non-zero i32 might be present"
247252
//! * `Result<NonZeroI32, ()>` is "a non-zero i32 success result, if any"
248253
//! * `Result<(), NonZeroI32>` is "a non-zero i32 error result, if any"
249254
//!
250255
//! [opt-rep]: ../option/index.html#representation "Option Representation"
256+
//! [function call ABI]: ../primitive.fn.html#abi-compatibility
251257
//!
252258
//! # Method overview
253259
//!

0 commit comments

Comments
 (0)