1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use std::mem::MaybeUninit;
/// [`MaybeUninit::fill_from`] backported to stable.
///
/// TODO: remove in favor of [`MaybeUninit::fill_from`] once stabilized.
/// <https://github.com/rust-lang/rust/issues/117428>
pub fn maybe_uninit_fill_from<I: IntoIterator>(
this: &mut [MaybeUninit<I::Item>],
it: I,
) -> (&mut [I::Item], &mut [MaybeUninit<I::Item>]) {
let iter = it.into_iter();
let mut initialized_len = 0;
for (element, val) in this.iter_mut().zip(iter) {
element.write(val);
initialized_len += 1;
}
// SAFETY: guard.initialized <= this.len()
let (initted, remainder) = unsafe { this.split_at_mut_unchecked(initialized_len) };
// SAFETY: Valid elements have just been written into `init`, so that portion
// of `this` is initialized.
(unsafe { assume_init_mut(initted) }, remainder)
}
/// [`<[MaybeUninit]>::assume_init_mut`] backported to stable.
/// <https://github.com/rust-lang/rust/issues/63569>
///
/// Gets a mutable (unique) reference to the contained value.
///
/// # Safety
///
/// Calling this when the content is not yet fully initialized causes undefined
/// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in the
/// slice really is in an initialized state. For instance, `.assume_init_mut()` cannot
/// be used to initialize a `MaybeUninit` slice.
#[inline(always)]
pub const unsafe fn assume_init_mut<T>(this: &mut [MaybeUninit<T>]) -> &mut [T] {
// SAFETY: similar to safety notes for `slice_get_ref`, but we have a
// mutable reference which is also guaranteed to be valid for writes.
unsafe { &mut *(this as *mut [MaybeUninit<T>] as *mut [T]) }
}
/// # Safety
///
/// Calling this when the content is not yet fully initialized causes undefined
/// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in the
/// vec really is in an initialized state. For instance, `.assume_init_vec()` cannot
/// be used to initialize a `MaybeUninit` vec.
#[inline(always)]
pub unsafe fn assume_init_vec<T>(this: Vec<MaybeUninit<T>>) -> Vec<T> {
// SAFETY: caller must guarantee every element was initialized.
unsafe {
let (ptr, len, cap) = this.into_raw_parts();
Vec::from_raw_parts(ptr.cast::<T>(), len, cap)
}
}