From ee69c3a17074dc0086229cc47fc34b8389b1b6f4 Mon Sep 17 00:00:00 2001 From: Pyrode Date: Sun, 2 Feb 2025 17:44:39 +0530 Subject: [PATCH] OnceCell & OnceLock docs: Using (un)initialized consistently --- library/core/src/cell/once.rs | 68 +++++++++++++------------ library/std/src/sync/once_lock.rs | 84 +++++++++++++++++-------------- 2 files changed, 84 insertions(+), 68 deletions(-) diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index 6a85791916a61..e5257c11017f8 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -10,6 +10,12 @@ use crate::{fmt, mem}; /// /// For a thread-safe version of this struct, see [`std::sync::OnceLock`]. /// +/// A OnceCell conceptually has two states, called the `uninitialized state` +/// and the `initialized state`. +/// +/// Like an `enum { Uninitialized, Initialized(T) }`, +/// except that it has invariants to uphold, so the enum is hidden. +/// /// [`RefCell`]: crate::cell::RefCell /// [`Cell`]: crate::cell::Cell /// [`std::sync::OnceLock`]: ../../std/sync/struct.OnceLock.html @@ -35,7 +41,7 @@ pub struct OnceCell { } impl OnceCell { - /// Creates a new empty cell. + /// Creates a new cell in the uninitialized state. #[inline] #[must_use] #[stable(feature = "once_cell", since = "1.70.0")] @@ -46,7 +52,7 @@ impl OnceCell { /// Gets the reference to the underlying value. /// - /// Returns `None` if the cell is empty. + /// Returns `None` if the cell is in the uninitialized state. #[inline] #[stable(feature = "once_cell", since = "1.70.0")] pub fn get(&self) -> Option<&T> { @@ -56,19 +62,19 @@ impl OnceCell { /// Gets the mutable reference to the underlying value. /// - /// Returns `None` if the cell is empty. + /// Returns `None` if the cell is in the uninitialized state. #[inline] #[stable(feature = "once_cell", since = "1.70.0")] pub fn get_mut(&mut self) -> Option<&mut T> { self.inner.get_mut().as_mut() } - /// Sets the contents of the cell to `value`. + /// Initializes the cell's value to `value`. /// /// # Errors /// - /// This method returns `Ok(())` if the cell was empty and `Err(value)` if - /// it was full. + /// This method returns `Ok(())` if the cell was in the uninitialized state + /// and `Err(value)` if it was already in the initialized state. /// /// # Examples /// @@ -92,13 +98,13 @@ impl OnceCell { } } - /// Sets the contents of the cell to `value` if the cell was empty, then - /// returns a reference to it. + /// Initializes the cell's value to `value` if the cell was in the + /// uninitialized state, then returns a reference to it. /// /// # Errors /// - /// This method returns `Ok(&value)` if the cell was empty and - /// `Err(¤t_value, value)` if it was full. + /// This method returns `Ok(&value)` if the cell was in the uninitialized state + /// and `Err((¤t_value, value))` if it was already in the initialized state. /// /// # Examples /// @@ -130,13 +136,13 @@ impl OnceCell { Ok(slot.insert(value)) } - /// Gets the contents of the cell, initializing it with `f` - /// if the cell was empty. + /// Gets the cell's value, initializing it to `f()` + /// if the cell was in the uninitialized state. /// /// # Panics /// - /// If `f` panics, the panic is propagated to the caller, and the cell - /// remains uninitialized. + /// If `f()` panics, the panic is propagated to the caller, and the cell + /// remains in the uninitialized state. /// /// It is an error to reentrantly initialize the cell from `f`. Doing /// so results in a panic. @@ -163,13 +169,13 @@ impl OnceCell { } } - /// Gets the mutable reference of the contents of the cell, - /// initializing it with `f` if the cell was empty. + /// Gets the mutable reference of the cell's value, + /// initializing it to `f()` if the cell was in the uninitialized state. /// /// # Panics /// - /// If `f` panics, the panic is propagated to the caller, and the cell - /// remains uninitialized. + /// If `f()` panics, the panic is propagated to the caller, and the cell + /// remains in the uninitialized state. /// /// # Examples /// @@ -199,14 +205,14 @@ impl OnceCell { } } - /// Gets the contents of the cell, initializing it with `f` if - /// the cell was empty. If the cell was empty and `f` failed, an - /// error is returned. + /// Gets the cell's value, initializing it to `f()` if + /// the cell was in the uninitialized state. If the cell was in + /// the uninitialized state and `f()` failed, an error is returned. /// /// # Panics /// - /// If `f` panics, the panic is propagated to the caller, and the cell - /// remains uninitialized. + /// If `f()` panics, the panic is propagated to the caller, and the cell + /// remains in the uninitialized state. /// /// It is an error to reentrantly initialize the cell from `f`. Doing /// so results in a panic. @@ -238,14 +244,14 @@ impl OnceCell { self.try_init(f) } - /// Gets the mutable reference of the contents of the cell, initializing - /// it with `f` if the cell was empty. If the cell was empty and `f` failed, - /// an error is returned. + /// Gets the mutable reference of the cell's value, initializing + /// it to `f()` if the cell was in the uninitialized state. If the cell + /// was in the uninitialized state and `f()` failed, an error is returned. /// /// # Panics /// - /// If `f` panics, the panic is propagated to the caller, and the cell - /// remains uninitialized. + /// If `f()` panics, the panic is propagated to the caller, and the cell + /// remains in the uninitialized state. /// /// # Examples /// @@ -256,7 +262,7 @@ impl OnceCell { /// /// let mut cell: OnceCell = OnceCell::new(); /// - /// // Failed initializers do not change the value + /// // Failed attempts to initialize cell's value has no effect on the cell /// assert!(cell.get_mut_or_try_init(|| "not a number!".parse()).is_err()); /// assert!(cell.get().is_none()); /// @@ -295,7 +301,7 @@ impl OnceCell { /// Consumes the cell, returning the wrapped value. /// - /// Returns `None` if the cell was empty. + /// Returns `None` if the cell was in the uninitialized state. /// /// # Examples /// @@ -321,7 +327,7 @@ impl OnceCell { /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state. /// - /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized. + /// Has no effect and returns `None` if the `OnceCell` is in the uninitialized state. /// /// Safety is guaranteed by requiring a mutable reference. /// diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index 49f2dafd8fd9c..aefb6035fc475 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -13,6 +13,12 @@ use crate::sync::Once; /// Where OnceLock shines is when LazyLock is too simple to support a given case, as LazyLock /// doesn't allow additional inputs to its function after you call [`LazyLock::new(|| ...)`]. /// +/// A OnceCell conceptually has two states, called the `uninitialized state` +/// and the `initialized state`. +/// +/// Like an `enum { Uninitialized, Initialized(T) }`, +/// except that it has invariants to uphold, so the enum is hidden. +/// /// [`OnceCell`]: crate::cell::OnceCell /// [`LazyLock`]: crate::sync::LazyLock /// [`LazyLock::new(|| ...)`]: crate::sync::LazyLock::new @@ -126,7 +132,7 @@ pub struct OnceLock { } impl OnceLock { - /// Creates a new empty cell. + /// Creates a new cell in the uninitialized state. #[inline] #[must_use] #[stable(feature = "once_cell", since = "1.70.0")] @@ -141,8 +147,8 @@ impl OnceLock { /// Gets the reference to the underlying value. /// - /// Returns `None` if the cell is empty, or being initialized. This - /// method never blocks. + /// Returns `None` if the cell is in the uninitialized state, + /// or being initialized. This method never blocks. #[inline] #[stable(feature = "once_cell", since = "1.70.0")] pub fn get(&self) -> Option<&T> { @@ -156,7 +162,8 @@ impl OnceLock { /// Gets the mutable reference to the underlying value. /// - /// Returns `None` if the cell is empty. This method never blocks. + /// Returns `None` if the cell is in the uninitialized state, + /// or being initialized. This method never blocks. #[inline] #[stable(feature = "once_cell", since = "1.70.0")] pub fn get_mut(&mut self) -> Option<&mut T> { @@ -168,7 +175,7 @@ impl OnceLock { } } - /// Blocks the current thread until the cell is initialized. + /// Blocks the current thread until the cell is not in the initialized state. /// /// # Example /// @@ -196,12 +203,14 @@ impl OnceLock { unsafe { self.get_unchecked() } } - /// Sets the contents of this cell to `value`. + /// Initializes the cell's value to `value`. /// - /// May block if another thread is currently attempting to initialize the cell. The cell is - /// guaranteed to contain a value when set returns, though not necessarily the one provided. + /// May block if another thread is currently attempting to initialize the value of a cell. + /// The cell is guaranteed to contain a value when `set` returns, though not necessarily + /// the one provided. /// - /// Returns `Ok(())` if the cell's value was set by this call. + /// Returns `Ok(())` if the cell's value was initialized by this call + /// and Err(value) if the cell's value was already initialized. /// /// # Examples /// @@ -230,13 +239,15 @@ impl OnceLock { } } - /// Sets the contents of this cell to `value` if the cell was empty, then - /// returns a reference to it. + /// Initializes the cell's value to `value` if the cell was in the uninitialized state, + /// then returns a reference to it. /// - /// May block if another thread is currently attempting to initialize the cell. The cell is - /// guaranteed to contain a value when set returns, though not necessarily the one provided. + /// May block if another thread is currently attempting to initialize the value of a cell. + /// The cell is guaranteed to contain a value when `try_insert` returns, though not necessarily + /// the one provided. /// - /// Returns `Ok(&value)` if the cell was empty and `Err(¤t_value, value)` if it was full. + /// Returns `Ok(&value)` if the cell was in the uninitialized state and + /// `Err((¤t_value, value))` if it was in the initialized state. /// /// # Examples /// @@ -269,8 +280,8 @@ impl OnceLock { } } - /// Gets the contents of the cell, initializing it with `f` if the cell - /// was empty. + /// Gets the cell's value, initializing it to `f()` if the cell + /// was in the uninitialized state. /// /// Many threads may call `get_or_init` concurrently with different /// initializing functions, but it is guaranteed that only one function @@ -278,7 +289,7 @@ impl OnceLock { /// /// # Panics /// - /// If `f` panics, the panic is propagated to the caller, and the cell + /// If `f()` panics, the panic is propagated to the caller, and the cell's value /// remains uninitialized. /// /// It is an error to reentrantly initialize the cell from `f`. The @@ -307,15 +318,15 @@ impl OnceLock { } } - /// Gets the mutable reference of the contents of the cell, initializing - /// it with `f` if the cell was empty. + /// Gets the mutable reference of the cell's value, initializing + /// it to `f()` if the cell was in the uninitialized state. /// /// This method never blocks. /// /// # Panics /// - /// If `f` panics, the panic is propagated to the caller, and the cell - /// remains uninitialized. + /// If `f()` panics, the panic is propagated to the caller, and the cell + /// remains in the uninitialized state. /// /// # Examples /// @@ -345,13 +356,12 @@ impl OnceLock { } } - /// Gets the contents of the cell, initializing it with `f` if - /// the cell was empty. If the cell was empty and `f` failed, an - /// error is returned. + /// Gets the cell's value, initializing it to `f()` if the cell was in the uninitialized state. + /// If the cell was in the uninitialized state and `f()` failed, an error is returned. /// /// # Panics /// - /// If `f` panics, the panic is propagated to the caller, and + /// If `f()` panics, the panic is propagated to the caller, and /// the cell remains uninitialized. /// /// It is an error to reentrantly initialize the cell from `f`. @@ -396,15 +406,15 @@ impl OnceLock { Ok(unsafe { self.get_unchecked() }) } - /// Gets the mutable reference of the contents of the cell, initializing - /// it with `f` if the cell was empty. If the cell was empty and `f` failed, - /// an error is returned. + /// Gets the mutable reference of the cell's value , initializing + /// it to `f()` if the cell was in the uninitialized state. If the cell + /// was in the uninitialized state and `f()` failed, an error is returned. /// /// This method never blocks. /// /// # Panics /// - /// If `f` panics, the panic is propagated to the caller, and + /// If `f()` panics, the panic is propagated to the caller, and /// the cell remains uninitialized. /// /// # Examples @@ -416,7 +426,7 @@ impl OnceLock { /// /// let mut cell: OnceLock = OnceLock::new(); /// - /// // Failed initializers do not change the value + /// // Failed attempts to initialize cell's value has no effect on the cell /// assert!(cell.get_mut_or_try_init(|| "not a number!".parse()).is_err()); /// assert!(cell.get().is_none()); /// @@ -440,7 +450,7 @@ impl OnceLock { } /// Consumes the `OnceLock`, returning the wrapped value. Returns - /// `None` if the cell was empty. + /// `None` if the cell was in the uninitialized state. /// /// # Examples /// @@ -460,9 +470,9 @@ impl OnceLock { self.take() } - /// Takes the value out of this `OnceLock`, moving it back to an uninitialized state. + /// Takes the value out of this `OnceLock`, moving it back to the uninitialized state. /// - /// Has no effect and returns `None` if the `OnceLock` hasn't been initialized. + /// Has no effect and returns `None` if the `OnceLock` was in the uninitialized state. /// /// Safety is guaranteed by requiring a mutable reference. /// @@ -528,7 +538,7 @@ impl OnceLock { /// # Safety /// - /// The value must be initialized + /// The cell must be in the initialized state #[inline] unsafe fn get_unchecked(&self) -> &T { debug_assert!(self.is_initialized()); @@ -537,7 +547,7 @@ impl OnceLock { /// # Safety /// - /// The value must be initialized + /// The cell must be in the initialized state #[inline] unsafe fn get_unchecked_mut(&mut self) -> &mut T { debug_assert!(self.is_initialized()); @@ -562,7 +572,7 @@ impl UnwindSafe for OnceLock {} #[stable(feature = "once_cell", since = "1.70.0")] impl Default for OnceLock { - /// Creates a new empty cell. + /// Creates a new cell in the uninitialized state. /// /// # Example /// @@ -608,7 +618,7 @@ impl Clone for OnceLock { #[stable(feature = "once_cell", since = "1.70.0")] impl From for OnceLock { - /// Creates a new cell with its contents set to `value`. + /// Creates a new cell with its value initialized to `value`. /// /// # Example ///