@@ -6,8 +6,15 @@ use core::{mem::MaybeUninit, ptr};
6
6
/// been initialized.
7
7
#[ inline( always) ]
8
8
pub unsafe fn slice_assume_init_mut < T > ( slice : & mut [ MaybeUninit < T > ] ) -> & mut [ T ] {
9
- // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
10
- & mut * ( slice as * mut [ MaybeUninit < T > ] as * mut [ T ] )
9
+ let ptr: * mut [ MaybeUninit < T > ] = slice;
10
+ // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`
11
+ // and casting between two slice types of layout-compatible types is sound.
12
+ let ptr = ptr as * mut [ T ] ;
13
+ // SAFETY: ptr was soundly constructed from a valid `&mut` reference so it
14
+ // safe to dereference it if the caller has ensured every element of `slice`
15
+ // has been ininitialized.
16
+ #[ allow( unused_unsafe) ] // TODO(MSRV 1.65): Remove this.
17
+ unsafe { & mut * ptr }
11
18
}
12
19
13
20
#[ inline]
@@ -18,10 +25,16 @@ pub fn uninit_slice_fill_zero(slice: &mut [MaybeUninit<u8>]) -> &mut [u8] {
18
25
19
26
#[ inline( always) ]
20
27
pub fn slice_as_uninit < T > ( slice : & [ T ] ) -> & [ MaybeUninit < T > ] {
21
- // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
22
- // There is no risk of writing a `MaybeUninit<T>` into the result since
23
- // the result isn't mutable.
24
- unsafe { & * ( slice as * const [ T ] as * const [ MaybeUninit < T > ] ) }
28
+ let ptr: * const [ T ] = slice;
29
+ // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`
30
+ // and casting between two slice types of layout-compatible types is sound.
31
+ let ptr = ptr as * const [ MaybeUninit < T > ] ;
32
+ // SAFETY:
33
+ // * ptr was soundly constructed from a valid reference so it safe to
34
+ // dereference it.
35
+ // * There is no risk of writing a `MaybeUninit<T>` into the result
36
+ // since the result isn't mutable.
37
+ unsafe { & * ptr }
25
38
}
26
39
27
40
/// View an mutable initialized array as potentially-uninitialized.
@@ -30,6 +43,15 @@ pub fn slice_as_uninit<T>(slice: &[T]) -> &[MaybeUninit<T>] {
30
43
/// `slice`, which would be undefined behavior.
31
44
#[ inline( always) ]
32
45
pub unsafe fn slice_as_uninit_mut < T > ( slice : & mut [ T ] ) -> & mut [ MaybeUninit < T > ] {
33
- // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
34
- & mut * ( slice as * mut [ T ] as * mut [ MaybeUninit < T > ] )
46
+ let ptr: * mut [ T ] = slice;
47
+ // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`
48
+ // and casting between two slice types of layout-compatible types is sound.
49
+ let ptr = ptr as * mut [ MaybeUninit < T > ] ;
50
+ // SAFETY:
51
+ // * ptr was soundly constructed from a valid reference so it safe to
52
+ // dereference it.
53
+ // * There *IS* a risk of writing a `MaybeUninit<T>` into the result,
54
+ // which is why this function is unsafe.
55
+ #[ allow( unused_unsafe) ] // TODO(MSRV 1.65): Remove this.
56
+ unsafe { & mut * ptr }
35
57
}
0 commit comments