@@ -402,10 +402,60 @@ impl<T> MaybeUninit<T> {
402
402
u
403
403
}
404
404
405
- /// Sets the value of the `MaybeUninit<T>`. This overwrites any previous value
406
- /// without dropping it, so be careful not to use this twice unless you want to
407
- /// skip running the destructor. For your convenience, this also returns a mutable
408
- /// reference to the (now safely initialized) contents of `self`.
405
+ /// Sets the value of the `MaybeUninit<T>`.
406
+ ///
407
+ /// This overwrites any previous value without dropping it, so be careful
408
+ /// not to use this twice unless you want to skip running the destructor.
409
+ /// For your convenience, this also returns a mutable reference to the
410
+ /// (now safely initialized) contents of `self`.
411
+ ///
412
+ /// As the content is stored inside a `MaybeUninit`, the destructor is not
413
+ /// ran for the inner data if the MaybeUninit leaves scope without a call to
414
+ /// [`assume_init`], [`assume_init_drop`], or similar. Code that receives
415
+ /// the mutable reference returned by this function needs to keep this in
416
+ /// mind. The safety model of Rust regards leaks as safe, but they are
417
+ /// usually still undesirable. This being said, the mutable reference
418
+ /// behaves like any other mutable reference would, so assigning a new value
419
+ /// to it will drop the old content.
420
+ ///
421
+ /// [`assume_init`]: Self::assume_init
422
+ /// [`assume_init_drop`]: Self::assume_init_drop
423
+ ///
424
+ /// # Examples
425
+ ///
426
+ /// Correct usage of this method:
427
+ ///
428
+ /// ```rust
429
+ /// #![feature(maybe_uninit_extra)]
430
+ /// use std::mem::MaybeUninit;
431
+ ///
432
+ /// let mut x = MaybeUninit::<Vec<u8>>::uninit();
433
+ ///
434
+ /// {
435
+ /// let hello = x.write((&b"Hello, world!").to_vec());
436
+ /// // Setting hello does not leak prior allocations, but drops them
437
+ /// *hello = (&b"Hello").to_vec();
438
+ /// hello[0] = 'h' as u8;
439
+ /// }
440
+ /// // x is initialized now:
441
+ /// let s = unsafe { x.assume_init() };
442
+ /// assert_eq!(b"hello", s.as_slice());
443
+ /// ```
444
+ ///
445
+ /// This usage of the method causes a leak:
446
+ ///
447
+ /// ```rust
448
+ /// #![feature(maybe_uninit_extra)]
449
+ /// use std::mem::MaybeUninit;
450
+ ///
451
+ /// let mut x = MaybeUninit::<String>::uninit();
452
+ ///
453
+ /// x.write("Hello".to_string());
454
+ /// // This leaks the contained string:
455
+ /// x.write("hello".to_string());
456
+ /// // x is initialized now:
457
+ /// let s = unsafe { x.assume_init() };
458
+ /// ```
409
459
#[ unstable( feature = "maybe_uninit_extra" , issue = "63567" ) ]
410
460
#[ rustc_const_unstable( feature = "maybe_uninit_extra" , issue = "63567" ) ]
411
461
#[ inline( always) ]
@@ -564,9 +614,11 @@ impl<T> MaybeUninit<T> {
564
614
/// behavior. The [type-level documentation][inv] contains more information about
565
615
/// this initialization invariant.
566
616
///
567
- /// Moreover, this leaves a copy of the same data behind in the `MaybeUninit<T>`. When using
568
- /// multiple copies of the data (by calling `assume_init_read` multiple times, or first
569
- /// calling `assume_init_read` and then [`assume_init`]), it is your responsibility
617
+ /// Moreover, similar to the [`ptr::read`] function, this function creates a
618
+ /// bitwise copy of the contents, regardless whether the contained type
619
+ /// implements the [`Copy`] trait or not. When using multiple copies of the
620
+ /// data (by calling `assume_init_read` multiple times, or first calling
621
+ /// `assume_init_read` and then [`assume_init`]), it is your responsibility
570
622
/// to ensure that that data may indeed be duplicated.
571
623
///
572
624
/// [inv]: #initialization-invariant
@@ -622,7 +674,8 @@ impl<T> MaybeUninit<T> {
622
674
623
675
/// Drops the contained value in place.
624
676
///
625
- /// If you have ownership of the `MaybeUninit`, you can use [`assume_init`] instead.
677
+ /// If you have ownership of the `MaybeUninit`, you can also use
678
+ /// [`assume_init`] as an alternative.
626
679
///
627
680
/// # Safety
628
681
///
@@ -632,11 +685,12 @@ impl<T> MaybeUninit<T> {
632
685
///
633
686
/// On top of that, all additional invariants of the type `T` must be
634
687
/// satisfied, as the `Drop` implementation of `T` (or its members) may
635
- /// rely on this. For example, a `1`-initialized [`Vec<T>`] is considered
636
- /// initialized (under the current implementation; this does not constitute
637
- /// a stable guarantee) because the only requirement the compiler knows
638
- /// about it is that the data pointer must be non-null. Dropping such a
639
- /// `Vec<T>` however will cause undefined behaviour.
688
+ /// rely on this. For example, setting a [`Vec<T>`] to an invalid but
689
+ /// non-null address makes it initialized (under the current implementation;
690
+ /// this does not constitute a stable guarantee), because the only
691
+ /// requirement the compiler knows about it is that the data pointer must be
692
+ /// non-null. Dropping such a `Vec<T>` however will cause undefined
693
+ /// behaviour.
640
694
///
641
695
/// [`assume_init`]: MaybeUninit::assume_init
642
696
/// [`Vec<T>`]: ../../std/vec/struct.Vec.html
0 commit comments