diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 1758e84ad7cdf..a1bd4c8571706 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -15,6 +15,22 @@ enum State { /// /// [`std::sync::LazyLock`]: ../../std/sync/struct.LazyLock.html /// +/// # Poisoning +/// +/// If the initialization closure passed to [`LazyCell::new`] panics, the cell will be poisoned. +/// Once the cell is poisoned, any threads that attempt to access this cell (via a dereference +/// or via an explicit call to [`force()`]) will panic. +/// +/// This concept is similar to that of poisoning in the [`std::sync::poison`] module. A key +/// difference, however, is that poisoning in `LazyCell` is _unrecoverable_. All future accesses of +/// the cell from other threads will panic, whereas a type in [`std::sync::poison`] like +/// [`std::sync::poison::Mutex`] allows recovery via [`PoisonError::into_inner()`]. +/// +/// [`force()`]: LazyCell::force +/// [`std::sync::poison`]: ../../std/sync/poison/index.html +/// [`std::sync::poison::Mutex`]: ../../std/sync/poison/struct.Mutex.html +/// [`PoisonError::into_inner()`]: ../../std/sync/poison/struct.PoisonError.html#method.into_inner +/// /// # Examples /// /// ``` @@ -64,6 +80,10 @@ impl T> LazyCell { /// /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise. /// + /// # Panics + /// + /// Panics if the cell is poisoned. + /// /// # Examples /// /// ``` @@ -93,6 +113,15 @@ impl T> LazyCell { /// /// This is equivalent to the `Deref` impl, but is explicit. /// + /// # Panics + /// + /// If the initialization closure panics (the one that is passed to the [`new()`] method), the + /// panic is propagated to the caller, and the cell becomes poisoned. This will cause all future + /// accesses of the cell (via [`force()`] or a dereference) to panic. + /// + /// [`new()`]: LazyCell::new + /// [`force()`]: LazyCell::force + /// /// # Examples /// /// ``` @@ -123,6 +152,15 @@ impl T> LazyCell { /// Forces the evaluation of this lazy value and returns a mutable reference to /// the result. /// + /// # Panics + /// + /// If the initialization closure panics (the one that is passed to the [`new()`] method), the + /// panic is propagated to the caller, and the cell becomes poisoned. This will cause all future + /// accesses of the cell (via [`force()`] or a dereference) to panic. + /// + /// [`new()`]: LazyCell::new + /// [`force()`]: LazyCell::force + /// /// # Examples /// /// ``` @@ -219,7 +257,8 @@ impl T> LazyCell { } impl LazyCell { - /// Returns a mutable reference to the value if initialized, or `None` if not. + /// Returns a mutable reference to the value if initialized. Otherwise (if uninitialized or + /// poisoned), returns `None`. /// /// # Examples /// @@ -245,7 +284,8 @@ impl LazyCell { } } - /// Returns a reference to the value if initialized, or `None` if not. + /// Returns a reference to the value if initialized. Otherwise (if uninitialized or poisoned), + /// returns `None`. /// /// # Examples /// @@ -278,6 +318,15 @@ impl LazyCell { #[stable(feature = "lazy_cell", since = "1.80.0")] impl T> Deref for LazyCell { type Target = T; + + /// # Panics + /// + /// If the initialization closure panics (the one that is passed to the [`new()`] method), the + /// panic is propagated to the caller, and the cell becomes poisoned. This will cause all future + /// accesses of the cell (via [`force()`] or a dereference) to panic. + /// + /// [`new()`]: LazyCell::new + /// [`force()`]: LazyCell::force #[inline] fn deref(&self) -> &T { LazyCell::force(self) @@ -286,6 +335,14 @@ impl T> Deref for LazyCell { #[stable(feature = "lazy_deref_mut", since = "1.89.0")] impl T> DerefMut for LazyCell { + /// # Panics + /// + /// If the initialization closure panics (the one that is passed to the [`new()`] method), the + /// panic is propagated to the caller, and the cell becomes poisoned. This will cause all future + /// accesses of the cell (via [`force()`] or a dereference) to panic. + /// + /// [`new()`]: LazyCell::new + /// [`force()`]: LazyCell::force #[inline] fn deref_mut(&mut self) -> &mut T { LazyCell::force_mut(self) diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index eba849d16dacd..a40e29a772a9c 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -25,6 +25,22 @@ union Data { /// /// [`LazyCell`]: crate::cell::LazyCell /// +/// # Poisoning +/// +/// If the initialization closure passed to [`LazyLock::new`] panics, the lock will be poisoned. +/// Once the lock is poisoned, any threads that attempt to access this lock (via a dereference +/// or via an explicit call to [`force()`]) will panic. +/// +/// This concept is similar to that of poisoning in the [`std::sync::poison`] module. A key +/// difference, however, is that poisoning in `LazyLock` is _unrecoverable_. All future accesses of +/// the lock from other threads will panic, whereas a type in [`std::sync::poison`] like +/// [`std::sync::poison::Mutex`] allows recovery via [`PoisonError::into_inner()`]. +/// +/// [`force()`]: LazyLock::force +/// [`std::sync::poison`]: crate::sync::poison +/// [`std::sync::poison::Mutex`]: crate::sync::poison::Mutex +/// [`PoisonError::into_inner()`]: crate::sync::poison::PoisonError::into_inner +/// /// # Examples /// /// Initialize static variables with `LazyLock`. @@ -102,6 +118,10 @@ impl T> LazyLock { /// /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise. /// + /// # Panics + /// + /// Panics if the lock is poisoned. + /// /// # Examples /// /// ``` @@ -136,6 +156,15 @@ impl T> LazyLock { /// Forces the evaluation of this lazy value and returns a mutable reference to /// the result. /// + /// # Panics + /// + /// If the initialization closure panics (the one that is passed to the [`new()`] method), the + /// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future + /// accesses of the lock (via [`force()`] or a dereference) to panic. + /// + /// [`new()`]: LazyLock::new + /// [`force()`]: LazyLock::force + /// /// # Examples /// /// ``` @@ -193,6 +222,15 @@ impl T> LazyLock { /// This method will block the calling thread if another initialization /// routine is currently running. /// + /// # Panics + /// + /// If the initialization closure panics (the one that is passed to the [`new()`] method), the + /// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future + /// accesses of the lock (via [`force()`] or a dereference) to panic. + /// + /// [`new()`]: LazyLock::new + /// [`force()`]: LazyLock::force + /// /// # Examples /// /// ``` @@ -227,7 +265,8 @@ impl T> LazyLock { } impl LazyLock { - /// Returns a mutable reference to the value if initialized, or `None` if not. + /// Returns a mutable reference to the value if initialized. Otherwise (if uninitialized or + /// poisoned), returns `None`. /// /// # Examples /// @@ -256,7 +295,8 @@ impl LazyLock { } } - /// Returns a reference to the value if initialized, or `None` if not. + /// Returns a reference to the value if initialized. Otherwise (if uninitialized or poisoned), + /// returns `None`. /// /// # Examples /// @@ -307,6 +347,14 @@ impl T> Deref for LazyLock { /// This method will block the calling thread if another initialization /// routine is currently running. /// + /// # Panics + /// + /// If the initialization closure panics (the one that is passed to the [`new()`] method), the + /// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future + /// accesses of the lock (via [`force()`] or a dereference) to panic. + /// + /// [`new()`]: LazyLock::new + /// [`force()`]: LazyLock::force #[inline] fn deref(&self) -> &T { LazyLock::force(self) @@ -315,6 +363,14 @@ impl T> Deref for LazyLock { #[stable(feature = "lazy_deref_mut", since = "1.89.0")] impl T> DerefMut for LazyLock { + /// # Panics + /// + /// If the initialization closure panics (the one that is passed to the [`new()`] method), the + /// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future + /// accesses of the lock (via [`force()`] or a dereference) to panic. + /// + /// [`new()`]: LazyLock::new + /// [`force()`]: LazyLock::force #[inline] fn deref_mut(&mut self) -> &mut T { LazyLock::force_mut(self) diff --git a/library/std/src/sync/poison.rs b/library/std/src/sync/poison.rs index d5adc9e29b505..31889dcc10fad 100644 --- a/library/std/src/sync/poison.rs +++ b/library/std/src/sync/poison.rs @@ -11,7 +11,7 @@ //! //! The specifics of how this "poisoned" state affects other threads and whether //! the panics are recognized reliably or on a best-effort basis depend on the -//! primitive. See [#Overview] below. +//! primitive. See [Overview](#overview) below. //! //! For the alternative implementations that do not employ poisoning, //! see [`std::sync::nonpoison`].