New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Meta tracking Issue for MaybeUninit methods for arrays #96097
Comments
…up, r=dtolnay MaybeUninit array cleanup * Links `MaybeUninit::uninit_array` to meta-tracking issue * Links `MaybeUninit::array_assume_init` to meta-tracking issue * Unstably constifies `MaybeUninit::array_assume_init` Another thing worth mentioning: this splits the const feature flag for `maybe_uninit_uninit_array` into `const_maybe_uninit_uninit_array` to avoid weird cases where only one gets stabilised. Note that it may be desired to keep the `array_assume_init` method linked to its dedicated issue, but at least for now, I decided to link to the meta-tracking issue so that all of the methods lead users to the same place. But I can revert that bit if desired. The meta-tracking issue that I filed is rust-lang#96097.
I'm a bit concerned about the size and inconsistency of this API, as the corresponding functions for single values are all methods, while for arrays and slices we have associated functions. For example, I would rather prefer a trait-based API like this: unsafe trait Uninitialized {
type Initialized: ?Sized;
fn uninit() -> Self
where Self: Sized;
fn zeroed() -> Self
where Self: Sized;
unsafe fn assume_init(self) -> Self::Initialized
where Self: Sized;
unsafe fn assume_init_ref(&self) -> &Self::Initialized;
...
}
unsafe impl<T> Uninitialized for MaybeUninit {...}
unsafe impl<T, const N: usize> Uninitialized for [T; N] {...}
unsafe impl<T> Uninitialized for [T] {...} or with a marker trait like I proposed here. |
I don't think it's worth making a trait for this. I've had many use cases for uninit_array before, and none for a generic solution. MaybeUninit is often used with arrays, since that's where initialization tends to be the most expensive. While it is a trivial function to write yourself, I do think that it's worth it to stabilize |
Another thing worth asking: why not have methods directly implemented on arrays? You'd still need some form of This seems possible specifically because the types exist in core, but open to other interpretations. I also suggested perhaps just adding Of course, the weirdness of |
@clarfonthey with the current implementation, |
Docs patch extracted from #102023: Subject: [PATCH] Add MaybeUninit array transpose impls
Signed-off-by: Alex Saveau <[email protected]>
---
Index: library/core/src/mem/maybe_uninit.rs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
--- a/library/core/src/mem/maybe_uninit.rs (revision 8147e6e427a1b3c4aedcd9fd85bd457888f80972)
+++ b/library/core/src/mem/maybe_uninit.rs (date 1665873934720)
@@ -117,15 +117,12 @@
/// `MaybeUninit<T>` can be used to initialize a large array element-by-element:
///
/// ```
-/// use std::mem::{self, MaybeUninit};
+/// use std::mem::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] = MaybeUninit::uninit().transpose();
///
/// // 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.
@@ -133,25 +130,23 @@
/// elem.write(vec![42]);
/// }
///
-/// // Everything is initialized. Transmute the array to the
-/// // initialized type.
-/// unsafe { mem::transmute::<_, [Vec<u32>; 1000]>(data) }
+/// // Everything is initialized. Convert the array to the initialized type.
+/// unsafe { MaybeUninit::<[Vec<_>; 1000]>::assume_init(data.transpose()) }
/// };
///
-/// assert_eq!(&data[0], &[42]);
+/// assert_eq!(&data[42], &[42]);
/// ```
///
/// You can also work with partially initialized arrays, which could
/// be found in low-level datastructures.
///
/// ```
/// use std::mem::MaybeUninit;
/// use std::ptr;
///
-/// // 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] = MaybeUninit::uninit().transpose();
/// // Count the number of elements we have assigned.
/// let mut data_len: usize = 0;
/// |
…r=scottmcm Add MaybeUninit array transpose From impls See discussion in rust-lang#101179 and rust-lang#96097. I believe this solution offers the simplest implementation with minimal future API regret. `@RalfJung` mind doing a correctness review?
Deprecate uninit_array Now that rust-lang#98304 has gone through, `uninit_array` should be removed since creating a const array is the One True Way of doing things. Tracking issue: rust-lang#96097
Add MaybeUninit array transpose From impls See discussion in rust-lang/rust#101179 and rust-lang/rust#96097. I believe this solution offers the simplest implementation with minimal future API regret. `@RalfJung` mind doing a correctness review?
This is a meta-tracking issue for multiple APIs that are linked across multiple issues. Right now it only includes two methods, but since there seems to be a desire to add more, this issue can be used as a placeholder for those discussions until those methods are added.
Public API
Sub-tracking issues:
MaybeUninit::array_assume_init
: Tracking Issue for maybe_uninit_array_assume_init #80908Steps / History
MaybeUninit::uninit_array
implementation: AddMaybeUninit
methodsuninit_array
,slice_get_ref
,slice_get_mut
#65580MaybeUninit::array_assume_init
implementation: AddMaybeUninit
methodarray_assume_init
#80600MaybeUninit::array_assume_init
const implementation: MaybeUninit array cleanup #96099Unresolved Questions
MaybeUninit::uninit_array::<LEN>()
be stabilised if it can be replaced by[const { MaybeUninit::uninit() }; LEN]
?array_assume_init
the right pattern, or should we convert from[MaybeUninit<T>, N]
back toMaybeUninit<[T; N]>
first?The text was updated successfully, but these errors were encountered: