@@ -4,11 +4,15 @@ use crate::{fmt, intrinsics, ptr, slice};
4
4
5
5
/// A wrapper type to construct uninitialized instances of `T`.
6
6
///
7
+ /// A `MaybeUninit<T>` is like a `T`, but without the requirement that it is properly initialized as a `T`.
8
+ /// Dropping a `MaybeUninit<T>` does nothing, even if properly initialized as a `T`, because
9
+ /// the compiler relies on the type system to decide how to drop variables. Thus, if a `MaybeUninit<T>`
10
+ /// should be dropped like a `T`, it should be converted to a `T` with `assume_init` or similar.
11
+ ///
7
12
/// # Initialization invariant
8
13
///
9
- /// The compiler, in general, assumes that a variable is properly initialized
10
- /// according to the requirements of the variable's type. For example, a variable of
11
- /// reference type must be aligned and non-null. This is an invariant that must
14
+ /// Every variable must be properly initialized according to the requirements of its type.
15
+ /// For example, a variable of reference type must be aligned and non-null. This is an invariant that must
12
16
/// *always* be upheld, even in unsafe code. As a consequence, zero-initializing a
13
17
/// variable of reference type causes instantaneous [undefined behavior][ub],
14
18
/// no matter whether that reference ever gets used to access memory:
@@ -25,7 +29,7 @@ use crate::{fmt, intrinsics, ptr, slice};
25
29
/// This is exploited by the compiler for various optimizations, such as eliding
26
30
/// run-time checks and optimizing `enum` layout.
27
31
///
28
- /// Similarly, entirely uninitialized memory may have any content , while a `bool` must
32
+ /// Similarly, entirely uninitialized memory may have any value , while a `bool` must
29
33
/// always be `true` or `false`. Hence, creating an uninitialized `bool` is undefined behavior:
30
34
///
31
35
/// ```rust,no_run
@@ -37,11 +41,11 @@ use crate::{fmt, intrinsics, ptr, slice};
37
41
/// let b: bool = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! ⚠️
38
42
/// ```
39
43
///
40
- /// Moreover, uninitialized memory is special in that it does not have a fixed value ("fixed"
41
- /// meaning "it won't change without being written to") . Reading the same uninitialized byte
42
- /// multiple times can give different results. This makes it undefined behavior to have
43
- /// uninitialized data in a variable even if that variable has an integer type, which otherwise can
44
- /// hold any *fixed* bit pattern:
44
+ /// Moreover, uninitialized memory is special in that it does not have a fixed
45
+ /// (unchanged unless written to) value . Reading the same uninitialized byte
46
+ /// multiple times can give different results. This even makes it undefined
47
+ /// behavior to have uninitialized data in a variable of integer type,
48
+ /// which otherwise could hold any *fixed* bit pattern:
45
49
///
46
50
/// ```rust,no_run
47
51
/// # #![allow(invalid_value)]
@@ -308,7 +312,7 @@ impl<T> MaybeUninit<T> {
308
312
MaybeUninit { value : ManuallyDrop :: new ( val) }
309
313
}
310
314
311
- /// Creates a new `MaybeUninit<T>` in an uninitialized state .
315
+ /// Creates a new uninitialized `MaybeUninit<T>`.
312
316
///
313
317
/// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
314
318
/// It is your responsibility to make sure `T` gets dropped if it got initialized.
@@ -331,7 +335,7 @@ impl<T> MaybeUninit<T> {
331
335
MaybeUninit { uninit : ( ) }
332
336
}
333
337
334
- /// Creates a new array of `MaybeUninit<T>` items, in an uninitialized state .
338
+ /// Creates a new array of uninitialized `MaybeUninit<T>` elements .
335
339
///
336
340
/// Note: in a future Rust version this method may become unnecessary
337
341
/// when Rust allows
@@ -367,8 +371,7 @@ impl<T> MaybeUninit<T> {
367
371
[ const { MaybeUninit :: uninit ( ) } ; N ]
368
372
}
369
373
370
- /// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
371
- /// filled with `0` bytes. It depends on `T` whether that already makes for
374
+ /// Creates a new zero-filled `MaybeUninit<T>`. It depends on `T` whether that already makes for
372
375
/// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized,
373
376
/// but `MaybeUninit<&'static i32>::zeroed()` is not because references must not
374
377
/// be null.
@@ -425,16 +428,13 @@ impl<T> MaybeUninit<T> {
425
428
/// This overwrites any previous value without dropping it, so be careful
426
429
/// not to use this twice unless you want to skip running the destructor.
427
430
/// For your convenience, this also returns a mutable reference to the
428
- /// (now safely initialized) contents of `self`.
431
+ /// (now safely initialized) value of `self`.
429
432
///
430
- /// As the content is stored inside a `MaybeUninit`, the destructor is not
431
- /// run for the inner data if the MaybeUninit leaves scope without a call to
432
- /// [`assume_init`], [`assume_init_drop`], or similar. Code that receives
433
- /// the mutable reference returned by this function needs to keep this in
434
- /// mind. The safety model of Rust regards leaks as safe, but they are
435
- /// usually still undesirable. This being said, the mutable reference
436
- /// behaves like any other mutable reference would, so assigning a new value
437
- /// to it will drop the old content.
433
+ /// Keep in mind, that the value, as it is wrapped in a `MaybeUninit`,
434
+ /// will not be dropped when its wrapper is. You can make sure the value is dropped by unwrapping
435
+ /// it with a call to [`assume_init`], or by dropping it directly with [`assume_init_drop`].
436
+ /// While the value is also dropped when the returned mutable reference is assigned a new value,
437
+ /// the new value is then subject to the same rules, as now the new value is wrapped in a `MaybeUninit`.
438
438
///
439
439
/// [`assume_init`]: Self::assume_init
440
440
/// [`assume_init_drop`]: Self::assume_init_drop
@@ -470,7 +470,7 @@ impl<T> MaybeUninit<T> {
470
470
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
471
471
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
472
472
/// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
473
- /// // This leaks the contained string:
473
+ /// // This leaks the initialized string:
474
474
/// x.write("hello".to_string());
475
475
/// // x is initialized now:
476
476
/// let s = unsafe { x.assume_init() };
@@ -513,7 +513,7 @@ impl<T> MaybeUninit<T> {
513
513
unsafe { self . assume_init_mut ( ) }
514
514
}
515
515
516
- /// Gets a pointer to the contained value. Reading from this pointer or turning it
516
+ /// Gets a pointer to the `T` value of the `MaybeUninit<T>` . Reading from this pointer or turning it
517
517
/// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
518
518
/// Writing to memory that this pointer (non-transitively) points to is undefined behavior
519
519
/// (except inside an `UnsafeCell<T>`).
@@ -545,7 +545,7 @@ impl<T> MaybeUninit<T> {
545
545
/// ```
546
546
///
547
547
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
548
- /// until they are, it is advisable to avoid them .)
548
+ /// until they are, it is advisable to avoid references to uninitialized data .)
549
549
#[ stable( feature = "maybe_uninit" , since = "1.36.0" ) ]
550
550
#[ rustc_const_stable( feature = "const_maybe_uninit_as_ptr" , since = "1.59.0" ) ]
551
551
#[ rustc_as_ptr]
@@ -555,7 +555,7 @@ impl<T> MaybeUninit<T> {
555
555
self as * const _ as * const T
556
556
}
557
557
558
- /// Gets a mutable pointer to the contained value. Reading from this pointer or turning it
558
+ /// Gets a mutable pointer to the `T` value of the `MaybeUninit<T>` . Reading from this pointer or turning it
559
559
/// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
560
560
///
561
561
/// # Examples
@@ -597,16 +597,17 @@ impl<T> MaybeUninit<T> {
597
597
self as * mut _ as * mut T
598
598
}
599
599
600
- /// Extracts the value from the `MaybeUninit<T>` container . This is a great way
600
+ /// Converts an initialized `MaybeUninit<T>` into a `T` . This is a great way
601
601
/// to ensure that the data will get dropped, because the resulting `T` is
602
602
/// subject to the usual drop handling.
603
603
///
604
604
/// # Safety
605
605
///
606
- /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
607
- /// state. Calling this when the content is not yet fully initialized causes immediate undefined
608
- /// behavior. The [type-level documentation][inv] contains more information about
609
- /// this initialization invariant.
606
+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
607
+ /// before converting it into a `T`. Calling this when the `T` value of the `MaybeUninit<T>`
608
+ /// is not yet fully initialized causes immediate undefined behavior.
609
+ ///
610
+ /// The [type-level documentation][inv] contains more information about this initialization invariant.
610
611
///
611
612
/// [inv]: #initialization-invariant
612
613
///
@@ -656,21 +657,23 @@ impl<T> MaybeUninit<T> {
656
657
}
657
658
}
658
659
659
- /// Reads the value from the `MaybeUninit<T>` container . The resulting `T` is subject
660
- /// to the usual drop handling.
660
+ /// Reads the `T` value of the `MaybeUninit<T>`. The result is an ordinary `T` which,
661
+ /// just like all `T` values, is subject to the usual drop handling.
661
662
///
662
663
/// Whenever possible, it is preferable to use [`assume_init`] instead, which
663
- /// prevents duplicating the content of the `MaybeUninit<T>`.
664
+ /// prevents duplicating the value of the `MaybeUninit<T>`.
664
665
///
665
666
/// # Safety
666
667
///
667
- /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
668
- /// state. Calling this when the content is not yet fully initialized causes undefined
669
- /// behavior. The [type-level documentation][inv] contains more information about
668
+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
669
+ /// before reading the `T` value of the `MaybeUninit<T>`. Calling this when the `T` value
670
+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior.
671
+ ///
672
+ /// The [type-level documentation][inv] contains more information about
670
673
/// this initialization invariant.
671
674
///
672
675
/// Moreover, similar to the [`ptr::read`] function, this function creates a
673
- /// bitwise copy of the contents , regardless whether the contained type
676
+ /// bitwise copy of the value , regardless of whether its type
674
677
/// implements the [`Copy`] trait or not. When using multiple copies of the
675
678
/// data (by calling `assume_init_read` multiple times, or first calling
676
679
/// `assume_init_read` and then [`assume_init`]), it is your responsibility
@@ -726,16 +729,16 @@ impl<T> MaybeUninit<T> {
726
729
}
727
730
}
728
731
729
- /// Drops the contained value in place.
732
+ /// Drops the `T` value of the `MaybeUninit<T>` in place.
730
733
///
731
734
/// If you have ownership of the `MaybeUninit`, you can also use
732
735
/// [`assume_init`] as an alternative.
733
736
///
734
737
/// # Safety
735
738
///
736
- /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is
737
- /// in an initialized state . Calling this when the content is not yet fully
738
- /// initialized causes undefined behavior.
739
+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
740
+ /// before dropping the `T` value of the `MaybeUninit<T>` . Calling this when the `T` value
741
+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior.
739
742
///
740
743
/// On top of that, all additional invariants of the type `T` must be
741
744
/// satisfied, as the `Drop` implementation of `T` (or its members) may
@@ -755,17 +758,17 @@ impl<T> MaybeUninit<T> {
755
758
unsafe { ptr:: drop_in_place ( self . as_mut_ptr ( ) ) }
756
759
}
757
760
758
- /// Gets a shared reference to the contained value.
761
+ /// Gets a shared reference to the `T` value of the `MaybeUninit<T>` .
759
762
///
760
763
/// This can be useful when we want to access a `MaybeUninit` that has been
761
764
/// initialized but don't have ownership of the `MaybeUninit` (preventing the use
762
765
/// of `.assume_init()`).
763
766
///
764
767
/// # Safety
765
768
///
766
- /// Calling this when the content is not yet fully initialized causes undefined
767
- /// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
768
- /// is in an initialized state .
769
+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
770
+ /// before getting a reference to the `T` value of the `MaybeUninit<T>`. Calling this when the `T` value
771
+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior .
769
772
///
770
773
/// # Examples
771
774
///
@@ -823,18 +826,17 @@ impl<T> MaybeUninit<T> {
823
826
}
824
827
}
825
828
826
- /// Gets a mutable (unique) reference to the contained value.
829
+ /// Gets a mutable (unique) reference to the `T` value of the `MaybeUninit<T>` .
827
830
///
828
831
/// This can be useful when we want to access a `MaybeUninit` that has been
829
832
/// initialized but don't have ownership of the `MaybeUninit` (preventing the use
830
833
/// of `.assume_init()`).
831
834
///
832
835
/// # Safety
833
836
///
834
- /// Calling this when the content is not yet fully initialized causes undefined
835
- /// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
836
- /// is in an initialized state. For instance, `.assume_init_mut()` cannot be used to
837
- /// initialize a `MaybeUninit`.
837
+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
838
+ /// before getting a mutable reference to the `T` value of the `MaybeUninit<T>`. Calling this when the `T` value
839
+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior.
838
840
///
839
841
/// # Examples
840
842
///
@@ -940,12 +942,12 @@ impl<T> MaybeUninit<T> {
940
942
}
941
943
}
942
944
943
- /// Extracts the values from an array of `MaybeUninit` containers .
945
+ /// Extracts the values from an array of `MaybeUninit` wrappers .
944
946
///
945
947
/// # Safety
946
948
///
947
949
/// It is up to the caller to guarantee that all elements of the array are
948
- /// in an initialized state .
950
+ /// properly initialized.
949
951
///
950
952
/// # Examples
951
953
///
@@ -980,10 +982,9 @@ impl<T> MaybeUninit<T> {
980
982
}
981
983
}
982
984
983
- /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes .
985
+ /// Returns a slice of potentially uninitialized bytes to the value of this `MaybeUninit` .
984
986
///
985
- /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
986
- /// contain padding bytes which are left uninitialized.
987
+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
987
988
///
988
989
/// # Examples
989
990
///
@@ -1005,11 +1006,9 @@ impl<T> MaybeUninit<T> {
1005
1006
}
1006
1007
}
1007
1008
1008
- /// Returns the contents of this `MaybeUninit` as a mutable slice of potentially uninitialized
1009
- /// bytes.
1009
+ /// Returns a mutable slice of potentially uninitialized bytes to the value of this `MaybeUninit`.
1010
1010
///
1011
- /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
1012
- /// contain padding bytes which are left uninitialized.
1011
+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
1013
1012
///
1014
1013
/// # Examples
1015
1014
///
@@ -1103,8 +1102,9 @@ impl<T> MaybeUninit<T> {
1103
1102
this. write_clone_of_slice ( src)
1104
1103
}
1105
1104
1106
- /// Fills a slice with elements by cloning `value`, returning a mutable reference to the now
1107
- /// initialized contents of the slice.
1105
+ /// Fills a `&mut [MaybeUninit<T>]` with clones of the given value of type `T`.
1106
+ /// Returns a `&mut [T]` to the so initialized slice.
1107
+ ///
1108
1108
/// Any previously initialized elements will not be dropped.
1109
1109
///
1110
1110
/// This is similar to [`slice::fill`].
@@ -1282,8 +1282,8 @@ impl<T> MaybeUninit<T> {
1282
1282
}
1283
1283
1284
1284
impl < T > [ MaybeUninit < T > ] {
1285
- /// Copies the elements from `src ` to `self`,
1286
- /// returning a mutable reference to the now initialized contents of `self` .
1285
+ /// Copies all elements from a `&[T] ` to this `[MaybeUninit<T>]`.
1286
+ /// Returns a `&mut [T]` to the so initialized array .
1287
1287
///
1288
1288
/// If `T` does not implement `Copy`, use [`write_clone_of_slice`] instead.
1289
1289
///
@@ -1340,13 +1340,14 @@ impl<T> [MaybeUninit<T>] {
1340
1340
unsafe { self . assume_init_mut ( ) }
1341
1341
}
1342
1342
1343
- /// Clones the elements from `src ` to `self`,
1344
- /// returning a mutable reference to the now initialized contents of `self` .
1343
+ /// Clones all elements from a `&[T] ` to this `[MaybeUninit<T>]`.
1344
+ /// Returns a `&mut [T]` to the so initialized array .
1345
1345
/// Any already initialized elements will not be dropped.
1346
1346
///
1347
1347
/// If `T` implements `Copy`, use [`write_copy_of_slice`] instead.
1348
1348
///
1349
- /// This is similar to [`slice::clone_from_slice`] but does not drop existing elements.
1349
+ /// This is similar to [`slice::clone_from_slice`] but cannot drop existing `MaybeUninit<T>`,
1350
+ /// as it cannot know if any of them was initialized.
1350
1351
///
1351
1352
/// # Panics
1352
1353
///
@@ -1419,10 +1420,9 @@ impl<T> [MaybeUninit<T>] {
1419
1420
unsafe { self . assume_init_mut ( ) }
1420
1421
}
1421
1422
1422
- /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes .
1423
+ /// Returns a slice of potentially uninitialized bytes to the value of this `[MaybeUninit<T>]` .
1423
1424
///
1424
- /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
1425
- /// contain padding bytes which are left uninitialized.
1425
+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
1426
1426
///
1427
1427
/// # Examples
1428
1428
///
@@ -1445,11 +1445,9 @@ impl<T> [MaybeUninit<T>] {
1445
1445
}
1446
1446
}
1447
1447
1448
- /// Returns the contents of this `MaybeUninit` slice as a mutable slice of potentially
1449
- /// uninitialized bytes.
1448
+ /// Returns a mutable slice of potentially uninitialized bytes to the value of this `[MaybeUninit<T>]`.
1450
1449
///
1451
- /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
1452
- /// contain padding bytes which are left uninitialized.
1450
+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
1453
1451
///
1454
1452
/// # Examples
1455
1453
///
@@ -1478,13 +1476,13 @@ impl<T> [MaybeUninit<T>] {
1478
1476
}
1479
1477
}
1480
1478
1481
- /// Drops the contained values in place.
1479
+ /// Assumes all elements have been fully initialized and drops them in place.
1482
1480
///
1483
1481
/// # Safety
1484
1482
///
1485
- /// It is up to the caller to guarantee that every `MaybeUninit<T>` in the slice
1486
- /// really is in an initialized state . Calling this when the content is not yet
1487
- /// fully initialized causes undefined behavior.
1483
+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
1484
+ /// before calling . Calling this when any of the `T` elements of the `[MaybeUninit<T>]`
1485
+ /// has not yet been fully initialized causes immediate undefined behavior.
1488
1486
///
1489
1487
/// On top of that, all additional invariants of the type `T` must be
1490
1488
/// satisfied, as the `Drop` implementation of `T` (or its members) may
@@ -1505,13 +1503,13 @@ impl<T> [MaybeUninit<T>] {
1505
1503
}
1506
1504
}
1507
1505
1508
- /// Gets a shared reference to the contained value .
1506
+ /// Gets a `&[T]` to the values in the `&[MaybeUninit<T>]` .
1509
1507
///
1510
1508
/// # Safety
1511
1509
///
1512
- /// Calling this when the content is not yet fully initialized causes undefined
1510
+ /// Calling this when the elements have not been fully initialized causes undefined
1513
1511
/// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in
1514
- /// the slice really is in an initialized state .
1512
+ /// the slice really is properly initialized.
1515
1513
#[ unstable( feature = "maybe_uninit_slice" , issue = "63569" ) ]
1516
1514
#[ inline( always) ]
1517
1515
pub const unsafe fn assume_init_ref ( & self ) -> & [ T ] {
@@ -1522,13 +1520,13 @@ impl<T> [MaybeUninit<T>] {
1522
1520
unsafe { & * ( self as * const Self as * const [ T ] ) }
1523
1521
}
1524
1522
1525
- /// Gets a mutable (unique) reference to the contained value .
1523
+ /// Gets a `&mut [T]` to the values in the `&mut [MaybeUninit<T>]` .
1526
1524
///
1527
1525
/// # Safety
1528
1526
///
1529
- /// Calling this when the content is not yet fully initialized causes undefined
1527
+ /// Calling this when the elements have not been fully initialized causes undefined
1530
1528
/// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in the
1531
- /// slice really is in an initialized state . For instance, `.assume_init_mut()` cannot
1529
+ /// slice really is properly initialized. For instance, `.assume_init_mut()` cannot
1532
1530
/// be used to initialize a `MaybeUninit` slice.
1533
1531
#[ unstable( feature = "maybe_uninit_slice" , issue = "63569" ) ]
1534
1532
#[ inline( always) ]
0 commit comments