From a94b2cb034c2521d52e54632b775e181eb7e0bc7 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 9 Sep 2020 18:54:17 +0200 Subject: [PATCH] Add safety docs about T's invariants in MaybeUninit::assume_init_drop. --- library/core/src/mem/maybe_uninit.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 38a006ce74ce..0d1d563b5cee 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -580,17 +580,23 @@ impl MaybeUninit { /// /// # Safety /// - /// Calling this when the content is not yet fully initialized causes undefined - /// behavior: it is up to the caller to guarantee that the `MaybeUninit` really - /// is in an initialized state. + /// It is up to the caller to guarantee that the `MaybeUninit` really is + /// in an initialized state. Calling this when the content is not yet fully + /// initialized causes undefined behavior. /// - /// This function runs the destructor of the contained value in place. - /// Afterwards, the memory is considered uninitialized again, but remains unmodified. + /// On top of that, all additional invariants of the type `T` must be + /// satisfied, as the `Drop` implementation of `T` (or its members) may + /// rely on this. For example, a `1`-initialized [`Vec`] is considered + /// initialized (under the current implementation; this does not constitute + /// a stable guarantee) because the only requirement the compiler knows + /// about it is that the data pointer must be non-null. Dropping such a + /// `Vec` however will cause undefined behaviour. /// /// [`assume_init`]: MaybeUninit::assume_init #[unstable(feature = "maybe_uninit_extra", issue = "63567")] pub unsafe fn assume_init_drop(&mut self) { - // SAFETY: the caller must guarantee that `self` is initialized. + // SAFETY: the caller must guarantee that `self` is initialized and + // satisfies all invariants of `T`. // Dropping the value in place is safe if that is the case. unsafe { ptr::drop_in_place(self.as_mut_ptr()) } }