Skip to content

Commit

Permalink
OnceCell & OnceLock docs: Using (un)initialized consistently
Browse files Browse the repository at this point in the history
  • Loading branch information
Pyr0de committed Feb 3, 2025
1 parent 5e55679 commit f8b01b3
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 54 deletions.
53 changes: 28 additions & 25 deletions library/core/src/cell/once.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ use crate::{fmt, mem};
/// only immutable references can be obtained unless one has a mutable reference to the cell
/// itself. In the same vein, the cell can only be re-initialized with such a mutable reference.
///
/// A `OnceCell` can be thought of as a safe abstraction over uninitialized data that becomes
/// initialized once written.
///
/// For a thread-safe version of this struct, see [`std::sync::OnceLock`].
///
/// [`RefCell`]: crate::cell::RefCell
Expand Down Expand Up @@ -35,7 +38,7 @@ pub struct OnceCell<T> {
}

impl<T> OnceCell<T> {
/// Creates a new empty cell.
/// Creates a new uninitialized cell.
#[inline]
#[must_use]
#[stable(feature = "once_cell", since = "1.70.0")]
Expand All @@ -46,7 +49,7 @@ impl<T> OnceCell<T> {

/// Gets the reference to the underlying value.
///
/// Returns `None` if the cell is empty.
/// Returns `None` if the cell is uninitialized.
#[inline]
#[stable(feature = "once_cell", since = "1.70.0")]
pub fn get(&self) -> Option<&T> {
Expand All @@ -56,19 +59,19 @@ impl<T> OnceCell<T> {

/// Gets the mutable reference to the underlying value.
///
/// Returns `None` if the cell is empty.
/// Returns `None` if the cell is uninitialized.
#[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 contents of the cell 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 uninitialized
/// and `Err(value)` if it was already initialized.
///
/// # Examples
///
Expand All @@ -92,13 +95,13 @@ impl<T> OnceCell<T> {
}
}

/// Sets the contents of the cell to `value` if the cell was empty, then
/// returns a reference to it.
/// Initializes the contents of the cell to `value` if the cell was
/// uninitialized, then returns a reference to it.
///
/// # Errors
///
/// This method returns `Ok(&value)` if the cell was empty and
/// `Err(&current_value, value)` if it was full.
/// This method returns `Ok(&value)` if the cell was uninitialized
/// and `Err((&current_value, value))` if it was already initialized.
///
/// # Examples
///
Expand Down Expand Up @@ -130,12 +133,12 @@ impl<T> OnceCell<T> {
Ok(slot.insert(value))
}

/// Gets the contents of the cell, initializing it with `f`
/// if the cell was empty.
/// Gets the contents of the cell, initializing it to `f()`
/// if the cell was uninitialized.
///
/// # 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
/// remains uninitialized.
///
/// It is an error to reentrantly initialize the cell from `f`. Doing
Expand Down Expand Up @@ -164,11 +167,11 @@ impl<T> OnceCell<T> {
}

/// Gets the mutable reference of the contents of the cell,
/// initializing it with `f` if the cell was empty.
/// initializing it to `f()` if the cell was uninitialized.
///
/// # 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
/// remains uninitialized.
///
/// # Examples
Expand Down Expand Up @@ -199,13 +202,13 @@ impl<T> OnceCell<T> {
}
}

/// 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 contents of the cell, initializing it to `f()` if
/// the cell was uninitialized. If the cell was uninitialized
/// and `f()` failed, an error is returned.
///
/// # 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
/// remains uninitialized.
///
/// It is an error to reentrantly initialize the cell from `f`. Doing
Expand Down Expand Up @@ -239,12 +242,12 @@ impl<T> OnceCell<T> {
}

/// 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.
/// it to `f()` if the cell was uninitialized. If the cell was uninitialized
/// and `f()` failed, an error is returned.
///
/// # 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
/// remains uninitialized.
///
/// # Examples
Expand All @@ -256,7 +259,7 @@ impl<T> OnceCell<T> {
///
/// let mut cell: OnceCell<u32> = OnceCell::new();
///
/// // Failed initializers do not change the value
/// // Failed attempts to initialize the cell do not change its contents
/// assert!(cell.get_mut_or_try_init(|| "not a number!".parse()).is_err());
/// assert!(cell.get().is_none());
///
Expand Down Expand Up @@ -295,7 +298,7 @@ impl<T> OnceCell<T> {

/// Consumes the cell, returning the wrapped value.
///
/// Returns `None` if the cell was empty.
/// Returns `None` if the cell was uninitialized.
///
/// # Examples
///
Expand All @@ -321,7 +324,7 @@ impl<T> OnceCell<T> {

/// 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 uninitialized.
///
/// Safety is guaranteed by requiring a mutable reference.
///
Expand Down
65 changes: 36 additions & 29 deletions library/std/src/sync/once_lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ 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 `OnceLock` can be thought of as a safe abstraction over uninitialized data that becomes
/// initialized once written.
///
/// [`OnceCell`]: crate::cell::OnceCell
/// [`LazyLock<T, F>`]: crate::sync::LazyLock
/// [`LazyLock::new(|| ...)`]: crate::sync::LazyLock::new
Expand Down Expand Up @@ -126,7 +129,7 @@ pub struct OnceLock<T> {
}

impl<T> OnceLock<T> {
/// Creates a new empty cell.
/// Creates a new uninitialized cell.
#[inline]
#[must_use]
#[stable(feature = "once_cell", since = "1.70.0")]
Expand All @@ -141,8 +144,8 @@ impl<T> OnceLock<T> {

/// 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 uninitialized, or being initialized.
/// This method never blocks.
#[inline]
#[stable(feature = "once_cell", since = "1.70.0")]
pub fn get(&self) -> Option<&T> {
Expand All @@ -156,7 +159,8 @@ impl<T> OnceLock<T> {

/// 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 uninitialized, 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> {
Expand Down Expand Up @@ -196,12 +200,13 @@ impl<T> OnceLock<T> {
unsafe { self.get_unchecked() }
}

/// Sets the contents of this cell to `value`.
/// Initializes the contents of the cell 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.
/// 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 was uninitialized and
/// `Err(value)` if the cell was already initialized.
///
/// # Examples
///
Expand Down Expand Up @@ -230,13 +235,15 @@ impl<T> OnceLock<T> {
}
}

/// Sets the contents of this cell to `value` if the cell was empty, then
/// returns a reference to it.
/// Initializes the contents of the cell to `value` if the cell was uninitialized,
/// 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.
/// 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(&current_value, value)` if it was full.
/// Returns `Ok(&value)` if the cell was uninitialized and
/// `Err((&current_value, value))` if it was already initialized.
///
/// # Examples
///
Expand Down Expand Up @@ -269,16 +276,16 @@ impl<T> OnceLock<T> {
}
}

/// Gets the contents of the cell, initializing it with `f` if the cell
/// was empty.
/// Gets the contents of the cell, initializing it to `f()` if the cell
/// was uninitialized.
///
/// Many threads may call `get_or_init` concurrently with different
/// initializing functions, but it is guaranteed that only one function
/// will be executed.
///
/// # 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
/// remains uninitialized.
///
/// It is an error to reentrantly initialize the cell from `f`. The
Expand Down Expand Up @@ -308,13 +315,13 @@ impl<T> OnceLock<T> {
}

/// Gets the mutable reference of the contents of the cell, initializing
/// it with `f` if the cell was empty.
/// it to `f()` if the cell was uninitialized.
///
/// This method never blocks.
///
/// # 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
/// remains uninitialized.
///
/// # Examples
Expand Down Expand Up @@ -345,13 +352,13 @@ impl<T> OnceLock<T> {
}
}

/// 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 contents of the cell, initializing it to `f()` if
/// the cell was uninitialized. If the cell was uninitialized
/// 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`.
Expand Down Expand Up @@ -397,14 +404,14 @@ impl<T> OnceLock<T> {
}

/// 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.
/// it to `f()` if the cell was uninitialized. If the cell was uninitialized
/// 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
Expand All @@ -416,7 +423,7 @@ impl<T> OnceLock<T> {
///
/// let mut cell: OnceLock<u32> = OnceLock::new();
///
/// // Failed initializers do not change the value
/// // Failed attempts to initialize the cell do not change its contents
/// assert!(cell.get_mut_or_try_init(|| "not a number!".parse()).is_err());
/// assert!(cell.get().is_none());
///
Expand All @@ -440,7 +447,7 @@ impl<T> OnceLock<T> {
}

/// Consumes the `OnceLock`, returning the wrapped value. Returns
/// `None` if the cell was empty.
/// `None` if the cell was uninitialized.
///
/// # Examples
///
Expand All @@ -462,7 +469,7 @@ impl<T> OnceLock<T> {

/// Takes the value out of this `OnceLock`, moving it back to an 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 uninitialized.
///
/// Safety is guaranteed by requiring a mutable reference.
///
Expand Down Expand Up @@ -528,7 +535,7 @@ impl<T> OnceLock<T> {

/// # Safety
///
/// The value must be initialized
/// The cell must be initialized
#[inline]
unsafe fn get_unchecked(&self) -> &T {
debug_assert!(self.is_initialized());
Expand All @@ -537,7 +544,7 @@ impl<T> OnceLock<T> {

/// # Safety
///
/// The value must be initialized
/// The cell must be initialized
#[inline]
unsafe fn get_unchecked_mut(&mut self) -> &mut T {
debug_assert!(self.is_initialized());
Expand All @@ -562,7 +569,7 @@ impl<T: UnwindSafe> UnwindSafe for OnceLock<T> {}

#[stable(feature = "once_cell", since = "1.70.0")]
impl<T> Default for OnceLock<T> {
/// Creates a new empty cell.
/// Creates a new uninitialized cell.
///
/// # Example
///
Expand Down

0 comments on commit f8b01b3

Please sign in to comment.