Skip to content

Commit 30a4332

Browse files
committed
apply feedback
1 parent b7afe77 commit 30a4332

File tree

1 file changed

+36
-28
lines changed

1 file changed

+36
-28
lines changed

src/libcore/mem.rs

+36-28
Original file line numberDiff line numberDiff line change
@@ -471,14 +471,12 @@ pub const fn needs_drop<T>() -> bool {
471471
/// There is no guarantee that an all-zero byte-pattern represents a valid value of
472472
/// some type `T`. For example, the all-zero byte-pattern is not a valid value
473473
/// for reference types (`&T` and `&mut T`). Using `zeroed` on such types
474-
/// causes immediate [undefined behavior][ub].
475-
///
476-
/// See the documentation of [`MaybeUninit<T>`] and [`MaybeUninit::zeroed()`][zeroed]
477-
/// for more discussion on how to initialize values.
474+
/// causes immediate [undefined behavior][ub] because [the Rust compiler assumes][inv]
475+
/// that there always is a valid value in a variable it considers initialized.
478476
///
479477
/// [zeroed]: union.MaybeUninit.html#method.zeroed
480-
/// [`MaybeUninit<T>`]: union.MaybeUninit.html
481478
/// [ub]: ../../reference/behavior-considered-undefined.html
479+
/// [inv]: union.MaybeUninit.html#initialization-invariant
482480
///
483481
/// # Examples
484482
///
@@ -508,11 +506,21 @@ pub unsafe fn zeroed<T>() -> T {
508506
/// Bypasses Rust's normal memory-initialization checks by pretending to
509507
/// produce a value of type `T`, while doing nothing at all.
510508
///
511-
/// **This functon is deprecated because it basically cannot be used correctly.**
509+
/// **This functon is deprecated.** Use [`MaybeUninit<T>`] instead.
512510
///
513-
/// Use [`MaybeUninit<T>`] instead.
511+
/// The reason for deprecation is that the function basically cannot be used
512+
/// correctly: [the Rust compiler assumes][inv] that values are properly initialized.
513+
/// As a consequence, calling e.g. `mem::uninitialized::<bool>()` causes immediate
514+
/// undefined behavior for returning a `bool` that is not definitely either `true`
515+
/// or `false`. Worse, truly uninitialized memory like what gets returned here
516+
/// is special in that the compiler knows that it does not have a fixed value.
517+
/// This makes it undefined behavior to have uninitialized data in a variable even
518+
/// if that variable has an integer type.
519+
/// (Notice that the rules around uninitialized integers are not finalized yet, but
520+
/// until they are, it is advisable to avoid them.)
514521
///
515522
/// [`MaybeUninit<T>`]: union.MaybeUninit.html
523+
/// [inv]: union.MaybeUninit.html#initialization-invariant
516524
#[inline]
517525
#[rustc_deprecated(since = "1.40.0", reason = "use `mem::MaybeUninit` instead")]
518526
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1022,21 +1030,23 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
10221030
/// use std::mem::{self, MaybeUninit};
10231031
/// use std::ptr;
10241032
///
1025-
/// let data = unsafe {
1033+
/// let data = {
10261034
/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
10271035
/// // safe because the type we are claiming to have initialized here is a
10281036
/// // bunch of `MaybeUninit`s, which do not require initialization.
1029-
/// let mut data: [MaybeUninit<Vec<u32>>; 1000] = MaybeUninit::uninit().assume_init();
1037+
/// let mut data: [MaybeUninit<Vec<u32>>; 1000] = unsafe {
1038+
/// MaybeUninit::uninit().assume_init()
1039+
/// };
10301040
///
10311041
/// // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop,
10321042
/// // we have a memory leak, but there is no memory safety issue.
10331043
/// for elem in &mut data[..] {
1034-
/// ptr::write(elem.as_mut_ptr(), vec![42]);
1044+
/// unsafe { ptr::write(elem.as_mut_ptr(), vec![42]); }
10351045
/// }
10361046
///
10371047
/// // Everything is initialized. Transmute the array to the
10381048
/// // initialized type.
1039-
/// mem::transmute::<_, [Vec<u32>; 1000]>(data)
1049+
/// unsafe { mem::transmute::<_, [Vec<u32>; 1000]>(data) }
10401050
/// };
10411051
///
10421052
/// println!("{:?}", &data[0]);
@@ -1049,29 +1059,27 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
10491059
/// use std::mem::MaybeUninit;
10501060
/// use std::ptr;
10511061
///
1052-
/// unsafe {
1053-
/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
1054-
/// // safe because the type we are claiming to have initialized here is a
1055-
/// // bunch of `MaybeUninit`s, which do not require initialization.
1056-
/// let mut data: [MaybeUninit<String>; 1000] = MaybeUninit::uninit().assume_init();
1057-
/// // Count the number of elements we have assigned.
1058-
/// let mut data_len: usize = 0;
1062+
/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
1063+
/// // safe because the type we are claiming to have initialized here is a
1064+
/// // bunch of `MaybeUninit`s, which do not require initialization.
1065+
/// let mut data: [MaybeUninit<String>; 1000] = unsafe { MaybeUninit::uninit().assume_init() };
1066+
/// // Count the number of elements we have assigned.
1067+
/// let mut data_len: usize = 0;
10591068
///
1060-
/// for elem in &mut data[0..500] {
1061-
/// ptr::write(elem.as_mut_ptr(), String::from("hello"));
1062-
/// data_len += 1;
1063-
/// }
1069+
/// for elem in &mut data[0..500] {
1070+
/// unsafe { ptr::write(elem.as_mut_ptr(), String::from("hello")); }
1071+
/// data_len += 1;
1072+
/// }
10641073
///
1065-
/// // For each item in the array, drop if we allocated it.
1066-
/// for elem in &mut data[0..data_len] {
1067-
/// ptr::drop_in_place(elem.as_mut_ptr());
1068-
/// }
1074+
/// // For each item in the array, drop if we allocated it.
1075+
/// for elem in &mut data[0..data_len] {
1076+
/// unsafe { ptr::drop_in_place(elem.as_mut_ptr()); }
10691077
/// }
10701078
/// ```
10711079
///
10721080
/// ## Initializing a struct field-by-field
10731081
///
1074-
/// There is unfortunately currently no supported way to create a raw pointer or reference
1082+
/// There is currently no supported way to create a raw pointer or reference
10751083
/// to a field of a struct inside `MaybeUninit<Struct>`. That means it is not possible
10761084
/// to create a struct by calling `MaybeUninit::uninit::<Struct>()` and then writing
10771085
/// to its fields.
@@ -1183,7 +1191,7 @@ impl<T> MaybeUninit<T> {
11831191
/// Gets a pointer to the contained value. Reading from this pointer or turning it
11841192
/// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
11851193
/// Writing to memory that this pointer (non-transitively) points to is undefined behavior
1186-
/// (except inside an `UnsafeCell`).
1194+
/// (except inside an `UnsafeCell<T>`).
11871195
///
11881196
/// # Examples
11891197
///

0 commit comments

Comments
 (0)