@@ -402,10 +402,60 @@ impl<T> MaybeUninit<T> {
402402        u
403403    } 
404404
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+      /// ``` 
409459     #[ unstable( feature = "maybe_uninit_extra" ,  issue = "63567" ) ]  
410460    #[ rustc_const_unstable( feature = "maybe_uninit_extra" ,  issue = "63567" ) ]  
411461    #[ inline( always) ]  
@@ -564,9 +614,11 @@ impl<T> MaybeUninit<T> {
564614     /// behavior. The [type-level documentation][inv] contains more information about 
565615     /// this initialization invariant. 
566616     /// 
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 
570622     /// to ensure that that data may indeed be duplicated. 
571623     /// 
572624     /// [inv]: #initialization-invariant 
@@ -622,7 +674,8 @@ impl<T> MaybeUninit<T> {
622674
623675    /// Drops the contained value in place. 
624676     /// 
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. 
626679     /// 
627680     /// # Safety 
628681     /// 
@@ -632,11 +685,12 @@ impl<T> MaybeUninit<T> {
632685     /// 
633686     /// On top of that, all additional invariants of the type `T` must be 
634687     /// 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. 
640694     /// 
641695     /// [`assume_init`]: MaybeUninit::assume_init 
642696     /// [`Vec<T>`]: ../../std/vec/struct.Vec.html 
0 commit comments