Skip to content

Commit 48a044b

Browse files
committed
remove unsound MaybeUninitSlice::from_init_mut and useless ...::from_init
Well, that's weird. I've had a safety comment: ```rust // `MaybeUninit<T>` is guaranteed to have the same ABI as `T`, so // it's safe to cast `&mut [T]` to `&mut [MaybeUninit<T>]` ``` But it's wrong. `&mut T` and `T` isn't the same thing. While it's true that `T => MaybeUninit<T>` or the same for an owned container (array, box, etc) should be fine, for an unique borrowed container (`&mut _`, `&mut [_]`) it is definitely **not fine**, because the original owned value remains `T`. Example of such a UB in safe code: ```rust let mut a = ["string"]; <_>::from_init_mut(&mut a[..])[0] = MaybeUninit::uninit(); println!("{}", a); // segfault ``` You can also think of `MaybeUninit<T>` as a supertype of `T` and then note that `&mut T` is invariant over `T`: https://doc.rust-lang.org/nomicon/subtyping.html#variance The weirdest part of all of this is that I haven't tested those functions. There aren't any tests. There aren't any test for safe function with unsafe in it! I am ashamed... A related issue in `rust-lang` repo, about documenting unsoundness of `&mut T => &mut MaybeUninit<T>`: rust-lang/rust#66699
1 parent 9fa1aa2 commit 48a044b

File tree

1 file changed

+0
-24
lines changed

1 file changed

+0
-24
lines changed

src/ext/slice_ext.rs

-24
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,6 @@ pub trait MaybeUninitSlice:
164164
/// [inv]: core::mem#initialization-invariant
165165
/// [`MaybeUninit::assume_init`]: core::mem::MaybeUninit::assume_init
166166
unsafe fn assume_init_mut(&mut self) -> &mut [Self::InitItem];
167-
168-
/// Create self from initialized slice
169-
fn from_init(init: &[Self::InitItem]) -> &Self;
170-
171-
/// Create self from initialized slice
172-
fn from_init_mut(init: &mut [Self::InitItem]) -> &mut Self;
173167
}
174168

175169
impl<T> Slice for [T] {
@@ -223,22 +217,4 @@ impl<T> MaybeUninitSlice for [MaybeUninit<T>] {
223217
// `uninit` state
224218
&mut *(self as *mut [MaybeUninit<T>] as *mut [T])
225219
}
226-
227-
#[inline]
228-
fn from_init(init: &[Self::InitItem]) -> &Self {
229-
// ## Safety
230-
//
231-
// `MaybeUninit<T>` is guaranteed to have the same ABI as `T`, so
232-
// it's safe to cast `&[T]` to `&[MaybeUninit<T>]`
233-
unsafe { &*(init as *const [T] as *const [MaybeUninit<T>]) }
234-
}
235-
236-
#[inline]
237-
fn from_init_mut(init: &mut [Self::InitItem]) -> &mut Self {
238-
// ## Safety
239-
//
240-
// `MaybeUninit<T>` is guaranteed to have the same ABI as `T`, so
241-
// it's safe to cast `&mut [T]` to `&mut [MaybeUninit<T>]`
242-
unsafe { &mut *(init as *mut [T] as *mut [MaybeUninit<T>]) }
243-
}
244220
}

0 commit comments

Comments
 (0)