Skip to content

Commit

Permalink
Rollup merge of #125995 - kpreid:const-uninit-stable, r=Nilstrieb
Browse files Browse the repository at this point in the history
Use inline const blocks to create arrays of `MaybeUninit`.

This PR contains 2 changes enabled by the fact that [`inline_const` is now stable](#104087), and was split out of #125082.

1. Use inline const instead of `unsafe` to construct arrays in `MaybeUninit` examples.

   Rationale: Demonstrate good practice of avoiding `unsafe` code where it is not strictly necessary.

4. Use inline const instead of `unsafe` to implement `MaybeUninit::uninit_array()`.

    This is arguably giving the compiler more work to do, in exchange for eliminating just one single internal unsafe block, so it's less certain that this is good on net.

r​? `@Nilstrieb`
  • Loading branch information
workingjubilee authored Jun 5, 2024
2 parents 448159c + ec8fa17 commit 6b6b698
Showing 1 changed file with 5 additions and 12 deletions.
17 changes: 5 additions & 12 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,8 @@ use crate::slice;
/// use std::mem::{self, MaybeUninit};
///
/// let data = {
/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
/// // safe because the type we are claiming to have initialized here is a
/// // bunch of `MaybeUninit`s, which do not require initialization.
/// let mut data: [MaybeUninit<Vec<u32>>; 1000] = unsafe {
/// MaybeUninit::uninit().assume_init()
/// };
/// // Create an uninitialized array of `MaybeUninit`.
/// let mut data: [MaybeUninit<Vec<u32>>; 1000] = [const { MaybeUninit::uninit() }; 1000];
///
/// // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop,
/// // we have a memory leak, but there is no memory safety issue.
Expand All @@ -147,10 +143,8 @@ use crate::slice;
/// ```
/// use std::mem::MaybeUninit;
///
/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
/// // safe because the type we are claiming to have initialized here is a
/// // bunch of `MaybeUninit`s, which do not require initialization.
/// let mut data: [MaybeUninit<String>; 1000] = unsafe { MaybeUninit::uninit().assume_init() };
/// // Create an uninitialized array of `MaybeUninit`.
/// let mut data: [MaybeUninit<String>; 1000] = [const { MaybeUninit::uninit() }; 1000];
/// // Count the number of elements we have assigned.
/// let mut data_len: usize = 0;
///
Expand Down Expand Up @@ -348,8 +342,7 @@ impl<T> MaybeUninit<T> {
#[must_use]
#[inline(always)]
pub const fn uninit_array<const N: usize>() -> [Self; N] {
// SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() }
[const { MaybeUninit::uninit() }; N]
}

/// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
Expand Down

0 comments on commit 6b6b698

Please sign in to comment.