From 107cd8e2678a3e3c5058f37e16ff998bbeda36f5 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 15 Aug 2023 02:11:10 -0700 Subject: [PATCH] Add alignment to the NPO guarantee As far as I know, this is always true already, but it's not in the text of the Option module docs, so I figured I'd bring this up to FCP it. --- library/core/src/num/nonzero.rs | 14 ++++++++++++++ library/core/src/option.rs | 2 +- library/core/src/ptr/non_null.rs | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 5939dedbd1db0..7f8d673c179a3 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -41,6 +41,20 @@ macro_rules! nonzero_integers { /// with the exception that `0` is not a valid instance. #[doc = concat!("`Option<", stringify!($Ty), ">` is guaranteed to be compatible with `", stringify!($Int), "`,")] /// including in FFI. + /// + /// Thanks to the [null pointer optimization], + #[doc = concat!("`", stringify!($Ty), "` and `Option<", stringify!($Ty), ">`")] + /// are guaranteed to have the same size and alignment: + /// + /// ``` + /// # use std::mem::{size_of, align_of}; + #[doc = concat!("use std::num::", stringify!($Ty), ";")] + /// + #[doc = concat!("assert_eq!(size_of::<", stringify!($Ty), ">(), size_of::>());")] + #[doc = concat!("assert_eq!(align_of::<", stringify!($Ty), ">(), align_of::>());")] + /// ``` + /// + /// [null pointer optimization]: crate::option#representation #[$stability] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index becb6330997d8..f2909a81d4920 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -119,7 +119,7 @@ //! # Representation //! //! Rust guarantees to optimize the following types `T` such that -//! [`Option`] has the same size as `T`: +//! [`Option`] has the same size and alignment as `T`: //! //! * [`Box`] //! * `&U` diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 9582ca9e0beff..8c8d4b55a4ad0 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -43,9 +43,27 @@ use crate::slice::{self, SliceIndex}; /// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr` /// is never used for mutation. /// +/// # Representation +/// +/// Thanks to the [null pointer optimization], +/// `NonNull` and `Option>` +/// are guaranteed to have the same size and alignment: +/// +/// ``` +/// # use std::mem::{size_of, align_of}; +/// use std::ptr::NonNull; +/// +/// assert_eq!(size_of::>(), size_of::>>()); +/// assert_eq!(align_of::>(), align_of::>>()); +/// +/// assert_eq!(size_of::>(), size_of::>>()); +/// assert_eq!(align_of::>(), align_of::>>()); +/// ``` +/// /// [covariant]: https://doc.rust-lang.org/reference/subtyping.html /// [`PhantomData`]: crate::marker::PhantomData /// [`UnsafeCell`]: crate::cell::UnsafeCell +/// [null pointer optimization]: crate::option#representation #[stable(feature = "nonnull", since = "1.25.0")] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)]