Skip to content

Commit

Permalink
Stabilize const_maybe_uninit_zeroed
Browse files Browse the repository at this point in the history
Make `MaybeUninit::zeroed` const stable. Newly stable API:

    // core::mem
    impl<T> MaybeUninit<T> {
        pub const fn zeroed() -> MaybeUninit<T>;
    }

Use of `const_mut_refs` should be acceptable since we do not leak the
mutability.

Tracking issue: #91850
  • Loading branch information
tgross35 committed Sep 28, 2023
1 parent 2ba4eb2 commit 5aac56c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
1 change: 0 additions & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
28 changes: 22 additions & 6 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,20 @@ impl<T> MaybeUninit<T> {
/// 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<fn(u32) -> 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:
///
Expand All @@ -387,17 +401,19 @@ impl<T> MaybeUninit<T> {
/// // 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<T> {
let mut u = MaybeUninit::<T>::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
}

Expand Down

0 comments on commit 5aac56c

Please sign in to comment.