about summary refs log tree commit diff
path: root/library/std/src/lazy.rs
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2022-06-16 19:39:39 +0400
committerMaybe Waffle <waffle.lapkin@gmail.com>2022-06-16 19:54:42 +0400
commitc1a2db3372a4d6896744919284f3287650a38ab7 (patch)
tree636b2ff560a6dc628c5cec1440db82210b73dee5 /library/std/src/lazy.rs
parent7c360dc117d554a11f7193505da0835c4b890c6f (diff)
downloadrust-c1a2db3372a4d6896744919284f3287650a38ab7.tar.gz
rust-c1a2db3372a4d6896744919284f3287650a38ab7.zip
Move/rename `lazy::Sync{OnceCell,Lazy}` to `sync::{Once,Lazy}Lock`
Diffstat (limited to 'library/std/src/lazy.rs')
-rw-r--r--library/std/src/lazy.rs616
1 files changed, 0 insertions, 616 deletions
diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs
index d7450962359..f8c06c3f9ae 100644
--- a/library/std/src/lazy.rs
+++ b/library/std/src/lazy.rs
@@ -1,617 +1 @@
 //! Lazy values and one-time initialization of static data.
-
-#[cfg(test)]
-mod tests;
-
-use crate::{
-    cell::{Cell, UnsafeCell},
-    fmt,
-    marker::PhantomData,
-    mem::MaybeUninit,
-    ops::{Deref, Drop},
-    panic::{RefUnwindSafe, UnwindSafe},
-    pin::Pin,
-    sync::Once,
-};
-
-#[doc(inline)]
-#[unstable(feature = "once_cell", issue = "74465")]
-pub use core::lazy::*;
-
-/// A synchronization primitive which can be written to only once.
-///
-/// This type is a thread-safe `OnceCell`.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(once_cell)]
-///
-/// use std::lazy::SyncOnceCell;
-///
-/// static CELL: SyncOnceCell<String> = SyncOnceCell::new();
-/// assert!(CELL.get().is_none());
-///
-/// std::thread::spawn(|| {
-///     let value: &String = CELL.get_or_init(|| {
-///         "Hello, World!".to_string()
-///     });
-///     assert_eq!(value, "Hello, World!");
-/// }).join().unwrap();
-///
-/// let value: Option<&String> = CELL.get();
-/// assert!(value.is_some());
-/// assert_eq!(value.unwrap().as_str(), "Hello, World!");
-/// ```
-#[unstable(feature = "once_cell", issue = "74465")]
-pub struct SyncOnceCell<T> {
-    once: Once,
-    // Whether or not the value is initialized is tracked by `state_and_queue`.
-    value: UnsafeCell<MaybeUninit<T>>,
-    /// `PhantomData` to make sure dropck understands we're dropping T in our Drop impl.
-    ///
-    /// ```compile_fail,E0597
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// struct A<'a>(&'a str);
-    ///
-    /// impl<'a> Drop for A<'a> {
-    ///     fn drop(&mut self) {}
-    /// }
-    ///
-    /// let cell = SyncOnceCell::new();
-    /// {
-    ///     let s = String::new();
-    ///     let _ = cell.set(A(&s));
-    /// }
-    /// ```
-    _marker: PhantomData<T>,
-}
-
-// Why do we need `T: Send`?
-// Thread A creates a `SyncOnceCell` and shares it with
-// scoped thread B, which fills the cell, which is
-// then destroyed by A. That is, destructor observes
-// a sent value.
-#[unstable(feature = "once_cell", issue = "74465")]
-unsafe impl<T: Sync + Send> Sync for SyncOnceCell<T> {}
-#[unstable(feature = "once_cell", issue = "74465")]
-unsafe impl<T: Send> Send for SyncOnceCell<T> {}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
-impl<T> const Default for SyncOnceCell<T> {
-    /// Creates a new empty cell.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// fn main() {
-    ///     assert_eq!(SyncOnceCell::<()>::new(), SyncOnceCell::default());
-    /// }
-    /// ```
-    fn default() -> SyncOnceCell<T> {
-        SyncOnceCell::new()
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: fmt::Debug> fmt::Debug for SyncOnceCell<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.get() {
-            Some(v) => f.debug_tuple("Once").field(v).finish(),
-            None => f.write_str("Once(Uninit)"),
-        }
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: Clone> Clone for SyncOnceCell<T> {
-    fn clone(&self) -> SyncOnceCell<T> {
-        let cell = Self::new();
-        if let Some(value) = self.get() {
-            match cell.set(value.clone()) {
-                Ok(()) => (),
-                Err(_) => unreachable!(),
-            }
-        }
-        cell
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T> From<T> for SyncOnceCell<T> {
-    /// Create a new cell with its contents set to `value`.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// # fn main() -> Result<(), i32> {
-    /// let a = SyncOnceCell::from(3);
-    /// let b = SyncOnceCell::new();
-    /// b.set(3)?;
-    /// assert_eq!(a, b);
-    /// Ok(())
-    /// # }
-    /// ```
-    fn from(value: T) -> Self {
-        let cell = Self::new();
-        match cell.set(value) {
-            Ok(()) => cell,
-            Err(_) => unreachable!(),
-        }
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: PartialEq> PartialEq for SyncOnceCell<T> {
-    fn eq(&self, other: &SyncOnceCell<T>) -> bool {
-        self.get() == other.get()
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: Eq> Eq for SyncOnceCell<T> {}
-
-impl<T> SyncOnceCell<T> {
-    /// Creates a new empty cell.
-    #[unstable(feature = "once_cell", issue = "74465")]
-    #[must_use]
-    pub const fn new() -> SyncOnceCell<T> {
-        SyncOnceCell {
-            once: Once::new(),
-            value: UnsafeCell::new(MaybeUninit::uninit()),
-            _marker: PhantomData,
-        }
-    }
-
-    /// Gets the reference to the underlying value.
-    ///
-    /// Returns `None` if the cell is empty, or being initialized. This
-    /// method never blocks.
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn get(&self) -> Option<&T> {
-        if self.is_initialized() {
-            // Safe b/c checked is_initialized
-            Some(unsafe { self.get_unchecked() })
-        } else {
-            None
-        }
-    }
-
-    /// Gets the mutable reference to the underlying value.
-    ///
-    /// Returns `None` if the cell is empty. This method never blocks.
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn get_mut(&mut self) -> Option<&mut T> {
-        if self.is_initialized() {
-            // Safe b/c checked is_initialized and we have a unique access
-            Some(unsafe { self.get_unchecked_mut() })
-        } else {
-            None
-        }
-    }
-
-    /// Sets the contents of this 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.
-    ///
-    /// Returns `Ok(())` if the cell's value was set by this call.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// static CELL: SyncOnceCell<i32> = SyncOnceCell::new();
-    ///
-    /// fn main() {
-    ///     assert!(CELL.get().is_none());
-    ///
-    ///     std::thread::spawn(|| {
-    ///         assert_eq!(CELL.set(92), Ok(()));
-    ///     }).join().unwrap();
-    ///
-    ///     assert_eq!(CELL.set(62), Err(62));
-    ///     assert_eq!(CELL.get(), Some(&92));
-    /// }
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn set(&self, value: T) -> Result<(), T> {
-        let mut value = Some(value);
-        self.get_or_init(|| value.take().unwrap());
-        match value {
-            None => Ok(()),
-            Some(value) => Err(value),
-        }
-    }
-
-    /// Gets the contents of the cell, initializing it with `f` if the cell
-    /// was empty.
-    ///
-    /// 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
-    /// remains uninitialized.
-    ///
-    /// It is an error to reentrantly initialize the cell from `f`. The
-    /// exact outcome is unspecified. Current implementation deadlocks, but
-    /// this may be changed to a panic in the future.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// let cell = SyncOnceCell::new();
-    /// let value = cell.get_or_init(|| 92);
-    /// assert_eq!(value, &92);
-    /// let value = cell.get_or_init(|| unreachable!());
-    /// assert_eq!(value, &92);
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn get_or_init<F>(&self, f: F) -> &T
-    where
-        F: FnOnce() -> T,
-    {
-        match self.get_or_try_init(|| Ok::<T, !>(f())) {
-            Ok(val) => val,
-        }
-    }
-
-    /// 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.
-    ///
-    /// # Panics
-    ///
-    /// 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 exact outcome is unspecified. Current implementation
-    /// deadlocks, but this may be changed to a panic in the future.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// let cell = SyncOnceCell::new();
-    /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
-    /// assert!(cell.get().is_none());
-    /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
-    ///     Ok(92)
-    /// });
-    /// assert_eq!(value, Ok(&92));
-    /// assert_eq!(cell.get(), Some(&92))
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
-    where
-        F: FnOnce() -> Result<T, E>,
-    {
-        // Fast path check
-        // NOTE: We need to perform an acquire on the state in this method
-        // in order to correctly synchronize `SyncLazy::force`. This is
-        // currently done by calling `self.get()`, which in turn calls
-        // `self.is_initialized()`, which in turn performs the acquire.
-        if let Some(value) = self.get() {
-            return Ok(value);
-        }
-        self.initialize(f)?;
-
-        debug_assert!(self.is_initialized());
-
-        // SAFETY: The inner value has been initialized
-        Ok(unsafe { self.get_unchecked() })
-    }
-
-    /// Internal-only API that gets the contents of the cell, initializing it
-    /// in two steps with `f` and `g` if the cell was empty.
-    ///
-    /// `f` is called to construct the value, which is then moved into the cell
-    /// and given as a (pinned) mutable reference to `g` to finish
-    /// initialization.
-    ///
-    /// This allows `g` to inspect an manipulate the value after it has been
-    /// moved into its final place in the cell, but before the cell is
-    /// considered initialized.
-    ///
-    /// # Panics
-    ///
-    /// If `f` or `g` panics, the panic is propagated to the caller, and the
-    /// cell remains uninitialized.
-    ///
-    /// With the current implementation, if `g` panics, the value from `f` will
-    /// not be dropped. This should probably be fixed if this is ever used for
-    /// a type where this matters.
-    ///
-    /// It is an error to reentrantly initialize the cell from `f`. The exact
-    /// outcome is unspecified. Current implementation deadlocks, but this may
-    /// be changed to a panic in the future.
-    pub(crate) fn get_or_init_pin<F, G>(self: Pin<&Self>, f: F, g: G) -> Pin<&T>
-    where
-        F: FnOnce() -> T,
-        G: FnOnce(Pin<&mut T>),
-    {
-        if let Some(value) = self.get_ref().get() {
-            // SAFETY: The inner value was already initialized, and will not be
-            // moved anymore.
-            return unsafe { Pin::new_unchecked(value) };
-        }
-
-        let slot = &self.value;
-
-        // Ignore poisoning from other threads
-        // If another thread panics, then we'll be able to run our closure
-        self.once.call_once_force(|_| {
-            let value = f();
-            // SAFETY: We use the Once (self.once) to guarantee unique access
-            // to the UnsafeCell (slot).
-            let value: &mut T = unsafe { (&mut *slot.get()).write(value) };
-            // SAFETY: The value has been written to its final place in
-            // self.value. We do not to move it anymore, which we promise here
-            // with a Pin<&mut T>.
-            g(unsafe { Pin::new_unchecked(value) });
-        });
-
-        // SAFETY: The inner value has been initialized, and will not be moved
-        // anymore.
-        unsafe { Pin::new_unchecked(self.get_ref().get_unchecked()) }
-    }
-
-    /// Consumes the `SyncOnceCell`, returning the wrapped value. Returns
-    /// `None` if the cell was empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// let cell: SyncOnceCell<String> = SyncOnceCell::new();
-    /// assert_eq!(cell.into_inner(), None);
-    ///
-    /// let cell = SyncOnceCell::new();
-    /// cell.set("hello".to_string()).unwrap();
-    /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn into_inner(mut self) -> Option<T> {
-        self.take()
-    }
-
-    /// Takes the value out of this `SyncOnceCell`, moving it back to an uninitialized state.
-    ///
-    /// Has no effect and returns `None` if the `SyncOnceCell` hasn't been initialized.
-    ///
-    /// Safety is guaranteed by requiring a mutable reference.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// let mut cell: SyncOnceCell<String> = SyncOnceCell::new();
-    /// assert_eq!(cell.take(), None);
-    ///
-    /// let mut cell = SyncOnceCell::new();
-    /// cell.set("hello".to_string()).unwrap();
-    /// assert_eq!(cell.take(), Some("hello".to_string()));
-    /// assert_eq!(cell.get(), None);
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn take(&mut self) -> Option<T> {
-        if self.is_initialized() {
-            self.once = Once::new();
-            // SAFETY: `self.value` is initialized and contains a valid `T`.
-            // `self.once` is reset, so `is_initialized()` will be false again
-            // which prevents the value from being read twice.
-            unsafe { Some((&mut *self.value.get()).assume_init_read()) }
-        } else {
-            None
-        }
-    }
-
-    #[inline]
-    fn is_initialized(&self) -> bool {
-        self.once.is_completed()
-    }
-
-    #[cold]
-    fn initialize<F, E>(&self, f: F) -> Result<(), E>
-    where
-        F: FnOnce() -> Result<T, E>,
-    {
-        let mut res: Result<(), E> = Ok(());
-        let slot = &self.value;
-
-        // Ignore poisoning from other threads
-        // If another thread panics, then we'll be able to run our closure
-        self.once.call_once_force(|p| {
-            match f() {
-                Ok(value) => {
-                    unsafe { (&mut *slot.get()).write(value) };
-                }
-                Err(e) => {
-                    res = Err(e);
-
-                    // Treat the underlying `Once` as poisoned since we
-                    // failed to initialize our value. Calls
-                    p.poison();
-                }
-            }
-        });
-        res
-    }
-
-    /// # Safety
-    ///
-    /// The value must be initialized
-    unsafe fn get_unchecked(&self) -> &T {
-        debug_assert!(self.is_initialized());
-        (&*self.value.get()).assume_init_ref()
-    }
-
-    /// # Safety
-    ///
-    /// The value must be initialized
-    unsafe fn get_unchecked_mut(&mut self) -> &mut T {
-        debug_assert!(self.is_initialized());
-        (&mut *self.value.get()).assume_init_mut()
-    }
-}
-
-unsafe impl<#[may_dangle] T> Drop for SyncOnceCell<T> {
-    fn drop(&mut self) {
-        if self.is_initialized() {
-            // SAFETY: The cell is initialized and being dropped, so it can't
-            // be accessed again. We also don't touch the `T` other than
-            // dropping it, which validates our usage of #[may_dangle].
-            unsafe { (&mut *self.value.get()).assume_init_drop() };
-        }
-    }
-}
-
-/// A value which is initialized on the first access.
-///
-/// This type is a thread-safe `Lazy`, and can be used in statics.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(once_cell)]
-///
-/// use std::collections::HashMap;
-///
-/// use std::lazy::SyncLazy;
-///
-/// static HASHMAP: SyncLazy<HashMap<i32, String>> = SyncLazy::new(|| {
-///     println!("initializing");
-///     let mut m = HashMap::new();
-///     m.insert(13, "Spica".to_string());
-///     m.insert(74, "Hoyten".to_string());
-///     m
-/// });
-///
-/// fn main() {
-///     println!("ready");
-///     std::thread::spawn(|| {
-///         println!("{:?}", HASHMAP.get(&13));
-///     }).join().unwrap();
-///     println!("{:?}", HASHMAP.get(&74));
-///
-///     // Prints:
-///     //   ready
-///     //   initializing
-///     //   Some("Spica")
-///     //   Some("Hoyten")
-/// }
-/// ```
-#[unstable(feature = "once_cell", issue = "74465")]
-pub struct SyncLazy<T, F = fn() -> T> {
-    cell: SyncOnceCell<T>,
-    init: Cell<Option<F>>,
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: fmt::Debug, F> fmt::Debug for SyncLazy<T, F> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Lazy").field("cell", &self.cell).finish_non_exhaustive()
-    }
-}
-
-// We never create a `&F` from a `&SyncLazy<T, F>` so it is fine
-// to not impl `Sync` for `F`
-// we do create a `&mut Option<F>` in `force`, but this is
-// properly synchronized, so it only happens once
-// so it also does not contribute to this impl.
-#[unstable(feature = "once_cell", issue = "74465")]
-unsafe impl<T, F: Send> Sync for SyncLazy<T, F> where SyncOnceCell<T>: Sync {}
-// auto-derived `Send` impl is OK.
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T, F: UnwindSafe> RefUnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: RefUnwindSafe {}
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T, F: UnwindSafe> UnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: UnwindSafe {}
-
-impl<T, F> SyncLazy<T, F> {
-    /// Creates a new lazy value with the given initializing
-    /// function.
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub const fn new(f: F) -> SyncLazy<T, F> {
-        SyncLazy { cell: SyncOnceCell::new(), init: Cell::new(Some(f)) }
-    }
-}
-
-impl<T, F: FnOnce() -> T> SyncLazy<T, F> {
-    /// Forces the evaluation of this lazy value and
-    /// returns a reference to result. This is equivalent
-    /// to the `Deref` impl, but is explicit.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncLazy;
-    ///
-    /// let lazy = SyncLazy::new(|| 92);
-    ///
-    /// assert_eq!(SyncLazy::force(&lazy), &92);
-    /// assert_eq!(&*lazy, &92);
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn force(this: &SyncLazy<T, F>) -> &T {
-        this.cell.get_or_init(|| match this.init.take() {
-            Some(f) => f(),
-            None => panic!("Lazy instance has previously been poisoned"),
-        })
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {
-    type Target = T;
-    fn deref(&self) -> &T {
-        SyncLazy::force(self)
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: Default> Default for SyncLazy<T> {
-    /// Creates a new lazy value using `Default` as the initializing function.
-    fn default() -> SyncLazy<T> {
-        SyncLazy::new(T::default)
-    }
-}