From 5aac56c0b4ad1ca3c8163bbf2988b41fc58356a7 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 28 Sep 2023 01:57:01 -0400 Subject: [PATCH] Stabilize `const_maybe_uninit_zeroed` Make `MaybeUninit::zeroed` const stable. Newly stable API: // core::mem impl MaybeUninit { pub const fn zeroed() -> MaybeUninit; } Use of `const_mut_refs` should be acceptable since we do not leak the mutability. Tracking issue: #91850 --- library/alloc/src/lib.rs | 1 - library/core/src/mem/maybe_uninit.rs | 28 ++++++++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index f435f503fc160..5b7062dec7a56 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -113,7 +113,6 @@ #![feature(const_eval_select)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_write)] -#![feature(const_maybe_uninit_zeroed)] #![feature(const_pin)] #![feature(const_refs_to_cell)] #![feature(const_size_of_val)] diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index d09a24b4b1d5b..ad0b121f5ed5c 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -374,6 +374,20 @@ impl MaybeUninit { /// assert_eq!(x, (0, false)); /// ``` /// + /// This can be used in const contexts, such as to indicate the end of plugin registration + /// arrays. + /// + /// ``` + /// use std::mem::MaybeUninit; + /// + /// struct PluginInfo { id: u32, action: Option u32> } + /// + /// static PLUGIN_LIST: [PluginInfo; 2] = [ + /// PluginInfo { id: 1, action: Some(|x| x + 5) }, + /// unsafe { MaybeUninit::zeroed().assume_init() } + /// ]; + /// ``` + /// /// *Incorrect* usage of this function: calling `x.zeroed().assume_init()` /// when `0` is not a valid bit-pattern for the type: /// @@ -387,17 +401,19 @@ impl MaybeUninit { /// // Inside a pair, we create a `NotZero` that does not have a valid discriminant. /// // This is undefined behavior. ⚠️ /// ``` - #[stable(feature = "maybe_uninit", since = "1.36.0")] - #[rustc_const_unstable(feature = "const_maybe_uninit_zeroed", issue = "91850")] - #[must_use] #[inline] + #[must_use] #[rustc_diagnostic_item = "maybe_uninit_zeroed"] + #[stable(feature = "maybe_uninit", since = "1.36.0")] + // These are OK to allow since we do not leak &mut to user-visible API + #[rustc_allow_const_fn_unstable(const_mut_refs)] + #[rustc_allow_const_fn_unstable(const_ptr_write)] + #[rustc_allow_const_fn_unstable(const_maybe_uninit_as_mut_ptr)] + #[rustc_const_stable(feature = "const_maybe_uninit_zeroed", since = "CURRENT_RUSTC_VERSION")] pub const fn zeroed() -> MaybeUninit { let mut u = MaybeUninit::::uninit(); // SAFETY: `u.as_mut_ptr()` points to allocated memory. - unsafe { - u.as_mut_ptr().write_bytes(0u8, 1); - } + unsafe { u.as_mut_ptr().write_bytes(0u8, 1) }; u }