Trait uninit::extension_traits::MaybeUninitExt
source · pub trait MaybeUninitExt {
type T: ?Sized;
// Required methods
unsafe fn assume_init_by_ref(&self) -> &Self::T;
unsafe fn assume_init_by_mut(&mut self) -> &mut Self::T;
fn from_ref(init_ref: &Self::T) -> &Self;
}
Expand description
Extension trait providing tranformations between init and uninit.
This is currently only implemented for Copy
types, since the
semantics when drop
glue is involved are less
easy to handle correctly (danger of leaking memory).
from_mut
?
The conversion &mut T
to &mut MaybeUninit<T>
is actually unsound,
since there is nothing preventing the obtained mut
reference to be used
to overwrite the pointee with MaybeUninit::uninit()
, i.e., an
uninitialised (and thus garbage) value:
use ::core::mem::{MaybeUninit, transmute};
unsafe fn from_mut<T> (it: &'_ mut T) -> &'_ mut MaybeUninit<T>
{
transmute(it)
}
let mut x = Box::new(42);
let at_x_uninit: &mut MaybeUninit<Box<i32>> = unsafe {
// If this were safe...
from_mut(&mut x)
};
// Then safe code would be able to do this:
*at_x_uninit = MaybeUninit::uninit(); // <--------+
// drop(x); // drops an uninitialized value! UB --+
The author of the crate did overlook that and offered such transformation
within a non-unsafe
function, leading to an unsound function. Hence the
yanked versions of the crate.
The correct way to do this now is through
the &out
reference abstraction.
Required Associated Types§
Required Methods§
sourceunsafe fn assume_init_by_ref(&self) -> &Self::T
unsafe fn assume_init_by_ref(&self) -> &Self::T
Converts a &MaybeUninit<_>
to a & _
.
Safety
Don’t be lured by the reference: this has the same safety requirements
that .assume_init
does. Mainly:
- The
Self::T
thatself
points to must be initialized.
sourceunsafe fn assume_init_by_mut(&mut self) -> &mut Self::T
unsafe fn assume_init_by_mut(&mut self) -> &mut Self::T
Converts a &mut MaybeUninit<_>
to a &mut _
.
Safety
Don’t be lured by the mut
reference: this has the same safety
requirements that .assume_init
does.
Mainly:
- The
Self::T
thatself
points to must be initialized.