From bba2d0944447a88e997f2b0ec74f440999d64b08 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Sun, 12 Jan 2020 18:14:29 +0100
Subject: [PATCH 1/6] First cut of `std::lazy` module

---
 src/libstd/lazy.rs | 1002 ++++++++++++++++++++++++++++++++++++++++++++
 src/libstd/lib.rs  |    6 +
 2 files changed, 1008 insertions(+)
 create mode 100644 src/libstd/lazy.rs

diff --git a/src/libstd/lazy.rs b/src/libstd/lazy.rs
new file mode 100644
index 0000000000000..bcac2dc311aff
--- /dev/null
+++ b/src/libstd/lazy.rs
@@ -0,0 +1,1002 @@
+//! `lazy` modules provides lazy values and one-time initialization of static data.
+//!
+//! `lazy` provides two new cell-like types, `OnceCell` and `SyncOnceCell`. `OnceCell`
+//! might store arbitrary non-`Copy` types, can be assigned to at most once and provide direct access
+//! to the stored contents. In a nutshell, API looks *roughly* like this:
+//!
+//! ```rust,ignore
+//! impl<T> OnceCell<T> {
+//!     fn new() -> OnceCell<T> { ... }
+//!     fn set(&self, value: T) -> Result<(), T> { ... }
+//!     fn get(&self) -> Option<&T> { ... }
+//! }
+//! ```
+//!
+//! Note that, like with `RefCell` and `Mutex`, the `set` method requires only a shared reference.
+//! Because of the single assignment restriction `get` can return an `&T` instead of `Ref<T>`
+//! or `MutexGuard<T>`.
+//!
+//! The `SyncOnceCell` flavor is thread-safe (that is, implements [`Sync`]) trait, while  `OnceCell` one is not.
+//!
+//! [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
+//!
+//! # Patterns
+//!
+//! `OnceCell` might be useful for a variety of patterns.
+//!
+//! ## Safe Initialization of global data
+//!
+//! ```rust
+//! use std::{env, io};
+//! use std::lazy::SyncOnceCell;
+//!
+//! #[derive(Debug)]
+//! pub struct Logger {
+//!     // ...
+//! }
+//! static INSTANCE: OnceCell<Logger> = OnceCell::new();
+//!
+//! impl Logger {
+//!     pub fn global() -> &'static Logger {
+//!         INSTANCE.get().expect("logger is not initialized")
+//!     }
+//!
+//!     fn from_cli(args: env::Args) -> Result<Logger, std::io::Error> {
+//!        // ...
+//! #      Ok(Logger {})
+//!     }
+//! }
+//!
+//! fn main() {
+//!     let logger = Logger::from_cli(env::args()).unwrap();
+//!     INSTANCE.set(logger).unwrap();
+//!     // use `Logger::global()` from now on
+//! }
+//! ```
+//!
+//! ## Lazy initialized global data
+//!
+//! This is essentially `lazy_static!` macro, but without a macro.
+//!
+//! ```rust
+//! use std::{sync::Mutex, collections::HashMap};
+//! use lazy::SyncOnceCell;
+//!
+//! fn global_data() -> &'static Mutex<HashMap<i32, String>> {
+//!     static INSTANCE: OnceCell<Mutex<HashMap<i32, String>>> = OnceCell::new();
+//!     INSTANCE.get_or_init(|| {
+//!         let mut m = HashMap::new();
+//!         m.insert(13, "Spica".to_string());
+//!         m.insert(74, "Hoyten".to_string());
+//!         Mutex::new(m)
+//!     })
+//! }
+//! ```
+//!
+//! There are also `sync::Lazy` and `unsync::Lazy` convenience types to streamline this pattern:
+//!
+//! ```rust
+//! use std::{sync::Mutex, collections::HashMap};
+//! use lazy::SyncLazy;
+//!
+//! static GLOBAL_DATA: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| {
+//!     let mut m = HashMap::new();
+//!     m.insert(13, "Spica".to_string());
+//!     m.insert(74, "Hoyten".to_string());
+//!     Mutex::new(m)
+//! });
+//!
+//! fn main() {
+//!     println!("{:?}", GLOBAL_DATA.lock().unwrap());
+//! }
+//! ```
+//!
+//! ## General purpose lazy evaluation
+//!
+//! `Lazy` also works with local variables.
+//!
+//! ```rust
+//! use std::lazy::Lazy;
+//!
+//! fn main() {
+//!     let ctx = vec![1, 2, 3];
+//!     let thunk = Lazy::new(|| {
+//!         ctx.iter().sum::<i32>()
+//!     });
+//!     assert_eq!(*thunk, 6);
+//! }
+//! ```
+//!
+//! If you need a lazy field in a struct, you probably should use `OnceCell`
+//! directly, because that will allow you to access `self` during initialization.
+//!
+//! ```rust
+//! use std::{fs, path::PathBuf};
+//!
+//! use std::lazy::OnceCell;
+//!
+//! struct Ctx {
+//!     config_path: PathBuf,
+//!     config: OnceCell<String>,
+//! }
+//!
+//! impl Ctx {
+//!     pub fn get_config(&self) -> Result<&str, std::io::Error> {
+//!         let cfg = self.config.get_or_try_init(|| {
+//!             fs::read_to_string(&self.config_path)
+//!         })?;
+//!         Ok(cfg.as_str())
+//!     }
+//! }
+//! ```
+//!
+//! ## Building block
+//!
+//! Naturally, it is  possible to build other abstractions on top of `OnceCell`.
+//! For example, this is a `regex!` macro which takes a string literal and returns an
+//! *expression* that evaluates to a `&'static Regex`:
+//!
+//! ```
+//! macro_rules! regex {
+//!     ($re:literal $(,)?) => {{
+//!         static RE: std::lazy::SyncOnceCell<regex::Regex> = std::lazy::SyncOnceCell::new();
+//!         RE.get_or_init(|| regex::Regex::new($re).unwrap())
+//!     }};
+//! }
+//! ```
+//!
+//! This macro can be useful to avoid "compile regex on every loop iteration" problem.
+//!
+//! # Comparison with other interior mutatbility types
+//!
+//! |`!Sync` types         | Access Mode            | Drawbacks                                     |
+//! |----------------------|------------------------|-----------------------------------------------|
+//! |`Cell<T>`             | `T`                    | requires `T: Copy` for `get`                  |
+//! |`RefCell<T>`          | `RefMut<T>` / `Ref<T>` | may panic at runtime                          |
+//! |`OnceCell<T>`         | `&T`                   | assignable only once                          |
+//!
+//! |`Sync` types          | Access Mode            | Drawbacks                                     |
+//! |----------------------|------------------------|-----------------------------------------------|
+//! |`AtomicT`             | `T`                    | works only with certain `Copy` types          |
+//! |`Mutex<T>`            | `MutexGuard<T>`        | may deadlock at runtime, may block the thread |
+//! |`SyncOnceCell<T>`     | `&T`                   | assignable only once, may block the thread    |
+//!
+//! Technically, calling `get_or_init` will also cause a panic or a deadlock if it recursively calls
+//! itself. However, because the assignment can happen only once, such cases should be more rare than
+//! equivalents with `RefCell` and `Mutex`.
+
+use crate::{
+    cell::{Cell, UnsafeCell},
+    fmt,
+    hint::unreachable_unchecked,
+    marker::PhantomData,
+    ops::Deref,
+    panic::{RefUnwindSafe, UnwindSafe},
+    sync::atomic::{AtomicBool, AtomicUsize, Ordering},
+    thread::{self, Thread},
+};
+
+/// A cell which can be written to only once. Not thread safe.
+///
+/// Unlike `:td::cell::RefCell`, a `OnceCell` provides simple `&`
+/// references to the contents.
+///
+/// # Example
+/// ```
+/// use std::lazy::OnceCell;
+///
+/// let cell = OnceCell::new();
+/// assert!(cell.get().is_none());
+///
+/// let value: &String = cell.get_or_init(|| {
+///     "Hello, World!".to_string()
+/// });
+/// assert_eq!(value, "Hello, World!");
+/// assert!(cell.get().is_some());
+/// ```
+pub struct OnceCell<T> {
+    // Invariant: written to at most once.
+    inner: UnsafeCell<Option<T>>,
+}
+
+// Similarly to a `Sync` bound on `SyncOnceCell`, we can use
+// `&OnceCell` to sneak a `T` through `catch_unwind`,
+// by initializing the cell in closure and extracting the value in the
+// `Drop`.
+#[cfg(feature = "std")]
+impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceCell<T> {}
+#[cfg(feature = "std")]
+impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
+
+impl<T> Default for OnceCell<T> {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self.get() {
+            Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
+            None => f.write_str("OnceCell(Uninit)"),
+        }
+    }
+}
+
+impl<T: Clone> Clone for OnceCell<T> {
+    fn clone(&self) -> OnceCell<T> {
+        let res = OnceCell::new();
+        if let Some(value) = self.get() {
+            match res.set(value.clone()) {
+                Ok(()) => (),
+                Err(_) => unreachable!(),
+            }
+        }
+        res
+    }
+}
+
+impl<T: PartialEq> PartialEq for OnceCell<T> {
+    fn eq(&self, other: &Self) -> bool {
+        self.get() == other.get()
+    }
+}
+
+impl<T: Eq> Eq for OnceCell<T> {}
+
+impl<T> From<T> for OnceCell<T> {
+    fn from(value: T) -> Self {
+        OnceCell { inner: UnsafeCell::new(Some(value)) }
+    }
+}
+
+impl<T> OnceCell<T> {
+    /// Creates a new empty cell.
+    pub const fn new() -> OnceCell<T> {
+        OnceCell { inner: UnsafeCell::new(None) }
+    }
+
+    /// Gets the reference to the underlying value.
+    ///
+    /// Returns `None` if the cell is empty.
+    pub fn get(&self) -> Option<&T> {
+        // Safe due to `inner`'s invariant
+        unsafe { &*self.inner.get() }.as_ref()
+    }
+
+    /// Gets the mutable reference to the underlying value.
+    ///
+    /// Returns `None` if the cell is empty.
+    pub fn get_mut(&mut self) -> Option<&mut T> {
+        // Safe because we have unique access
+        unsafe { &mut *self.inner.get() }.as_mut()
+    }
+
+    /// Sets the contents of this cell to `value`.
+    ///
+    /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
+    /// full.
+    ///
+    /// # Example
+    /// ```
+    /// use std::lazy::OnceCell;
+    ///
+    /// let cell = OnceCell::new();
+    /// assert!(cell.get().is_none());
+    ///
+    /// assert_eq!(cell.set(92), Ok(()));
+    /// assert_eq!(cell.set(62), Err(62));
+    ///
+    /// assert!(cell.get().is_some());
+    /// ```
+    pub fn set(&self, value: T) -> Result<(), T> {
+        let slot = unsafe { &*self.inner.get() };
+        if slot.is_some() {
+            return Err(value);
+        }
+        let slot = unsafe { &mut *self.inner.get() };
+        // This is the only place where we set the slot, no races
+        // due to reentrancy/concurrency are possible, and we've
+        // checked that slot is currently `None`, so this write
+        // maintains the `inner`'s invariant.
+        *slot = Some(value);
+        Ok(())
+    }
+
+    /// Gets the contents of the cell, initializing it with `f`
+    /// if the cell was empty.
+    ///
+    /// # 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`. Doing
+    /// so results in a panic.
+    ///
+    /// # Example
+    /// ```
+    /// use std::lazy::OnceCell;
+    ///
+    /// let cell = OnceCell::new();
+    /// let value = cell.get_or_init(|| 92);
+    /// assert_eq!(value, &92);
+    /// let value = cell.get_or_init(|| unreachable!());
+    /// assert_eq!(value, &92);
+    /// ```
+    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`. Doing
+    /// so results in a panic.
+    ///
+    /// # Example
+    /// ```
+    /// use std::lazy::OnceCell;
+    ///
+    /// let cell = OnceCell::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))
+    /// ```
+    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
+    where
+        F: FnOnce() -> Result<T, E>,
+    {
+        if let Some(val) = self.get() {
+            return Ok(val);
+        }
+        let val = f()?;
+        // Note that *some* forms of reentrant initialization might lead to
+        // UB (see `reentrant_init` test). I believe that just removing this
+        // `assert`, while keeping `set/get` would be sound, but it seems
+        // better to panic, rather than to silently use an old value.
+        assert!(self.set(val).is_ok(), "reentrant init");
+        Ok(self.get().unwrap())
+    }
+
+    /// Consumes the `OnceCell`, returning the wrapped value.
+    ///
+    /// Returns `None` if the cell was empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::lazy::OnceCell;
+    ///
+    /// let cell: OnceCell<String> = OnceCell::new();
+    /// assert_eq!(cell.into_inner(), None);
+    ///
+    /// let cell = OnceCell::new();
+    /// cell.set("hello".to_string()).unwrap();
+    /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
+    /// ```
+    pub fn into_inner(self) -> Option<T> {
+        // Because `into_inner` takes `self` by value, the compiler statically verifies
+        // that it is not currently borrowed. So it is safe to move out `Option<T>`.
+        self.inner.into_inner()
+    }
+}
+
+/// A value which is initialized on the first access.
+///
+/// # Example
+/// ```
+/// use std::lazy::Lazy;
+///
+/// let lazy: Lazy<i32> = Lazy::new(|| {
+///     println!("initializing");
+///     92
+/// });
+/// println!("ready");
+/// println!("{}", *lazy);
+/// println!("{}", *lazy);
+///
+/// // Prints:
+/// //   ready
+/// //   initializing
+/// //   92
+/// //   92
+/// ```
+pub struct Lazy<T, F = fn() -> T> {
+    cell: OnceCell<T>,
+    init: Cell<Option<F>>,
+}
+
+#[cfg(feature = "std")]
+impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where OnceCell<T>: RefUnwindSafe {}
+
+impl<T: fmt::Debug, F: fmt::Debug> fmt::Debug for Lazy<T, F> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
+    }
+}
+
+impl<T, F> Lazy<T, F> {
+    /// Creates a new lazy value with the given initializing function.
+    ///
+    /// # Example
+    /// ```
+    /// # fn main() {
+    /// use std::lazy::Lazy;
+    ///
+    /// let hello = "Hello, World!".to_string();
+    ///
+    /// let lazy = Lazy::new(|| hello.to_uppercase());
+    ///
+    /// assert_eq!(&*lazy, "HELLO, WORLD!");
+    /// # }
+    /// ```
+    pub const fn new(init: F) -> Lazy<T, F> {
+        Lazy { cell: OnceCell::new(), init: Cell::new(Some(init)) }
+    }
+}
+
+impl<T, F: FnOnce() -> T> Lazy<T, F> {
+    /// Forces the evaluation of this lazy value and returns a reference to
+    /// the result.
+    ///
+    /// This is equivalent to the `Deref` impl, but is explicit.
+    ///
+    /// # Example
+    /// ```
+    /// use std::lazy::Lazy;
+    ///
+    /// let lazy = Lazy::new(|| 92);
+    ///
+    /// assert_eq!(Lazy::force(&lazy), &92);
+    /// assert_eq!(&*lazy, &92);
+    /// ```
+    pub fn force(this: &Lazy<T, F>) -> &T {
+        this.cell.get_or_init(|| match this.init.take() {
+            Some(f) => f(),
+            None => panic!("Lazy instance has previously been poisoned"),
+        })
+    }
+}
+
+impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
+    type Target = T;
+    fn deref(&self) -> &T {
+        Lazy::force(self)
+    }
+}
+
+impl<T: Default> Default for Lazy<T> {
+    /// Creates a new lazy value using `Default` as the initializing function.
+    fn default() -> Lazy<T> {
+        Lazy::new(T::default)
+    }
+}
+
+/// A thread-safe cell which can be written to only once.
+///
+/// `OnceCell` provides `&` references to the contents without RAII guards.
+///
+/// Reading a non-`None` value out of `OnceCell` establishes a
+/// happens-before relationship with a corresponding write. For example, if
+/// thread A initializes the cell with `get_or_init(f)`, and thread B
+/// subsequently reads the result of this call, B also observes all the side
+/// effects of `f`.
+///
+/// # Example
+/// ```
+/// use std::lazy::SyncOnceCell;
+///
+/// static CELL: OnceCell<String> = OnceCell::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!");
+/// ```
+pub struct SyncOnceCell<T> {
+    // This `state` word is actually an encoded version of just a pointer to a
+    // `Waiter`, so we add the `PhantomData` appropriately.
+    state_and_queue: AtomicUsize,
+    _marker: PhantomData<*mut Waiter>,
+    // FIXME: switch to `std::mem::MaybeUninit` once we are ready to bump MSRV
+    // that far. It was stabilized in 1.36.0, so, if you are reading this and
+    // it's higher than 1.46.0 outside, please send a PR! ;) (and do the same
+    // for `Lazy`, while we are at it).
+    pub(crate) value: UnsafeCell<Option<T>>,
+}
+
+// Why do we need `T: Send`?
+// Thread A creates a `OnceCell` and shares it with
+// scoped thread B, which fills the cell, which is
+// then destroyed by A. That is, destructor observes
+// a sent value.
+unsafe impl<T: Sync + Send> Sync for SyncOnceCell<T> {}
+unsafe impl<T: Send> Send for SyncOnceCell<T> {}
+
+impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
+impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
+
+impl<T> Default for SyncOnceCell<T> {
+    fn default() -> SyncOnceCell<T> {
+        SyncOnceCell::new()
+    }
+}
+
+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("SyncOnceCell").field(v).finish(),
+            None => f.write_str("SyncOnceCell(Uninit)"),
+        }
+    }
+}
+
+impl<T: Clone> Clone for SyncOnceCell<T> {
+    fn clone(&self) -> SyncOnceCell<T> {
+        let res = SyncOnceCell::new();
+        if let Some(value) = self.get() {
+            match res.set(value.clone()) {
+                Ok(()) => (),
+                Err(_) => unreachable!(),
+            }
+        }
+        res
+    }
+}
+
+impl<T> From<T> for SyncOnceCell<T> {
+    fn from(value: T) -> Self {
+        let cell = Self::new();
+        cell.get_or_init(|| value);
+        cell
+    }
+}
+
+impl<T: PartialEq> PartialEq for SyncOnceCell<T> {
+    fn eq(&self, other: &SyncOnceCell<T>) -> bool {
+        self.get() == other.get()
+    }
+}
+
+impl<T: Eq> Eq for SyncOnceCell<T> {}
+
+impl<T> SyncOnceCell<T> {
+    /// Creates a new empty cell.
+    pub const fn new() -> SyncOnceCell<T> {
+        SyncOnceCell {
+            state_and_queue: AtomicUsize::new(INCOMPLETE),
+            _marker: PhantomData,
+            value: UnsafeCell::new(None),
+        }
+    }
+
+    /// Gets the reference to the underlying value.
+    ///
+    /// Returns `None` if the cell is empty, or being initialized. This
+    /// method never blocks.
+    pub fn get(&self) -> Option<&T> {
+        if self.is_initialized() {
+            // Safe b/c checked is_initialize
+            Some(unsafe { self.get_unchecked() })
+        } else {
+            None
+        }
+    }
+
+    /// Gets the mutable reference to the underlying value.
+    ///
+    /// Returns `None` if the cell is empty.
+    pub fn get_mut(&mut self) -> Option<&mut T> {
+        // Safe b/c we have a unique access.
+        unsafe { &mut *self.value.get() }.as_mut()
+    }
+
+    /// Get the reference to the underlying value, without checking if the
+    /// cell is initialized.
+    ///
+    /// Safety:
+    ///
+    /// Caller must ensure that the cell is in initialized state, and that
+    /// the contents are acquired by (synchronized to) this thread.
+    pub unsafe fn get_unchecked(&self) -> &T {
+        debug_assert!(self.is_initialized());
+        let slot: &Option<T> = &*self.value.get();
+        match slot {
+            Some(value) => value,
+            // This unsafe does improve performance, see `examples/bench`.
+            None => {
+                debug_assert!(false);
+                unreachable_unchecked()
+            }
+        }
+    }
+
+    /// Sets the contents of this cell to `value`.
+    ///
+    /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
+    /// full.
+    ///
+    /// # Example
+    /// ```
+    /// 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));
+    /// }
+    /// ```
+    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.
+    ///
+    /// # Example
+    /// ```
+    /// 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);
+    /// ```
+    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.
+    ///
+    /// # Example
+    /// ```
+    /// 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))
+    /// ```
+    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
+    where
+        F: FnOnce() -> Result<T, E>,
+    {
+        // Fast path check
+        if let Some(value) = self.get() {
+            return Ok(value);
+        }
+        self.initialize(f)?;
+
+        // Safe b/c called initialize
+        debug_assert!(self.is_initialized());
+        Ok(unsafe { self.get_unchecked() })
+    }
+
+    /// Consumes the `SyncOnceCell`, returning the wrapped value. Returns
+    /// `None` if the cell was empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// 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()));
+    /// ```
+    pub fn into_inner(self) -> Option<T> {
+        // Because `into_inner` takes `self` by value, the compiler statically verifies
+        // that it is not currently borrowed. So it is safe to move out `Option<T>`.
+        self.value.into_inner()
+    }
+
+    /// Safety: synchronizes with store to value via Release/(Acquire|SeqCst).
+    #[inline]
+    fn is_initialized(&self) -> bool {
+        // An `Acquire` load is enough because that makes all the initialization
+        // operations visible to us, and, this being a fast path, weaker
+        // ordering helps with performance. This `Acquire` synchronizes with
+        // `SeqCst` operations on the slow path.
+        self.state_and_queue.load(Ordering::Acquire) == COMPLETE
+    }
+
+    /// Safety: synchronizes with store to value via SeqCst read from state,
+    /// writes value only once because we never get to INCOMPLETE state after a
+    /// successful write.
+    #[cold]
+    fn initialize<F, E>(&self, f: F) -> Result<(), E>
+    where
+        F: FnOnce() -> Result<T, E>,
+    {
+        let mut f = Some(f);
+        let mut res: Result<(), E> = Ok(());
+        let slot = &self.value;
+        initialize_inner(&self.state_and_queue, &mut || {
+            let f = f.take().unwrap();
+            match f() {
+                Ok(value) => {
+                    unsafe { *slot.get() = Some(value) };
+                    true
+                }
+                Err(e) => {
+                    res = Err(e);
+                    false
+                }
+            }
+        });
+        res
+    }
+}
+
+// region: copy-paste
+// The following code is copied from `sync::Once`.
+// This should be uncopypasted once we decide the right way to handle panics.
+const INCOMPLETE: usize = 0x0;
+const RUNNING: usize = 0x1;
+const COMPLETE: usize = 0x2;
+
+const STATE_MASK: usize = 0x3;
+
+
+#[repr(align(4))]
+struct Waiter {
+    thread: Cell<Option<Thread>>,
+    signaled: AtomicBool,
+    next: *const Waiter,
+}
+
+struct WaiterQueue<'a> {
+    state_and_queue: &'a AtomicUsize,
+    set_state_on_drop_to: usize,
+}
+
+impl Drop for WaiterQueue<'_> {
+    fn drop(&mut self) {
+        let state_and_queue =
+            self.state_and_queue.swap(self.set_state_on_drop_to, Ordering::AcqRel);
+
+        assert_eq!(state_and_queue & STATE_MASK, RUNNING);
+
+        unsafe {
+            let mut queue = (state_and_queue & !STATE_MASK) as *const Waiter;
+            while !queue.is_null() {
+                let next = (*queue).next;
+                let thread = (*queue).thread.replace(None).unwrap();
+                (*queue).signaled.store(true, Ordering::Release);
+                queue = next;
+                thread.unpark();
+            }
+        }
+    }
+}
+
+fn initialize_inner(my_state_and_queue: &AtomicUsize, init: &mut dyn FnMut() -> bool) -> bool {
+    let mut state_and_queue = my_state_and_queue.load(Ordering::Acquire);
+
+    loop {
+        match state_and_queue {
+            COMPLETE => return true,
+            INCOMPLETE => {
+                let old = my_state_and_queue.compare_and_swap(
+                    state_and_queue,
+                    RUNNING,
+                    Ordering::Acquire,
+                );
+                if old != state_and_queue {
+                    state_and_queue = old;
+                    continue;
+                }
+                let mut waiter_queue = WaiterQueue {
+                    state_and_queue: my_state_and_queue,
+                    set_state_on_drop_to: INCOMPLETE,
+                };
+                let success = init();
+
+                waiter_queue.set_state_on_drop_to = if success { COMPLETE } else { INCOMPLETE };
+                return success;
+            }
+            _ => {
+                assert!(state_and_queue & STATE_MASK == RUNNING);
+                wait(&my_state_and_queue, state_and_queue);
+                state_and_queue = my_state_and_queue.load(Ordering::Acquire);
+            }
+        }
+    }
+}
+
+fn wait(state_and_queue: &AtomicUsize, mut current_state: usize) {
+    loop {
+        if current_state & STATE_MASK != RUNNING {
+            return;
+        }
+
+        let node = Waiter {
+            thread: Cell::new(Some(thread::current())),
+            signaled: AtomicBool::new(false),
+            next: (current_state & !STATE_MASK) as *const Waiter,
+        };
+        let me = &node as *const Waiter as usize;
+
+        let old = state_and_queue.compare_and_swap(current_state, me | RUNNING, Ordering::Release);
+        if old != current_state {
+            current_state = old;
+            continue;
+        }
+
+        while !node.signaled.load(Ordering::Acquire) {
+            thread::park();
+        }
+        break;
+    }
+}
+// endregion: copy-paste
+
+/// A value which is initialized on the first access.
+///
+/// This type is thread-safe and can be used in statics:
+///
+/// # Example
+/// ```
+/// use std::collections::HashMap;
+///
+/// use std::lazy::Lazy;
+///
+/// static HASHMAP: Lazy<HashMap<i32, String>> = Lazy::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")
+/// }
+/// ```
+pub struct SyncLazy<T, F = fn() -> T> {
+    cell: SyncOnceCell<T>,
+    init: Cell<Option<F>>,
+}
+
+impl<T: fmt::Debug, F: fmt::Debug> fmt::Debug for SyncLazy<T, F> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("SyncLazy").field("cell", &self.cell).field("init", &"..").finish()
+    }
+}
+
+// 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.
+unsafe impl<T, F: Send> Sync for SyncLazy<T, F> where SyncOnceCell<T>: Sync {}
+// auto-derived `Send` impl is OK.
+
+#[cfg(feature = "std")]
+impl<T, F: RefUnwindSafe> RefUnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: RefUnwindSafe {}
+
+impl<T, F> SyncLazy<T, F> {
+    /// Creates a new lazy value with the given initializing
+    /// function.
+    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.
+    ///
+    /// # Example
+    /// ```
+    /// use std::lazy::SyncLazy;
+    ///
+    /// let lazy = SyncLazy::new(|| 92);
+    ///
+    /// assert_eq!(SyncLazy::force(&lazy), &92);
+    /// assert_eq!(&*lazy, &92);
+    /// ```
+    pub fn force(this: &SyncLazy<T, F>) -> &T {
+        this.cell.get_or_init(|| match this.init.take() {
+            Some(f) => f(),
+            None => panic!("SyncLazy instance has previously been poisoned"),
+        })
+    }
+}
+
+impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {
+    type Target = T;
+    fn deref(&self) -> &T {
+        SyncLazy::force(self)
+    }
+}
+
+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)
+    }
+}
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index bc07c6b487b17..0720aa769238e 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -466,6 +466,12 @@ pub mod process;
 pub mod sync;
 pub mod time;
 
+#[unstable(
+    feature = "std_lazy",
+    issue = "99",
+)]
+pub mod lazy;
+
 #[stable(feature = "futures_api", since = "1.36.0")]
 pub mod task {
     //! Types and Traits for working with asynchronous tasks.

From 973e9531771481a657df82483380a9070fb1e3b9 Mon Sep 17 00:00:00 2001
From: Ashley Mannix <ashleymannix@live.com.au>
Date: Tue, 14 Jan 2020 13:34:23 +1000
Subject: [PATCH 2/6] integrate Lazy into std layout

---
 src/libcore/cell.rs | 362 ++++++++++++++++++++++++++-
 src/libstd/lazy.rs  | 594 +++++++++++++-------------------------------
 src/libstd/lib.rs   |   6 +-
 src/stdsimd         |   1 +
 4 files changed, 529 insertions(+), 434 deletions(-)
 create mode 160000 src/stdsimd

diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index e7eecf7540ad7..45b5c5b7fd77e 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -18,15 +18,16 @@
 //! [`RwLock`](../../std/sync/struct.RwLock.html) or
 //! [`atomic`](../../core/sync/atomic/index.html) types.
 //!
-//! Values of the `Cell<T>` and `RefCell<T>` types may be mutated through shared references (i.e.
+//! Values of the cell types may be mutated through shared references (i.e.
 //! the common `&T` type), whereas most Rust types can only be mutated through unique (`&mut T`)
-//! references. We say that `Cell<T>` and `RefCell<T>` provide 'interior mutability', in contrast
+//! references. We say that cells provide 'interior mutability', in contrast
 //! with typical Rust types that exhibit 'inherited mutability'.
 //!
-//! Cell types come in two flavors: `Cell<T>` and `RefCell<T>`. `Cell<T>` implements interior
+//! Cell types come in several flavors. `Cell<T>` implements interior
 //! mutability by moving values in and out of the `Cell<T>`. To use references instead of values,
-//! one must use the `RefCell<T>` type, acquiring a write lock before mutating. `Cell<T>` provides
-//! methods to retrieve and change the current interior value:
+//! one must use the `RefCell<T>` type, acquiring a write lock before mutating. For values that
+//! only need lazy initialization, one can use the `OnceCell<T>` or `LazyCell<T, F>` types. `Cell<T>`
+//! provides methods to retrieve and change the current interior value:
 //!
 //!  - For types that implement `Copy`, the `get` method retrieves the current interior value.
 //!  - For types that implement `Default`, the `take` method replaces the current interior value
@@ -43,6 +44,12 @@
 //! to borrow a value that is already mutably borrowed; when this happens it results in thread
 //! panic.
 //!
+//! `OnceCell<T>` allows one to access a value by also providing an initialization function for it.
+//! If the `OnceCell<T>` already contains an initialized value then it is returned, otherwise the
+//! initialization function is run and the result is stored in the cell.
+//! `LazyCell<T, F>` is similar to `OnceCell<T>`, but keeps its initialization function as part of
+//! the type, so it doesn't need to be provided whenever the cell is accessed.
+//!
 //! # When to choose interior mutability
 //!
 //! The more common inherited mutability, where one must have unique access to mutate a value, is
@@ -1414,6 +1421,351 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
     }
 }
 
+/// A cell which can be written to only once.
+///
+/// Unlike `RefCell`, a `OnceCell` only provides shared `&T` references to its value.
+/// Unlike `Cell`, a `OnceCell` doesn't require `T: Copy` to access its value.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(once_cell)]
+///
+/// use std::cell::OnceCell;
+///
+/// let cell = OnceCell::new();
+/// assert!(cell.get().is_none());
+///
+/// let value: &String = cell.get_or_init(|| {
+///     "Hello, World!".to_string()
+/// });
+/// assert_eq!(value, "Hello, World!");
+/// assert!(cell.get().is_some());
+/// ```
+#[unstable(feature = "once_cell", issue = "68198")]
+pub struct OnceCell<T> {
+    // Invariant: written to at most once.
+    inner: UnsafeCell<Option<T>>,
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T> Default for OnceCell<T> {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self.get() {
+            Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
+            None => f.write_str("OnceCell(Uninit)"),
+        }
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: Clone> Clone for OnceCell<T> {
+    fn clone(&self) -> OnceCell<T> {
+        let res = OnceCell::new();
+        if let Some(value) = self.get() {
+            match res.set(value.clone()) {
+                Ok(()) => (),
+                Err(_) => unreachable!(),
+            }
+        }
+        res
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: PartialEq> PartialEq for OnceCell<T> {
+    fn eq(&self, other: &Self) -> bool {
+        self.get() == other.get()
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: Eq> Eq for OnceCell<T> {}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T> From<T> for OnceCell<T> {
+    fn from(value: T) -> Self {
+        OnceCell { inner: UnsafeCell::new(Some(value)) }
+    }
+}
+
+impl<T> OnceCell<T> {
+    /// Creates a new empty cell.
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub const fn new() -> OnceCell<T> {
+        OnceCell { inner: UnsafeCell::new(None) }
+    }
+
+    /// Gets the reference to the underlying value.
+    ///
+    /// Returns `None` if the cell is empty.
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub fn get(&self) -> Option<&T> {
+        // Safe due to `inner`'s invariant
+        unsafe { &*self.inner.get() }.as_ref()
+    }
+
+    /// Gets the mutable reference to the underlying value.
+    ///
+    /// Returns `None` if the cell is empty.
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub fn get_mut(&mut self) -> Option<&mut T> {
+        // Safe because we have unique access
+        unsafe { &mut *self.inner.get() }.as_mut()
+    }
+
+    /// Sets the contents of the cell to `value`.
+    ///
+    /// # Errors
+    ///
+    /// This method returns `Ok(())` if the cell was empty and `Err(value)` if
+    /// it was full.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::cell::OnceCell;
+    ///
+    /// let cell = OnceCell::new();
+    /// assert!(cell.get().is_none());
+    ///
+    /// assert_eq!(cell.set(92), Ok(()));
+    /// assert_eq!(cell.set(62), Err(62));
+    ///
+    /// assert!(cell.get().is_some());
+    /// ```
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub fn set(&self, value: T) -> Result<(), T> {
+        let slot = unsafe { &*self.inner.get() };
+        if slot.is_some() {
+            return Err(value);
+        }
+        let slot = unsafe { &mut *self.inner.get() };
+        // This is the only place where we set the slot, no races
+        // due to reentrancy/concurrency are possible, and we've
+        // checked that slot is currently `None`, so this write
+        // maintains the `inner`'s invariant.
+        *slot = Some(value);
+        Ok(())
+    }
+
+    /// Gets the contents of the cell, initializing it with `f`
+    /// if the cell was empty.
+    ///
+    /// # 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`. Doing
+    /// so results in a panic.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::cell::OnceCell;
+    ///
+    /// let cell = OnceCell::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 = "68198")]
+    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`. Doing
+    /// so results in a panic.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::cell::OnceCell;
+    ///
+    /// let cell = OnceCell::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 = "68198")]
+    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
+    where
+        F: FnOnce() -> Result<T, E>,
+    {
+        if let Some(val) = self.get() {
+            return Ok(val);
+        }
+        let val = f()?;
+        // Note that *some* forms of reentrant initialization might lead to
+        // UB (see `reentrant_init` test). I believe that just removing this
+        // `assert`, while keeping `set/get` would be sound, but it seems
+        // better to panic, rather than to silently use an old value.
+        assert!(self.set(val).is_ok(), "reentrant init");
+        Ok(self.get().unwrap())
+    }
+
+    /// Consumes the cell, returning the wrapped value.
+    ///
+    /// Returns `None` if the cell was empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::cell::OnceCell;
+    ///
+    /// let cell: OnceCell<String> = OnceCell::new();
+    /// assert_eq!(cell.into_inner(), None);
+    ///
+    /// let cell = OnceCell::new();
+    /// cell.set("hello".to_string()).unwrap();
+    /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
+    /// ```
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub fn into_inner(self) -> Option<T> {
+        // Because `into_inner` takes `self` by value, the compiler statically verifies
+        // that it is not currently borrowed. So it is safe to move out `Option<T>`.
+        self.inner.into_inner()
+    }
+}
+
+/// A value which is initialized on the first access.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(once_cell)]
+///
+/// use std::cell::LazyCell;
+///
+/// let lazy: LazyCell<i32> = LazyCell::new(|| {
+///     println!("initializing");
+///     92
+/// });
+/// println!("ready");
+/// println!("{}", *lazy);
+/// println!("{}", *lazy);
+///
+/// // Prints:
+/// //   ready
+/// //   initializing
+/// //   92
+/// //   92
+/// ```
+#[unstable(feature = "once_cell", issue = "68198")]
+pub struct LazyCell<T, F = fn() -> T> {
+    cell: OnceCell<T>,
+    init: Cell<Option<F>>,
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: fmt::Debug, F: fmt::Debug> fmt::Debug for LazyCell<T, F> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("LazyCell").field("cell", &self.cell).field("init", &"..").finish()
+    }
+}
+
+impl<T, F> LazyCell<T, F> {
+    /// Creates a new lazy value with the given initializing function.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// # fn main() {
+    /// use std::cell::LazyCell;
+    ///
+    /// let hello = "Hello, World!".to_string();
+    ///
+    /// let lazy = LazyCell::new(|| hello.to_uppercase());
+    ///
+    /// assert_eq!(&*lazy, "HELLO, WORLD!");
+    /// # }
+    /// ```
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub const fn new(init: F) -> LazyCell<T, F> {
+        LazyCell { cell: OnceCell::new(), init: Cell::new(Some(init)) }
+    }
+}
+
+impl<T, F: FnOnce() -> T> LazyCell<T, F> {
+    /// Forces the evaluation of this lazy value and returns a reference to
+    /// the result.
+    ///
+    /// This is equivalent to the `Deref` impl, but is explicit.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::cell::LazyCell;
+    ///
+    /// let lazy = LazyCell::new(|| 92);
+    ///
+    /// assert_eq!(LazyCell::force(&lazy), &92);
+    /// assert_eq!(&*lazy, &92);
+    /// ```
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub fn force(this: &LazyCell<T, F>) -> &T {
+        this.cell.get_or_init(|| match this.init.take() {
+            Some(f) => f(),
+            None => panic!("`LazyCell` instance has previously been poisoned"),
+        })
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T, F: FnOnce() -> T> Deref for LazyCell<T, F> {
+    type Target = T;
+    fn deref(&self) -> &T {
+        LazyCell::force(self)
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: Default> Default for LazyCell<T> {
+    /// Creates a new lazy value using `Default` as the initializing function.
+    fn default() -> LazyCell<T> {
+        LazyCell::new(T::default)
+    }
+}
+
 /// The core primitive for interior mutability in Rust.
 ///
 /// `UnsafeCell<T>` is a type that wraps some `T` and indicates unsafe interior operations on the
diff --git a/src/libstd/lazy.rs b/src/libstd/lazy.rs
index bcac2dc311aff..11b5e5d40a10d 100644
--- a/src/libstd/lazy.rs
+++ b/src/libstd/lazy.rs
@@ -1,40 +1,30 @@
-//! `lazy` modules provides lazy values and one-time initialization of static data.
+//! Lazy values and one-time initialization of static data.
 //!
-//! `lazy` provides two new cell-like types, `OnceCell` and `SyncOnceCell`. `OnceCell`
+//! `lazy` provides two new cell-like types, `Once` and `Lazy`. `Once`
 //! might store arbitrary non-`Copy` types, can be assigned to at most once and provide direct access
-//! to the stored contents. In a nutshell, API looks *roughly* like this:
-//!
-//! ```rust,ignore
-//! impl<T> OnceCell<T> {
-//!     fn new() -> OnceCell<T> { ... }
-//!     fn set(&self, value: T) -> Result<(), T> { ... }
-//!     fn get(&self) -> Option<&T> { ... }
-//! }
-//! ```
+//! to the stored contents.
 //!
 //! Note that, like with `RefCell` and `Mutex`, the `set` method requires only a shared reference.
 //! Because of the single assignment restriction `get` can return an `&T` instead of `Ref<T>`
 //! or `MutexGuard<T>`.
 //!
-//! The `SyncOnceCell` flavor is thread-safe (that is, implements [`Sync`]) trait, while  `OnceCell` one is not.
-//!
-//! [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
-//!
 //! # Patterns
 //!
-//! `OnceCell` might be useful for a variety of patterns.
+//! `Once` can be useful for a variety of patterns.
 //!
 //! ## Safe Initialization of global data
 //!
 //! ```rust
+//! #![feature(once_cell)]
+//!
 //! use std::{env, io};
-//! use std::lazy::SyncOnceCell;
+//! use std::lazy::Once;
 //!
 //! #[derive(Debug)]
 //! pub struct Logger {
 //!     // ...
 //! }
-//! static INSTANCE: OnceCell<Logger> = OnceCell::new();
+//! static INSTANCE: Once<Logger> = Once::new();
 //!
 //! impl Logger {
 //!     pub fn global() -> &'static Logger {
@@ -59,11 +49,13 @@
 //! This is essentially `lazy_static!` macro, but without a macro.
 //!
 //! ```rust
+//! #![feature(once_cell)]
+//!
 //! use std::{sync::Mutex, collections::HashMap};
-//! use lazy::SyncOnceCell;
+//! use lazy::Once;
 //!
 //! fn global_data() -> &'static Mutex<HashMap<i32, String>> {
-//!     static INSTANCE: OnceCell<Mutex<HashMap<i32, String>>> = OnceCell::new();
+//!     static INSTANCE: Once<Mutex<HashMap<i32, String>>> = Once::new();
 //!     INSTANCE.get_or_init(|| {
 //!         let mut m = HashMap::new();
 //!         m.insert(13, "Spica".to_string());
@@ -73,11 +65,13 @@
 //! }
 //! ```
 //!
-//! There are also `sync::Lazy` and `unsync::Lazy` convenience types to streamline this pattern:
+//! There is also `Lazy` to streamline this pattern:
 //!
 //! ```rust
+//! #![feature(once_cell)]
+//!
 //! use std::{sync::Mutex, collections::HashMap};
-//! use lazy::SyncLazy;
+//! use lazy::Lazy;
 //!
 //! static GLOBAL_DATA: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| {
 //!     let mut m = HashMap::new();
@@ -96,6 +90,8 @@
 //! `Lazy` also works with local variables.
 //!
 //! ```rust
+//! #![feature(once_cell)]
+//!
 //! use std::lazy::Lazy;
 //!
 //! fn main() {
@@ -107,17 +103,19 @@
 //! }
 //! ```
 //!
-//! If you need a lazy field in a struct, you probably should use `OnceCell`
+//! If you need a lazy field in a struct, you probably should use `Once`
 //! directly, because that will allow you to access `self` during initialization.
 //!
 //! ```rust
+//! #![feature(once_cell)]
+//!
 //! use std::{fs, path::PathBuf};
 //!
-//! use std::lazy::OnceCell;
+//! use std::lazy::Once;
 //!
 //! struct Ctx {
 //!     config_path: PathBuf,
-//!     config: OnceCell<String>,
+//!     config: Once<String>,
 //! }
 //!
 //! impl Ctx {
@@ -132,14 +130,14 @@
 //!
 //! ## Building block
 //!
-//! Naturally, it is  possible to build other abstractions on top of `OnceCell`.
+//! Naturally, it is  possible to build other abstractions on top of `Once`.
 //! For example, this is a `regex!` macro which takes a string literal and returns an
 //! *expression* that evaluates to a `&'static Regex`:
 //!
 //! ```
 //! macro_rules! regex {
 //!     ($re:literal $(,)?) => {{
-//!         static RE: std::lazy::SyncOnceCell<regex::Regex> = std::lazy::SyncOnceCell::new();
+//!         static RE: std::lazy::Once<regex::Regex> = std::lazy::Once::new();
 //!         RE.get_or_init(|| regex::Regex::new($re).unwrap())
 //!     }};
 //! }
@@ -147,19 +145,21 @@
 //!
 //! This macro can be useful to avoid "compile regex on every loop iteration" problem.
 //!
-//! # Comparison with other interior mutatbility types
+//! # Comparison with other interior mutability types
 //!
 //! |`!Sync` types         | Access Mode            | Drawbacks                                     |
 //! |----------------------|------------------------|-----------------------------------------------|
 //! |`Cell<T>`             | `T`                    | requires `T: Copy` for `get`                  |
 //! |`RefCell<T>`          | `RefMut<T>` / `Ref<T>` | may panic at runtime                          |
 //! |`OnceCell<T>`         | `&T`                   | assignable only once                          |
+//! |`LazyCell<T, F>`      | `&T`                   | assignable only once                          |
 //!
 //! |`Sync` types          | Access Mode            | Drawbacks                                     |
 //! |----------------------|------------------------|-----------------------------------------------|
 //! |`AtomicT`             | `T`                    | works only with certain `Copy` types          |
 //! |`Mutex<T>`            | `MutexGuard<T>`        | may deadlock at runtime, may block the thread |
-//! |`SyncOnceCell<T>`     | `&T`                   | assignable only once, may block the thread    |
+//! |`Once<T>`             | `&T`                   | assignable only once, may block the thread    |
+//! |`Lazy<T, F>`          | `&T`                   | assignable only once, may block the thread    |
 //!
 //! Technically, calling `get_or_init` will also cause a panic or a deadlock if it recursively calls
 //! itself. However, because the assignment can happen only once, such cases should be more rare than
@@ -168,326 +168,14 @@
 use crate::{
     cell::{Cell, UnsafeCell},
     fmt,
-    hint::unreachable_unchecked,
     marker::PhantomData,
+    mem::MaybeUninit,
     ops::Deref,
     panic::{RefUnwindSafe, UnwindSafe},
     sync::atomic::{AtomicBool, AtomicUsize, Ordering},
     thread::{self, Thread},
 };
 
-/// A cell which can be written to only once. Not thread safe.
-///
-/// Unlike `:td::cell::RefCell`, a `OnceCell` provides simple `&`
-/// references to the contents.
-///
-/// # Example
-/// ```
-/// use std::lazy::OnceCell;
-///
-/// let cell = OnceCell::new();
-/// assert!(cell.get().is_none());
-///
-/// let value: &String = cell.get_or_init(|| {
-///     "Hello, World!".to_string()
-/// });
-/// assert_eq!(value, "Hello, World!");
-/// assert!(cell.get().is_some());
-/// ```
-pub struct OnceCell<T> {
-    // Invariant: written to at most once.
-    inner: UnsafeCell<Option<T>>,
-}
-
-// Similarly to a `Sync` bound on `SyncOnceCell`, we can use
-// `&OnceCell` to sneak a `T` through `catch_unwind`,
-// by initializing the cell in closure and extracting the value in the
-// `Drop`.
-#[cfg(feature = "std")]
-impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceCell<T> {}
-#[cfg(feature = "std")]
-impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
-
-impl<T> Default for OnceCell<T> {
-    fn default() -> Self {
-        Self::new()
-    }
-}
-
-impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.get() {
-            Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
-            None => f.write_str("OnceCell(Uninit)"),
-        }
-    }
-}
-
-impl<T: Clone> Clone for OnceCell<T> {
-    fn clone(&self) -> OnceCell<T> {
-        let res = OnceCell::new();
-        if let Some(value) = self.get() {
-            match res.set(value.clone()) {
-                Ok(()) => (),
-                Err(_) => unreachable!(),
-            }
-        }
-        res
-    }
-}
-
-impl<T: PartialEq> PartialEq for OnceCell<T> {
-    fn eq(&self, other: &Self) -> bool {
-        self.get() == other.get()
-    }
-}
-
-impl<T: Eq> Eq for OnceCell<T> {}
-
-impl<T> From<T> for OnceCell<T> {
-    fn from(value: T) -> Self {
-        OnceCell { inner: UnsafeCell::new(Some(value)) }
-    }
-}
-
-impl<T> OnceCell<T> {
-    /// Creates a new empty cell.
-    pub const fn new() -> OnceCell<T> {
-        OnceCell { inner: UnsafeCell::new(None) }
-    }
-
-    /// Gets the reference to the underlying value.
-    ///
-    /// Returns `None` if the cell is empty.
-    pub fn get(&self) -> Option<&T> {
-        // Safe due to `inner`'s invariant
-        unsafe { &*self.inner.get() }.as_ref()
-    }
-
-    /// Gets the mutable reference to the underlying value.
-    ///
-    /// Returns `None` if the cell is empty.
-    pub fn get_mut(&mut self) -> Option<&mut T> {
-        // Safe because we have unique access
-        unsafe { &mut *self.inner.get() }.as_mut()
-    }
-
-    /// Sets the contents of this cell to `value`.
-    ///
-    /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
-    /// full.
-    ///
-    /// # Example
-    /// ```
-    /// use std::lazy::OnceCell;
-    ///
-    /// let cell = OnceCell::new();
-    /// assert!(cell.get().is_none());
-    ///
-    /// assert_eq!(cell.set(92), Ok(()));
-    /// assert_eq!(cell.set(62), Err(62));
-    ///
-    /// assert!(cell.get().is_some());
-    /// ```
-    pub fn set(&self, value: T) -> Result<(), T> {
-        let slot = unsafe { &*self.inner.get() };
-        if slot.is_some() {
-            return Err(value);
-        }
-        let slot = unsafe { &mut *self.inner.get() };
-        // This is the only place where we set the slot, no races
-        // due to reentrancy/concurrency are possible, and we've
-        // checked that slot is currently `None`, so this write
-        // maintains the `inner`'s invariant.
-        *slot = Some(value);
-        Ok(())
-    }
-
-    /// Gets the contents of the cell, initializing it with `f`
-    /// if the cell was empty.
-    ///
-    /// # 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`. Doing
-    /// so results in a panic.
-    ///
-    /// # Example
-    /// ```
-    /// use std::lazy::OnceCell;
-    ///
-    /// let cell = OnceCell::new();
-    /// let value = cell.get_or_init(|| 92);
-    /// assert_eq!(value, &92);
-    /// let value = cell.get_or_init(|| unreachable!());
-    /// assert_eq!(value, &92);
-    /// ```
-    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`. Doing
-    /// so results in a panic.
-    ///
-    /// # Example
-    /// ```
-    /// use std::lazy::OnceCell;
-    ///
-    /// let cell = OnceCell::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))
-    /// ```
-    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
-    where
-        F: FnOnce() -> Result<T, E>,
-    {
-        if let Some(val) = self.get() {
-            return Ok(val);
-        }
-        let val = f()?;
-        // Note that *some* forms of reentrant initialization might lead to
-        // UB (see `reentrant_init` test). I believe that just removing this
-        // `assert`, while keeping `set/get` would be sound, but it seems
-        // better to panic, rather than to silently use an old value.
-        assert!(self.set(val).is_ok(), "reentrant init");
-        Ok(self.get().unwrap())
-    }
-
-    /// Consumes the `OnceCell`, returning the wrapped value.
-    ///
-    /// Returns `None` if the cell was empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::lazy::OnceCell;
-    ///
-    /// let cell: OnceCell<String> = OnceCell::new();
-    /// assert_eq!(cell.into_inner(), None);
-    ///
-    /// let cell = OnceCell::new();
-    /// cell.set("hello".to_string()).unwrap();
-    /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
-    /// ```
-    pub fn into_inner(self) -> Option<T> {
-        // Because `into_inner` takes `self` by value, the compiler statically verifies
-        // that it is not currently borrowed. So it is safe to move out `Option<T>`.
-        self.inner.into_inner()
-    }
-}
-
-/// A value which is initialized on the first access.
-///
-/// # Example
-/// ```
-/// use std::lazy::Lazy;
-///
-/// let lazy: Lazy<i32> = Lazy::new(|| {
-///     println!("initializing");
-///     92
-/// });
-/// println!("ready");
-/// println!("{}", *lazy);
-/// println!("{}", *lazy);
-///
-/// // Prints:
-/// //   ready
-/// //   initializing
-/// //   92
-/// //   92
-/// ```
-pub struct Lazy<T, F = fn() -> T> {
-    cell: OnceCell<T>,
-    init: Cell<Option<F>>,
-}
-
-#[cfg(feature = "std")]
-impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where OnceCell<T>: RefUnwindSafe {}
-
-impl<T: fmt::Debug, F: fmt::Debug> fmt::Debug for Lazy<T, F> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
-    }
-}
-
-impl<T, F> Lazy<T, F> {
-    /// Creates a new lazy value with the given initializing function.
-    ///
-    /// # Example
-    /// ```
-    /// # fn main() {
-    /// use std::lazy::Lazy;
-    ///
-    /// let hello = "Hello, World!".to_string();
-    ///
-    /// let lazy = Lazy::new(|| hello.to_uppercase());
-    ///
-    /// assert_eq!(&*lazy, "HELLO, WORLD!");
-    /// # }
-    /// ```
-    pub const fn new(init: F) -> Lazy<T, F> {
-        Lazy { cell: OnceCell::new(), init: Cell::new(Some(init)) }
-    }
-}
-
-impl<T, F: FnOnce() -> T> Lazy<T, F> {
-    /// Forces the evaluation of this lazy value and returns a reference to
-    /// the result.
-    ///
-    /// This is equivalent to the `Deref` impl, but is explicit.
-    ///
-    /// # Example
-    /// ```
-    /// use std::lazy::Lazy;
-    ///
-    /// let lazy = Lazy::new(|| 92);
-    ///
-    /// assert_eq!(Lazy::force(&lazy), &92);
-    /// assert_eq!(&*lazy, &92);
-    /// ```
-    pub fn force(this: &Lazy<T, F>) -> &T {
-        this.cell.get_or_init(|| match this.init.take() {
-            Some(f) => f(),
-            None => panic!("Lazy instance has previously been poisoned"),
-        })
-    }
-}
-
-impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
-    type Target = T;
-    fn deref(&self) -> &T {
-        Lazy::force(self)
-    }
-}
-
-impl<T: Default> Default for Lazy<T> {
-    /// Creates a new lazy value using `Default` as the initializing function.
-    fn default() -> Lazy<T> {
-        Lazy::new(T::default)
-    }
-}
-
 /// A thread-safe cell which can be written to only once.
 ///
 /// `OnceCell` provides `&` references to the contents without RAII guards.
@@ -498,9 +186,12 @@ impl<T: Default> Default for Lazy<T> {
 /// subsequently reads the result of this call, B also observes all the side
 /// effects of `f`.
 ///
-/// # Example
+/// # Examples
+///
 /// ```
-/// use std::lazy::SyncOnceCell;
+/// #![feature(once_cell)]
+///
+/// use std::lazy::Once;
 ///
 /// static CELL: OnceCell<String> = OnceCell::new();
 /// assert!(CELL.get().is_none());
@@ -516,16 +207,14 @@ impl<T: Default> Default for Lazy<T> {
 /// assert!(value.is_some());
 /// assert_eq!(value.unwrap().as_str(), "Hello, World!");
 /// ```
-pub struct SyncOnceCell<T> {
+#[unstable(feature = "once_cell", issue = "68198")]
+pub struct Once<T> {
     // This `state` word is actually an encoded version of just a pointer to a
     // `Waiter`, so we add the `PhantomData` appropriately.
     state_and_queue: AtomicUsize,
     _marker: PhantomData<*mut Waiter>,
-    // FIXME: switch to `std::mem::MaybeUninit` once we are ready to bump MSRV
-    // that far. It was stabilized in 1.36.0, so, if you are reading this and
-    // it's higher than 1.46.0 outside, please send a PR! ;) (and do the same
-    // for `Lazy`, while we are at it).
-    pub(crate) value: UnsafeCell<Option<T>>,
+    // Whether or not the value is initialized is tracked by `state_and_queue`.
+    value: UnsafeCell<MaybeUninit<T>>,
 }
 
 // Why do we need `T: Send`?
@@ -533,30 +222,37 @@ pub struct SyncOnceCell<T> {
 // scoped thread B, which fills the cell, which is
 // then destroyed by A. That is, destructor observes
 // a sent value.
-unsafe impl<T: Sync + Send> Sync for SyncOnceCell<T> {}
-unsafe impl<T: Send> Send for SyncOnceCell<T> {}
+#[unstable(feature = "once_cell", issue = "68198")]
+unsafe impl<T: Sync + Send> Sync for Once<T> {}
+#[unstable(feature = "once_cell", issue = "68198")]
+unsafe impl<T: Send> Send for Once<T> {}
 
-impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
-impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for Once<T> {}
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: UnwindSafe> UnwindSafe for Once<T> {}
 
-impl<T> Default for SyncOnceCell<T> {
-    fn default() -> SyncOnceCell<T> {
-        SyncOnceCell::new()
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T> Default for Once<T> {
+    fn default() -> Once<T> {
+        Once::new()
     }
 }
 
-impl<T: fmt::Debug> fmt::Debug for SyncOnceCell<T> {
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: fmt::Debug> fmt::Debug for Once<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self.get() {
-            Some(v) => f.debug_tuple("SyncOnceCell").field(v).finish(),
-            None => f.write_str("SyncOnceCell(Uninit)"),
+            Some(v) => f.debug_tuple("Once").field(v).finish(),
+            None => f.write_str("Once(Uninit)"),
         }
     }
 }
 
-impl<T: Clone> Clone for SyncOnceCell<T> {
-    fn clone(&self) -> SyncOnceCell<T> {
-        let res = SyncOnceCell::new();
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: Clone> Clone for Once<T> {
+    fn clone(&self) -> Once<T> {
+        let res = Once::new();
         if let Some(value) = self.get() {
             match res.set(value.clone()) {
                 Ok(()) => (),
@@ -567,7 +263,8 @@ impl<T: Clone> Clone for SyncOnceCell<T> {
     }
 }
 
-impl<T> From<T> for SyncOnceCell<T> {
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T> From<T> for Once<T> {
     fn from(value: T) -> Self {
         let cell = Self::new();
         cell.get_or_init(|| value);
@@ -575,21 +272,24 @@ impl<T> From<T> for SyncOnceCell<T> {
     }
 }
 
-impl<T: PartialEq> PartialEq for SyncOnceCell<T> {
-    fn eq(&self, other: &SyncOnceCell<T>) -> bool {
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: PartialEq> PartialEq for Once<T> {
+    fn eq(&self, other: &Once<T>) -> bool {
         self.get() == other.get()
     }
 }
 
-impl<T: Eq> Eq for SyncOnceCell<T> {}
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: Eq> Eq for Once<T> {}
 
-impl<T> SyncOnceCell<T> {
+impl<T> Once<T> {
     /// Creates a new empty cell.
-    pub const fn new() -> SyncOnceCell<T> {
-        SyncOnceCell {
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub const fn new() -> Once<T> {
+        Once {
             state_and_queue: AtomicUsize::new(INCOMPLETE),
             _marker: PhantomData,
-            value: UnsafeCell::new(None),
+            value: UnsafeCell::new(MaybeUninit::uninit()),
         }
     }
 
@@ -597,6 +297,7 @@ impl<T> SyncOnceCell<T> {
     ///
     /// Returns `None` if the cell is empty, or being initialized. This
     /// method never blocks.
+    #[unstable(feature = "once_cell", issue = "68198")]
     pub fn get(&self) -> Option<&T> {
         if self.is_initialized() {
             // Safe b/c checked is_initialize
@@ -609,9 +310,14 @@ impl<T> SyncOnceCell<T> {
     /// Gets the mutable reference to the underlying value.
     ///
     /// Returns `None` if the cell is empty.
+    #[unstable(feature = "once_cell", issue = "68198")]
     pub fn get_mut(&mut self) -> Option<&mut T> {
-        // Safe b/c we have a unique access.
-        unsafe { &mut *self.value.get() }.as_mut()
+        if self.is_initialized() {
+            // Safe b/c checked is_initialize and we have a unique access
+            Some(unsafe { self.get_unchecked_mut() })
+        } else {
+            None
+        }
     }
 
     /// Get the reference to the underlying value, without checking if the
@@ -621,17 +327,23 @@ impl<T> SyncOnceCell<T> {
     ///
     /// Caller must ensure that the cell is in initialized state, and that
     /// the contents are acquired by (synchronized to) this thread.
+    #[unstable(feature = "once_cell", issue = "68198")]
     pub unsafe fn get_unchecked(&self) -> &T {
         debug_assert!(self.is_initialized());
-        let slot: &Option<T> = &*self.value.get();
-        match slot {
-            Some(value) => value,
-            // This unsafe does improve performance, see `examples/bench`.
-            None => {
-                debug_assert!(false);
-                unreachable_unchecked()
-            }
-        }
+        (&*self.value.get()).get_ref()
+    }
+
+    /// Get the reference to the underlying value, without checking if the
+    /// cell is initialized.
+    ///
+    /// Safety:
+    ///
+    /// Caller must ensure that the cell is in initialized state, and that
+    /// the contents are acquired by (synchronized to) this thread.
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub unsafe fn get_unchecked_mut(&mut self) -> &mut T {
+        debug_assert!(self.is_initialized());
+        (&mut *self.value.get()).get_mut()
     }
 
     /// Sets the contents of this cell to `value`.
@@ -639,11 +351,14 @@ impl<T> SyncOnceCell<T> {
     /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
     /// full.
     ///
-    /// # Example
+    /// # Examples
+    ///
     /// ```
-    /// use std::lazy::SyncOnceCell;
+    /// #![feature(once_cell)]
     ///
-    /// static CELL: SyncOnceCell<i32> = SyncOnceCell::new();
+    /// use std::lazy::Once;
+    ///
+    /// static CELL: Once<i32> = Once::new();
     ///
     /// fn main() {
     ///     assert!(CELL.get().is_none());
@@ -656,6 +371,7 @@ impl<T> SyncOnceCell<T> {
     ///     assert_eq!(CELL.get(), Some(&92));
     /// }
     /// ```
+    #[unstable(feature = "once_cell", issue = "68198")]
     pub fn set(&self, value: T) -> Result<(), T> {
         let mut value = Some(value);
         self.get_or_init(|| value.take().unwrap());
@@ -681,16 +397,20 @@ impl<T> SyncOnceCell<T> {
     /// exact outcome is unspecified. Current implementation deadlocks, but
     /// this may be changed to a panic in the future.
     ///
-    /// # Example
+    /// # Examples
+    ///
     /// ```
-    /// use std::lazy::SyncOnceCell;
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::Once;
     ///
-    /// let cell = SyncOnceCell::new();
+    /// let cell = Once::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 = "68198")]
     pub fn get_or_init<F>(&self, f: F) -> &T
     where
         F: FnOnce() -> T,
@@ -713,11 +433,14 @@ impl<T> SyncOnceCell<T> {
     /// The exact outcome is unspecified. Current implementation
     /// deadlocks, but this may be changed to a panic in the future.
     ///
-    /// # Example
+    /// # Examples
+    ///
     /// ```
-    /// use std::lazy::SyncOnceCell;
+    /// #![feature(once_cell)]
     ///
-    /// let cell = SyncOnceCell::new();
+    /// use std::lazy::Once;
+    ///
+    /// let cell = Once::new();
     /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
     /// assert!(cell.get().is_none());
     /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
@@ -726,6 +449,7 @@ impl<T> SyncOnceCell<T> {
     /// assert_eq!(value, Ok(&92));
     /// assert_eq!(cell.get(), Some(&92))
     /// ```
+    #[unstable(feature = "once_cell", issue = "68198")]
     pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
     where
         F: FnOnce() -> Result<T, E>,
@@ -741,25 +465,33 @@ impl<T> SyncOnceCell<T> {
         Ok(unsafe { self.get_unchecked() })
     }
 
-    /// Consumes the `SyncOnceCell`, returning the wrapped value. Returns
+    /// Consumes the `Once`, returning the wrapped value. Returns
     /// `None` if the cell was empty.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::lazy::SyncOnceCell;
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::Once;
     ///
-    /// let cell: SyncOnceCell<String> = SyncOnceCell::new();
+    /// let cell: Once<String> = Once::new();
     /// assert_eq!(cell.into_inner(), None);
     ///
-    /// let cell = SyncOnceCell::new();
+    /// let cell = Once::new();
     /// cell.set("hello".to_string()).unwrap();
     /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
     /// ```
+    #[unstable(feature = "once_cell", issue = "68198")]
     pub fn into_inner(self) -> Option<T> {
         // Because `into_inner` takes `self` by value, the compiler statically verifies
         // that it is not currently borrowed. So it is safe to move out `Option<T>`.
-        self.value.into_inner()
+        if self.is_initialized() {
+            // Safe b/c called initialize
+            return Some(unsafe { self.value.into_inner().assume_init() });
+        }
+
+        None
     }
 
     /// Safety: synchronizes with store to value via Release/(Acquire|SeqCst).
@@ -787,7 +519,7 @@ impl<T> SyncOnceCell<T> {
             let f = f.take().unwrap();
             match f() {
                 Ok(value) => {
-                    unsafe { *slot.get() = Some(value) };
+                    unsafe { (&mut *slot.get()).write(value) };
                     true
                 }
                 Err(e) => {
@@ -800,16 +532,16 @@ impl<T> SyncOnceCell<T> {
     }
 }
 
-// region: copy-paste
-// The following code is copied from `sync::Once`.
+// FIXME: The following code is copied from `sync::Once`.
 // This should be uncopypasted once we decide the right way to handle panics.
+// Do we want to effectively move the `Once` synchronization here and make `Once`
+// a newtype: `pub struct Once(lazy::Once<()>)`?
 const INCOMPLETE: usize = 0x0;
 const RUNNING: usize = 0x1;
 const COMPLETE: usize = 0x2;
 
 const STATE_MASK: usize = 0x3;
 
-
 #[repr(align(4))]
 struct Waiter {
     thread: Cell<Option<Thread>>,
@@ -901,14 +633,16 @@ fn wait(state_and_queue: &AtomicUsize, mut current_state: usize) {
         break;
     }
 }
-// endregion: copy-paste
 
 /// A value which is initialized on the first access.
 ///
 /// This type is thread-safe and can be used in statics:
 ///
-/// # Example
+/// # Examples
+///
 /// ```
+/// #![feature(once_cell)]
+///
 /// use std::collections::HashMap;
 ///
 /// use std::lazy::Lazy;
@@ -935,68 +669,78 @@ fn wait(state_and_queue: &AtomicUsize, mut current_state: usize) {
 ///     //   Some("Hoyten")
 /// }
 /// ```
-pub struct SyncLazy<T, F = fn() -> T> {
-    cell: SyncOnceCell<T>,
+#[unstable(feature = "once_cell", issue = "68198")]
+pub struct Lazy<T, F = fn() -> T> {
+    cell: Once<T>,
     init: Cell<Option<F>>,
 }
 
-impl<T: fmt::Debug, F: fmt::Debug> fmt::Debug for SyncLazy<T, F> {
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: fmt::Debug, F: fmt::Debug> fmt::Debug for Lazy<T, F> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("SyncLazy").field("cell", &self.cell).field("init", &"..").finish()
+        f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
     }
 }
 
-// We never create a `&F` from a `&SyncLazy<T, F>` so it is fine
+// We never create a `&F` from a `&Lazy<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.
-unsafe impl<T, F: Send> Sync for SyncLazy<T, F> where SyncOnceCell<T>: Sync {}
+#[unstable(feature = "once_cell", issue = "68198")]
+unsafe impl<T, F: Send> Sync for Lazy<T, F> where Once<T>: Sync {}
 // auto-derived `Send` impl is OK.
 
-#[cfg(feature = "std")]
-impl<T, F: RefUnwindSafe> RefUnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: RefUnwindSafe {}
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where Once<T>: RefUnwindSafe {}
 
-impl<T, F> SyncLazy<T, F> {
+impl<T, F> Lazy<T, F> {
     /// Creates a new lazy value with the given initializing
     /// function.
-    pub const fn new(f: F) -> SyncLazy<T, F> {
-        SyncLazy { cell: SyncOnceCell::new(), init: Cell::new(Some(f)) }
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub const fn new(f: F) -> Lazy<T, F> {
+        Lazy { cell: Once::new(), init: Cell::new(Some(f)) }
     }
 }
 
-impl<T, F: FnOnce() -> T> SyncLazy<T, F> {
+impl<T, F: FnOnce() -> T> Lazy<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.
     ///
-    /// # Example
+    /// # Examples
+    ///
     /// ```
-    /// use std::lazy::SyncLazy;
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::Lazy;
     ///
-    /// let lazy = SyncLazy::new(|| 92);
+    /// let lazy = Lazy::new(|| 92);
     ///
-    /// assert_eq!(SyncLazy::force(&lazy), &92);
+    /// assert_eq!(Lazy::force(&lazy), &92);
     /// assert_eq!(&*lazy, &92);
     /// ```
-    pub fn force(this: &SyncLazy<T, F>) -> &T {
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub fn force(this: &Lazy<T, F>) -> &T {
         this.cell.get_or_init(|| match this.init.take() {
             Some(f) => f(),
-            None => panic!("SyncLazy instance has previously been poisoned"),
+            None => panic!("Lazy instance has previously been poisoned"),
         })
     }
 }
 
-impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
     type Target = T;
     fn deref(&self) -> &T {
-        SyncLazy::force(self)
+        Lazy::force(self)
     }
 }
 
-impl<T: Default> Default for SyncLazy<T> {
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: Default> Default for Lazy<T> {
     /// Creates a new lazy value using `Default` as the initializing function.
-    fn default() -> SyncLazy<T> {
-        SyncLazy::new(T::default)
+    fn default() -> Lazy<T> {
+        Lazy::new(T::default)
     }
 }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 0720aa769238e..06a581c27da62 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -276,6 +276,7 @@
 #![feature(link_args)]
 #![feature(linkage)]
 #![feature(log_syntax)]
+#![feature(maybe_uninit_extra)]
 #![feature(maybe_uninit_ref)]
 #![feature(maybe_uninit_slice)]
 #![feature(needs_panic_runtime)]
@@ -466,10 +467,7 @@ pub mod process;
 pub mod sync;
 pub mod time;
 
-#[unstable(
-    feature = "std_lazy",
-    issue = "99",
-)]
+#[unstable(feature = "once_cell", issue = "68198")]
 pub mod lazy;
 
 #[stable(feature = "futures_api", since = "1.36.0")]
diff --git a/src/stdsimd b/src/stdsimd
new file mode 160000
index 0000000000000..4bf456c35e85f
--- /dev/null
+++ b/src/stdsimd
@@ -0,0 +1 @@
+Subproject commit 4bf456c35e85fcca5cf95008401af8ab25abf850

From 91c9d1c21ea2a8db64cbc026c5b315f2f7027751 Mon Sep 17 00:00:00 2001
From: Ashley Mannix <ashleymannix@live.com.au>
Date: Wed, 15 Jan 2020 07:24:55 +1000
Subject: [PATCH 3/6] correctly impl Drop for lazy::Once

---
 src/libstd/lazy.rs | 96 ++++++++++++++++++++++++----------------------
 1 file changed, 50 insertions(+), 46 deletions(-)

diff --git a/src/libstd/lazy.rs b/src/libstd/lazy.rs
index 11b5e5d40a10d..f8c8f86cf0b05 100644
--- a/src/libstd/lazy.rs
+++ b/src/libstd/lazy.rs
@@ -169,22 +169,16 @@ use crate::{
     cell::{Cell, UnsafeCell},
     fmt,
     marker::PhantomData,
-    mem::MaybeUninit,
-    ops::Deref,
+    mem::{self, MaybeUninit},
+    ops::{Deref, Drop},
     panic::{RefUnwindSafe, UnwindSafe},
     sync::atomic::{AtomicBool, AtomicUsize, Ordering},
     thread::{self, Thread},
 };
 
-/// A thread-safe cell which can be written to only once.
+/// A synchronization primitive which can be written to only once.
 ///
-/// `OnceCell` provides `&` references to the contents without RAII guards.
-///
-/// Reading a non-`None` value out of `OnceCell` establishes a
-/// happens-before relationship with a corresponding write. For example, if
-/// thread A initializes the cell with `get_or_init(f)`, and thread B
-/// subsequently reads the result of this call, B also observes all the side
-/// effects of `f`.
+/// This type is a thread-safe `OnceCell`.
 ///
 /// # Examples
 ///
@@ -193,7 +187,7 @@ use crate::{
 ///
 /// use std::lazy::Once;
 ///
-/// static CELL: OnceCell<String> = OnceCell::new();
+/// static CELL: Once<String> = Once::new();
 /// assert!(CELL.get().is_none());
 ///
 /// std::thread::spawn(|| {
@@ -218,7 +212,7 @@ pub struct Once<T> {
 }
 
 // Why do we need `T: Send`?
-// Thread A creates a `OnceCell` and shares it with
+// Thread A creates a `Once` and shares it with
 // scoped thread B, which fills the cell, which is
 // then destroyed by A. That is, destructor observes
 // a sent value.
@@ -320,32 +314,6 @@ impl<T> Once<T> {
         }
     }
 
-    /// Get the reference to the underlying value, without checking if the
-    /// cell is initialized.
-    ///
-    /// Safety:
-    ///
-    /// Caller must ensure that the cell is in initialized state, and that
-    /// the contents are acquired by (synchronized to) this thread.
-    #[unstable(feature = "once_cell", issue = "68198")]
-    pub unsafe fn get_unchecked(&self) -> &T {
-        debug_assert!(self.is_initialized());
-        (&*self.value.get()).get_ref()
-    }
-
-    /// Get the reference to the underlying value, without checking if the
-    /// cell is initialized.
-    ///
-    /// Safety:
-    ///
-    /// Caller must ensure that the cell is in initialized state, and that
-    /// the contents are acquired by (synchronized to) this thread.
-    #[unstable(feature = "once_cell", issue = "68198")]
-    pub unsafe fn get_unchecked_mut(&mut self) -> &mut T {
-        debug_assert!(self.is_initialized());
-        (&mut *self.value.get()).get_mut()
-    }
-
     /// Sets the contents of this cell to `value`.
     ///
     /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
@@ -483,15 +451,32 @@ impl<T> Once<T> {
     /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
     /// ```
     #[unstable(feature = "once_cell", issue = "68198")]
-    pub fn into_inner(self) -> Option<T> {
-        // Because `into_inner` takes `self` by value, the compiler statically verifies
-        // that it is not currently borrowed. So it is safe to move out `Option<T>`.
+    pub fn into_inner(mut self) -> Option<T> {
+        // Safety: Safe because we immediately free `self` without dropping
+        let inner = unsafe { self.take_inner() };
+
+        // Don't drop this `Once`. We just moved out one of the fields, but didn't set
+        // the state to uninitialized.
+        mem::ManuallyDrop::new(self);
+        inner
+    }
+
+    /// Takes the wrapped value out of a `Once`.
+    /// Afterwards the cell is no longer initialized.
+    ///
+    /// Safety: The cell must now be free'd WITHOUT dropping. No other usages of the cell
+    /// are valid. Only used by `into_inner` and `drop`.
+    unsafe fn take_inner(&mut self) -> Option<T> {
+        // The mutable reference guarantees there are no other threads that can observe us
+        // taking out the wrapped value.
+        // Right after this function `self` is supposed to be freed, so it makes little sense
+        // to atomically set the state to uninitialized.
         if self.is_initialized() {
-            // Safe b/c called initialize
-            return Some(unsafe { self.value.into_inner().assume_init() });
+            let value = mem::replace(&mut self.value, UnsafeCell::new(MaybeUninit::uninit()));
+            Some(value.into_inner().assume_init())
+        } else {
+            None
         }
-
-        None
     }
 
     /// Safety: synchronizes with store to value via Release/(Acquire|SeqCst).
@@ -530,6 +515,25 @@ impl<T> Once<T> {
         });
         res
     }
+
+    /// Safety: The value must be initialized
+    unsafe fn get_unchecked(&self) -> &T {
+        debug_assert!(self.is_initialized());
+        (&*self.value.get()).get_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()).get_mut()
+    }
+}
+
+impl<T> Drop for Once<T> {
+    fn drop(&mut self) {
+        // Safety: The cell is being dropped, so it can't be accessed again
+        unsafe { self.take_inner() };
+    }
 }
 
 // FIXME: The following code is copied from `sync::Once`.
@@ -636,7 +640,7 @@ fn wait(state_and_queue: &AtomicUsize, mut current_state: usize) {
 
 /// A value which is initialized on the first access.
 ///
-/// This type is thread-safe and can be used in statics:
+/// This type is a thread-safe `LazyCell`, and can be used in statics.
 ///
 /// # Examples
 ///

From 0f7f3de14d9a399b7da2e78c0c6758a0aad7cbd2 Mon Sep 17 00:00:00 2001
From: Ashley Mannix <ashleymannix@live.com.au>
Date: Wed, 15 Jan 2020 16:37:51 +1000
Subject: [PATCH 4/6] move unsync OnceCell and Lazy into lazy module

---
 src/libcore/cell.rs | 351 -------------------------------------------
 src/libcore/lazy.rs | 352 ++++++++++++++++++++++++++++++++++++++++++++
 src/libcore/lib.rs  |   2 +
 src/libstd/lazy.rs  | 277 ++++++++--------------------------
 src/libstd/lib.rs   |   1 +
 5 files changed, 413 insertions(+), 570 deletions(-)
 create mode 100644 src/libcore/lazy.rs

diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 45b5c5b7fd77e..feda37e329278 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -44,12 +44,6 @@
 //! to borrow a value that is already mutably borrowed; when this happens it results in thread
 //! panic.
 //!
-//! `OnceCell<T>` allows one to access a value by also providing an initialization function for it.
-//! If the `OnceCell<T>` already contains an initialized value then it is returned, otherwise the
-//! initialization function is run and the result is stored in the cell.
-//! `LazyCell<T, F>` is similar to `OnceCell<T>`, but keeps its initialization function as part of
-//! the type, so it doesn't need to be provided whenever the cell is accessed.
-//!
 //! # When to choose interior mutability
 //!
 //! The more common inherited mutability, where one must have unique access to mutate a value, is
@@ -1421,351 +1415,6 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
     }
 }
 
-/// A cell which can be written to only once.
-///
-/// Unlike `RefCell`, a `OnceCell` only provides shared `&T` references to its value.
-/// Unlike `Cell`, a `OnceCell` doesn't require `T: Copy` to access its value.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(once_cell)]
-///
-/// use std::cell::OnceCell;
-///
-/// let cell = OnceCell::new();
-/// assert!(cell.get().is_none());
-///
-/// let value: &String = cell.get_or_init(|| {
-///     "Hello, World!".to_string()
-/// });
-/// assert_eq!(value, "Hello, World!");
-/// assert!(cell.get().is_some());
-/// ```
-#[unstable(feature = "once_cell", issue = "68198")]
-pub struct OnceCell<T> {
-    // Invariant: written to at most once.
-    inner: UnsafeCell<Option<T>>,
-}
-
-#[unstable(feature = "once_cell", issue = "68198")]
-impl<T> Default for OnceCell<T> {
-    fn default() -> Self {
-        Self::new()
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "68198")]
-impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.get() {
-            Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
-            None => f.write_str("OnceCell(Uninit)"),
-        }
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "68198")]
-impl<T: Clone> Clone for OnceCell<T> {
-    fn clone(&self) -> OnceCell<T> {
-        let res = OnceCell::new();
-        if let Some(value) = self.get() {
-            match res.set(value.clone()) {
-                Ok(()) => (),
-                Err(_) => unreachable!(),
-            }
-        }
-        res
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "68198")]
-impl<T: PartialEq> PartialEq for OnceCell<T> {
-    fn eq(&self, other: &Self) -> bool {
-        self.get() == other.get()
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "68198")]
-impl<T: Eq> Eq for OnceCell<T> {}
-
-#[unstable(feature = "once_cell", issue = "68198")]
-impl<T> From<T> for OnceCell<T> {
-    fn from(value: T) -> Self {
-        OnceCell { inner: UnsafeCell::new(Some(value)) }
-    }
-}
-
-impl<T> OnceCell<T> {
-    /// Creates a new empty cell.
-    #[unstable(feature = "once_cell", issue = "68198")]
-    pub const fn new() -> OnceCell<T> {
-        OnceCell { inner: UnsafeCell::new(None) }
-    }
-
-    /// Gets the reference to the underlying value.
-    ///
-    /// Returns `None` if the cell is empty.
-    #[unstable(feature = "once_cell", issue = "68198")]
-    pub fn get(&self) -> Option<&T> {
-        // Safe due to `inner`'s invariant
-        unsafe { &*self.inner.get() }.as_ref()
-    }
-
-    /// Gets the mutable reference to the underlying value.
-    ///
-    /// Returns `None` if the cell is empty.
-    #[unstable(feature = "once_cell", issue = "68198")]
-    pub fn get_mut(&mut self) -> Option<&mut T> {
-        // Safe because we have unique access
-        unsafe { &mut *self.inner.get() }.as_mut()
-    }
-
-    /// Sets the contents of the cell to `value`.
-    ///
-    /// # Errors
-    ///
-    /// This method returns `Ok(())` if the cell was empty and `Err(value)` if
-    /// it was full.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::cell::OnceCell;
-    ///
-    /// let cell = OnceCell::new();
-    /// assert!(cell.get().is_none());
-    ///
-    /// assert_eq!(cell.set(92), Ok(()));
-    /// assert_eq!(cell.set(62), Err(62));
-    ///
-    /// assert!(cell.get().is_some());
-    /// ```
-    #[unstable(feature = "once_cell", issue = "68198")]
-    pub fn set(&self, value: T) -> Result<(), T> {
-        let slot = unsafe { &*self.inner.get() };
-        if slot.is_some() {
-            return Err(value);
-        }
-        let slot = unsafe { &mut *self.inner.get() };
-        // This is the only place where we set the slot, no races
-        // due to reentrancy/concurrency are possible, and we've
-        // checked that slot is currently `None`, so this write
-        // maintains the `inner`'s invariant.
-        *slot = Some(value);
-        Ok(())
-    }
-
-    /// Gets the contents of the cell, initializing it with `f`
-    /// if the cell was empty.
-    ///
-    /// # 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`. Doing
-    /// so results in a panic.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::cell::OnceCell;
-    ///
-    /// let cell = OnceCell::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 = "68198")]
-    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`. Doing
-    /// so results in a panic.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::cell::OnceCell;
-    ///
-    /// let cell = OnceCell::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 = "68198")]
-    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
-    where
-        F: FnOnce() -> Result<T, E>,
-    {
-        if let Some(val) = self.get() {
-            return Ok(val);
-        }
-        let val = f()?;
-        // Note that *some* forms of reentrant initialization might lead to
-        // UB (see `reentrant_init` test). I believe that just removing this
-        // `assert`, while keeping `set/get` would be sound, but it seems
-        // better to panic, rather than to silently use an old value.
-        assert!(self.set(val).is_ok(), "reentrant init");
-        Ok(self.get().unwrap())
-    }
-
-    /// Consumes the cell, returning the wrapped value.
-    ///
-    /// Returns `None` if the cell was empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::cell::OnceCell;
-    ///
-    /// let cell: OnceCell<String> = OnceCell::new();
-    /// assert_eq!(cell.into_inner(), None);
-    ///
-    /// let cell = OnceCell::new();
-    /// cell.set("hello".to_string()).unwrap();
-    /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
-    /// ```
-    #[unstable(feature = "once_cell", issue = "68198")]
-    pub fn into_inner(self) -> Option<T> {
-        // Because `into_inner` takes `self` by value, the compiler statically verifies
-        // that it is not currently borrowed. So it is safe to move out `Option<T>`.
-        self.inner.into_inner()
-    }
-}
-
-/// A value which is initialized on the first access.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(once_cell)]
-///
-/// use std::cell::LazyCell;
-///
-/// let lazy: LazyCell<i32> = LazyCell::new(|| {
-///     println!("initializing");
-///     92
-/// });
-/// println!("ready");
-/// println!("{}", *lazy);
-/// println!("{}", *lazy);
-///
-/// // Prints:
-/// //   ready
-/// //   initializing
-/// //   92
-/// //   92
-/// ```
-#[unstable(feature = "once_cell", issue = "68198")]
-pub struct LazyCell<T, F = fn() -> T> {
-    cell: OnceCell<T>,
-    init: Cell<Option<F>>,
-}
-
-#[unstable(feature = "once_cell", issue = "68198")]
-impl<T: fmt::Debug, F: fmt::Debug> fmt::Debug for LazyCell<T, F> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("LazyCell").field("cell", &self.cell).field("init", &"..").finish()
-    }
-}
-
-impl<T, F> LazyCell<T, F> {
-    /// Creates a new lazy value with the given initializing function.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// # fn main() {
-    /// use std::cell::LazyCell;
-    ///
-    /// let hello = "Hello, World!".to_string();
-    ///
-    /// let lazy = LazyCell::new(|| hello.to_uppercase());
-    ///
-    /// assert_eq!(&*lazy, "HELLO, WORLD!");
-    /// # }
-    /// ```
-    #[unstable(feature = "once_cell", issue = "68198")]
-    pub const fn new(init: F) -> LazyCell<T, F> {
-        LazyCell { cell: OnceCell::new(), init: Cell::new(Some(init)) }
-    }
-}
-
-impl<T, F: FnOnce() -> T> LazyCell<T, F> {
-    /// Forces the evaluation of this lazy value and returns a reference to
-    /// the result.
-    ///
-    /// This is equivalent to the `Deref` impl, but is explicit.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::cell::LazyCell;
-    ///
-    /// let lazy = LazyCell::new(|| 92);
-    ///
-    /// assert_eq!(LazyCell::force(&lazy), &92);
-    /// assert_eq!(&*lazy, &92);
-    /// ```
-    #[unstable(feature = "once_cell", issue = "68198")]
-    pub fn force(this: &LazyCell<T, F>) -> &T {
-        this.cell.get_or_init(|| match this.init.take() {
-            Some(f) => f(),
-            None => panic!("`LazyCell` instance has previously been poisoned"),
-        })
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "68198")]
-impl<T, F: FnOnce() -> T> Deref for LazyCell<T, F> {
-    type Target = T;
-    fn deref(&self) -> &T {
-        LazyCell::force(self)
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "68198")]
-impl<T: Default> Default for LazyCell<T> {
-    /// Creates a new lazy value using `Default` as the initializing function.
-    fn default() -> LazyCell<T> {
-        LazyCell::new(T::default)
-    }
-}
-
 /// The core primitive for interior mutability in Rust.
 ///
 /// `UnsafeCell<T>` is a type that wraps some `T` and indicates unsafe interior operations on the
diff --git a/src/libcore/lazy.rs b/src/libcore/lazy.rs
new file mode 100644
index 0000000000000..eb74faeaf11d3
--- /dev/null
+++ b/src/libcore/lazy.rs
@@ -0,0 +1,352 @@
+//! Lazy values and one-time initialization of static data.
+
+use crate::cell::{Cell, UnsafeCell};
+use crate::fmt;
+use crate::ops::Deref;
+
+/// A cell which can be written to only once.
+///
+/// Unlike `RefCell`, a `OnceCell` only provides shared `&T` references to its value.
+/// Unlike `Cell`, a `OnceCell` doesn't require `T: Copy` to access its value.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(once_cell)]
+///
+/// use std::lazy::OnceCell;
+///
+/// let cell = OnceCell::new();
+/// assert!(cell.get().is_none());
+///
+/// let value: &String = cell.get_or_init(|| {
+///     "Hello, World!".to_string()
+/// });
+/// assert_eq!(value, "Hello, World!");
+/// assert!(cell.get().is_some());
+/// ```
+#[unstable(feature = "once_cell", issue = "68198")]
+pub struct OnceCell<T> {
+    // Invariant: written to at most once.
+    inner: UnsafeCell<Option<T>>,
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T> Default for OnceCell<T> {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self.get() {
+            Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
+            None => f.write_str("OnceCell(Uninit)"),
+        }
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: Clone> Clone for OnceCell<T> {
+    fn clone(&self) -> OnceCell<T> {
+        let res = OnceCell::new();
+        if let Some(value) = self.get() {
+            match res.set(value.clone()) {
+                Ok(()) => (),
+                Err(_) => unreachable!(),
+            }
+        }
+        res
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: PartialEq> PartialEq for OnceCell<T> {
+    fn eq(&self, other: &Self) -> bool {
+        self.get() == other.get()
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: Eq> Eq for OnceCell<T> {}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T> From<T> for OnceCell<T> {
+    fn from(value: T) -> Self {
+        OnceCell { inner: UnsafeCell::new(Some(value)) }
+    }
+}
+
+impl<T> OnceCell<T> {
+    /// Creates a new empty cell.
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub const fn new() -> OnceCell<T> {
+        OnceCell { inner: UnsafeCell::new(None) }
+    }
+
+    /// Gets the reference to the underlying value.
+    ///
+    /// Returns `None` if the cell is empty.
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub fn get(&self) -> Option<&T> {
+        // Safety: Safe due to `inner`'s invariant
+        unsafe { &*self.inner.get() }.as_ref()
+    }
+
+    /// Gets the mutable reference to the underlying value.
+    ///
+    /// Returns `None` if the cell is empty.
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub fn get_mut(&mut self) -> Option<&mut T> {
+        // Safety: Safe because we have unique access
+        unsafe { &mut *self.inner.get() }.as_mut()
+    }
+
+    /// Sets the contents of the cell to `value`.
+    ///
+    /// # Errors
+    ///
+    /// This method returns `Ok(())` if the cell was empty and `Err(value)` if
+    /// it was full.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::OnceCell;
+    ///
+    /// let cell = OnceCell::new();
+    /// assert!(cell.get().is_none());
+    ///
+    /// assert_eq!(cell.set(92), Ok(()));
+    /// assert_eq!(cell.set(62), Err(62));
+    ///
+    /// assert!(cell.get().is_some());
+    /// ```
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub fn set(&self, value: T) -> Result<(), T> {
+        // Safety: Safe because we cannot have overlapping mutable borrows
+        let slot = unsafe { &*self.inner.get() };
+        if slot.is_some() {
+            return Err(value);
+        }
+
+        // Safety: This is the only place where we set the slot, no races
+        // due to reentrancy/concurrency are possible, and we've
+        // checked that slot is currently `None`, so this write
+        // maintains the `inner`'s invariant.
+        let slot = unsafe { &mut *self.inner.get() };
+        *slot = Some(value);
+        Ok(())
+    }
+
+    /// Gets the contents of the cell, initializing it with `f`
+    /// if the cell was empty.
+    ///
+    /// # 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`. Doing
+    /// so results in a panic.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::OnceCell;
+    ///
+    /// let cell = OnceCell::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 = "68198")]
+    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`. Doing
+    /// so results in a panic.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::OnceCell;
+    ///
+    /// let cell = OnceCell::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 = "68198")]
+    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
+    where
+        F: FnOnce() -> Result<T, E>,
+    {
+        if let Some(val) = self.get() {
+            return Ok(val);
+        }
+        let val = f()?;
+        // Note that *some* forms of reentrant initialization might lead to
+        // UB (see `reentrant_init` test). I believe that just removing this
+        // `assert`, while keeping `set/get` would be sound, but it seems
+        // better to panic, rather than to silently use an old value.
+        assert!(self.set(val).is_ok(), "reentrant init");
+        Ok(self.get().unwrap())
+    }
+
+    /// Consumes the cell, returning the wrapped value.
+    ///
+    /// Returns `None` if the cell was empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::OnceCell;
+    ///
+    /// let cell: OnceCell<String> = OnceCell::new();
+    /// assert_eq!(cell.into_inner(), None);
+    ///
+    /// let cell = OnceCell::new();
+    /// cell.set("hello".to_string()).unwrap();
+    /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
+    /// ```
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub fn into_inner(self) -> Option<T> {
+        // Because `into_inner` takes `self` by value, the compiler statically verifies
+        // that it is not currently borrowed. So it is safe to move out `Option<T>`.
+        self.inner.into_inner()
+    }
+}
+
+/// A value which is initialized on the first access.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(once_cell)]
+///
+/// use std::lazy::Lazy;
+///
+/// let lazy: Lazy<i32> = Lazy::new(|| {
+///     println!("initializing");
+///     92
+/// });
+/// println!("ready");
+/// println!("{}", *lazy);
+/// println!("{}", *lazy);
+///
+/// // Prints:
+/// //   ready
+/// //   initializing
+/// //   92
+/// //   92
+/// ```
+#[unstable(feature = "once_cell", issue = "68198")]
+pub struct Lazy<T, F = fn() -> T> {
+    cell: OnceCell<T>,
+    init: Cell<Option<F>>,
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: fmt::Debug, F: fmt::Debug> fmt::Debug for Lazy<T, F> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
+    }
+}
+
+impl<T, F> Lazy<T, F> {
+    /// Creates a new lazy value with the given initializing function.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// # fn main() {
+    /// use std::lazy::Lazy;
+    ///
+    /// let hello = "Hello, World!".to_string();
+    ///
+    /// let lazy = Lazy::new(|| hello.to_uppercase());
+    ///
+    /// assert_eq!(&*lazy, "HELLO, WORLD!");
+    /// # }
+    /// ```
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub const fn new(init: F) -> Lazy<T, F> {
+        Lazy { cell: OnceCell::new(), init: Cell::new(Some(init)) }
+    }
+}
+
+impl<T, F: FnOnce() -> T> Lazy<T, F> {
+    /// Forces the evaluation of this lazy value and returns a reference to
+    /// the result.
+    ///
+    /// This is equivalent to the `Deref` impl, but is explicit.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::Lazy;
+    ///
+    /// let lazy = Lazy::new(|| 92);
+    ///
+    /// assert_eq!(Lazy::force(&lazy), &92);
+    /// assert_eq!(&*lazy, &92);
+    /// ```
+    #[unstable(feature = "once_cell", issue = "68198")]
+    pub fn force(this: &Lazy<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 = "68198")]
+impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
+    type Target = T;
+    fn deref(&self) -> &T {
+        Lazy::force(self)
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "68198")]
+impl<T: Default> Default for Lazy<T> {
+    /// Creates a new lazy value using `Default` as the initializing function.
+    fn default() -> Lazy<T> {
+        Lazy::new(T::default)
+    }
+}
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index ce7ddffd82584..4ea9f30845960 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -225,6 +225,8 @@ pub mod char;
 pub mod ffi;
 #[cfg(not(test))] // See #65860
 pub mod iter;
+#[unstable(feature = "once_cell", issue = "68198")]
+pub mod lazy;
 pub mod option;
 pub mod panic;
 pub mod panicking;
diff --git a/src/libstd/lazy.rs b/src/libstd/lazy.rs
index f8c8f86cf0b05..4afd76107c1bd 100644
--- a/src/libstd/lazy.rs
+++ b/src/libstd/lazy.rs
@@ -1,169 +1,4 @@
 //! Lazy values and one-time initialization of static data.
-//!
-//! `lazy` provides two new cell-like types, `Once` and `Lazy`. `Once`
-//! might store arbitrary non-`Copy` types, can be assigned to at most once and provide direct access
-//! to the stored contents.
-//!
-//! Note that, like with `RefCell` and `Mutex`, the `set` method requires only a shared reference.
-//! Because of the single assignment restriction `get` can return an `&T` instead of `Ref<T>`
-//! or `MutexGuard<T>`.
-//!
-//! # Patterns
-//!
-//! `Once` can be useful for a variety of patterns.
-//!
-//! ## Safe Initialization of global data
-//!
-//! ```rust
-//! #![feature(once_cell)]
-//!
-//! use std::{env, io};
-//! use std::lazy::Once;
-//!
-//! #[derive(Debug)]
-//! pub struct Logger {
-//!     // ...
-//! }
-//! static INSTANCE: Once<Logger> = Once::new();
-//!
-//! impl Logger {
-//!     pub fn global() -> &'static Logger {
-//!         INSTANCE.get().expect("logger is not initialized")
-//!     }
-//!
-//!     fn from_cli(args: env::Args) -> Result<Logger, std::io::Error> {
-//!        // ...
-//! #      Ok(Logger {})
-//!     }
-//! }
-//!
-//! fn main() {
-//!     let logger = Logger::from_cli(env::args()).unwrap();
-//!     INSTANCE.set(logger).unwrap();
-//!     // use `Logger::global()` from now on
-//! }
-//! ```
-//!
-//! ## Lazy initialized global data
-//!
-//! This is essentially `lazy_static!` macro, but without a macro.
-//!
-//! ```rust
-//! #![feature(once_cell)]
-//!
-//! use std::{sync::Mutex, collections::HashMap};
-//! use lazy::Once;
-//!
-//! fn global_data() -> &'static Mutex<HashMap<i32, String>> {
-//!     static INSTANCE: Once<Mutex<HashMap<i32, String>>> = Once::new();
-//!     INSTANCE.get_or_init(|| {
-//!         let mut m = HashMap::new();
-//!         m.insert(13, "Spica".to_string());
-//!         m.insert(74, "Hoyten".to_string());
-//!         Mutex::new(m)
-//!     })
-//! }
-//! ```
-//!
-//! There is also `Lazy` to streamline this pattern:
-//!
-//! ```rust
-//! #![feature(once_cell)]
-//!
-//! use std::{sync::Mutex, collections::HashMap};
-//! use lazy::Lazy;
-//!
-//! static GLOBAL_DATA: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| {
-//!     let mut m = HashMap::new();
-//!     m.insert(13, "Spica".to_string());
-//!     m.insert(74, "Hoyten".to_string());
-//!     Mutex::new(m)
-//! });
-//!
-//! fn main() {
-//!     println!("{:?}", GLOBAL_DATA.lock().unwrap());
-//! }
-//! ```
-//!
-//! ## General purpose lazy evaluation
-//!
-//! `Lazy` also works with local variables.
-//!
-//! ```rust
-//! #![feature(once_cell)]
-//!
-//! use std::lazy::Lazy;
-//!
-//! fn main() {
-//!     let ctx = vec![1, 2, 3];
-//!     let thunk = Lazy::new(|| {
-//!         ctx.iter().sum::<i32>()
-//!     });
-//!     assert_eq!(*thunk, 6);
-//! }
-//! ```
-//!
-//! If you need a lazy field in a struct, you probably should use `Once`
-//! directly, because that will allow you to access `self` during initialization.
-//!
-//! ```rust
-//! #![feature(once_cell)]
-//!
-//! use std::{fs, path::PathBuf};
-//!
-//! use std::lazy::Once;
-//!
-//! struct Ctx {
-//!     config_path: PathBuf,
-//!     config: Once<String>,
-//! }
-//!
-//! impl Ctx {
-//!     pub fn get_config(&self) -> Result<&str, std::io::Error> {
-//!         let cfg = self.config.get_or_try_init(|| {
-//!             fs::read_to_string(&self.config_path)
-//!         })?;
-//!         Ok(cfg.as_str())
-//!     }
-//! }
-//! ```
-//!
-//! ## Building block
-//!
-//! Naturally, it is  possible to build other abstractions on top of `Once`.
-//! For example, this is a `regex!` macro which takes a string literal and returns an
-//! *expression* that evaluates to a `&'static Regex`:
-//!
-//! ```
-//! macro_rules! regex {
-//!     ($re:literal $(,)?) => {{
-//!         static RE: std::lazy::Once<regex::Regex> = std::lazy::Once::new();
-//!         RE.get_or_init(|| regex::Regex::new($re).unwrap())
-//!     }};
-//! }
-//! ```
-//!
-//! This macro can be useful to avoid "compile regex on every loop iteration" problem.
-//!
-//! # Comparison with other interior mutability types
-//!
-//! |`!Sync` types         | Access Mode            | Drawbacks                                     |
-//! |----------------------|------------------------|-----------------------------------------------|
-//! |`Cell<T>`             | `T`                    | requires `T: Copy` for `get`                  |
-//! |`RefCell<T>`          | `RefMut<T>` / `Ref<T>` | may panic at runtime                          |
-//! |`OnceCell<T>`         | `&T`                   | assignable only once                          |
-//! |`LazyCell<T, F>`      | `&T`                   | assignable only once                          |
-//!
-//! |`Sync` types          | Access Mode            | Drawbacks                                     |
-//! |----------------------|------------------------|-----------------------------------------------|
-//! |`AtomicT`             | `T`                    | works only with certain `Copy` types          |
-//! |`Mutex<T>`            | `MutexGuard<T>`        | may deadlock at runtime, may block the thread |
-//! |`Once<T>`             | `&T`                   | assignable only once, may block the thread    |
-//! |`Lazy<T, F>`          | `&T`                   | assignable only once, may block the thread    |
-//!
-//! Technically, calling `get_or_init` will also cause a panic or a deadlock if it recursively calls
-//! itself. However, because the assignment can happen only once, such cases should be more rare than
-//! equivalents with `RefCell` and `Mutex`.
 
 use crate::{
     cell::{Cell, UnsafeCell},
@@ -176,6 +11,10 @@ use crate::{
     thread::{self, Thread},
 };
 
+#[doc(inline)]
+#[unstable(feature = "once_cell", issue = "68198")]
+pub use core::lazy::*;
+
 /// A synchronization primitive which can be written to only once.
 ///
 /// This type is a thread-safe `OnceCell`.
@@ -185,9 +24,9 @@ use crate::{
 /// ```
 /// #![feature(once_cell)]
 ///
-/// use std::lazy::Once;
+/// use std::lazy::SyncOnceCell;
 ///
-/// static CELL: Once<String> = Once::new();
+/// static CELL: SyncOnceCell<String> = SyncOnceCell::new();
 /// assert!(CELL.get().is_none());
 ///
 /// std::thread::spawn(|| {
@@ -202,7 +41,7 @@ use crate::{
 /// assert_eq!(value.unwrap().as_str(), "Hello, World!");
 /// ```
 #[unstable(feature = "once_cell", issue = "68198")]
-pub struct Once<T> {
+pub struct SyncOnceCell<T> {
     // This `state` word is actually an encoded version of just a pointer to a
     // `Waiter`, so we add the `PhantomData` appropriately.
     state_and_queue: AtomicUsize,
@@ -217,24 +56,24 @@ pub struct Once<T> {
 // then destroyed by A. That is, destructor observes
 // a sent value.
 #[unstable(feature = "once_cell", issue = "68198")]
-unsafe impl<T: Sync + Send> Sync for Once<T> {}
+unsafe impl<T: Sync + Send> Sync for SyncOnceCell<T> {}
 #[unstable(feature = "once_cell", issue = "68198")]
-unsafe impl<T: Send> Send for Once<T> {}
+unsafe impl<T: Send> Send for SyncOnceCell<T> {}
 
 #[unstable(feature = "once_cell", issue = "68198")]
-impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for Once<T> {}
+impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
 #[unstable(feature = "once_cell", issue = "68198")]
-impl<T: UnwindSafe> UnwindSafe for Once<T> {}
+impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
 
 #[unstable(feature = "once_cell", issue = "68198")]
-impl<T> Default for Once<T> {
-    fn default() -> Once<T> {
-        Once::new()
+impl<T> Default for SyncOnceCell<T> {
+    fn default() -> SyncOnceCell<T> {
+        SyncOnceCell::new()
     }
 }
 
 #[unstable(feature = "once_cell", issue = "68198")]
-impl<T: fmt::Debug> fmt::Debug for Once<T> {
+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(),
@@ -244,9 +83,9 @@ impl<T: fmt::Debug> fmt::Debug for Once<T> {
 }
 
 #[unstable(feature = "once_cell", issue = "68198")]
-impl<T: Clone> Clone for Once<T> {
-    fn clone(&self) -> Once<T> {
-        let res = Once::new();
+impl<T: Clone> Clone for SyncOnceCell<T> {
+    fn clone(&self) -> SyncOnceCell<T> {
+        let res = SyncOnceCell::new();
         if let Some(value) = self.get() {
             match res.set(value.clone()) {
                 Ok(()) => (),
@@ -258,7 +97,7 @@ impl<T: Clone> Clone for Once<T> {
 }
 
 #[unstable(feature = "once_cell", issue = "68198")]
-impl<T> From<T> for Once<T> {
+impl<T> From<T> for SyncOnceCell<T> {
     fn from(value: T) -> Self {
         let cell = Self::new();
         cell.get_or_init(|| value);
@@ -267,20 +106,20 @@ impl<T> From<T> for Once<T> {
 }
 
 #[unstable(feature = "once_cell", issue = "68198")]
-impl<T: PartialEq> PartialEq for Once<T> {
-    fn eq(&self, other: &Once<T>) -> bool {
+impl<T: PartialEq> PartialEq for SyncOnceCell<T> {
+    fn eq(&self, other: &SyncOnceCell<T>) -> bool {
         self.get() == other.get()
     }
 }
 
 #[unstable(feature = "once_cell", issue = "68198")]
-impl<T: Eq> Eq for Once<T> {}
+impl<T: Eq> Eq for SyncOnceCell<T> {}
 
-impl<T> Once<T> {
+impl<T> SyncOnceCell<T> {
     /// Creates a new empty cell.
     #[unstable(feature = "once_cell", issue = "68198")]
-    pub const fn new() -> Once<T> {
-        Once {
+    pub const fn new() -> SyncOnceCell<T> {
+        SyncOnceCell {
             state_and_queue: AtomicUsize::new(INCOMPLETE),
             _marker: PhantomData,
             value: UnsafeCell::new(MaybeUninit::uninit()),
@@ -324,9 +163,9 @@ impl<T> Once<T> {
     /// ```
     /// #![feature(once_cell)]
     ///
-    /// use std::lazy::Once;
+    /// use std::lazy::SyncOnceCell;
     ///
-    /// static CELL: Once<i32> = Once::new();
+    /// static CELL: SyncOnceCell<i32> = SyncOnceCell::new();
     ///
     /// fn main() {
     ///     assert!(CELL.get().is_none());
@@ -370,9 +209,9 @@ impl<T> Once<T> {
     /// ```
     /// #![feature(once_cell)]
     ///
-    /// use std::lazy::Once;
+    /// use std::lazy::SyncOnceCell;
     ///
-    /// let cell = Once::new();
+    /// let cell = SyncOnceCell::new();
     /// let value = cell.get_or_init(|| 92);
     /// assert_eq!(value, &92);
     /// let value = cell.get_or_init(|| unreachable!());
@@ -406,9 +245,9 @@ impl<T> Once<T> {
     /// ```
     /// #![feature(once_cell)]
     ///
-    /// use std::lazy::Once;
+    /// use std::lazy::SyncOnceCell;
     ///
-    /// let cell = Once::new();
+    /// 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, ()> {
@@ -441,12 +280,12 @@ impl<T> Once<T> {
     /// ```
     /// #![feature(once_cell)]
     ///
-    /// use std::lazy::Once;
+    /// use std::lazy::SyncOnceCell;
     ///
-    /// let cell: Once<String> = Once::new();
+    /// let cell: SyncOnceCell<String> = SyncOnceCell::new();
     /// assert_eq!(cell.into_inner(), None);
     ///
-    /// let cell = Once::new();
+    /// let cell = SyncOnceCell::new();
     /// cell.set("hello".to_string()).unwrap();
     /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
     /// ```
@@ -529,7 +368,7 @@ impl<T> Once<T> {
     }
 }
 
-impl<T> Drop for Once<T> {
+impl<T> Drop for SyncOnceCell<T> {
     fn drop(&mut self) {
         // Safety: The cell is being dropped, so it can't be accessed again
         unsafe { self.take_inner() };
@@ -539,7 +378,7 @@ impl<T> Drop for Once<T> {
 // FIXME: The following code is copied from `sync::Once`.
 // This should be uncopypasted once we decide the right way to handle panics.
 // Do we want to effectively move the `Once` synchronization here and make `Once`
-// a newtype: `pub struct Once(lazy::Once<()>)`?
+// a newtype: `pub struct Once(lazy::SyncOnceCell<()>)`?
 const INCOMPLETE: usize = 0x0;
 const RUNNING: usize = 0x1;
 const COMPLETE: usize = 0x2;
@@ -640,7 +479,7 @@ fn wait(state_and_queue: &AtomicUsize, mut current_state: usize) {
 
 /// A value which is initialized on the first access.
 ///
-/// This type is a thread-safe `LazyCell`, and can be used in statics.
+/// This type is a thread-safe `Lazy`, and can be used in statics.
 ///
 /// # Examples
 ///
@@ -649,9 +488,9 @@ fn wait(state_and_queue: &AtomicUsize, mut current_state: usize) {
 ///
 /// use std::collections::HashMap;
 ///
-/// use std::lazy::Lazy;
+/// use std::lazy::SyncLazy;
 ///
-/// static HASHMAP: Lazy<HashMap<i32, String>> = Lazy::new(|| {
+/// static HASHMAP: SyncLazy<HashMap<i32, String>> = SyncLazy::new(|| {
 ///     println!("initializing");
 ///     let mut m = HashMap::new();
 ///     m.insert(13, "Spica".to_string());
@@ -674,40 +513,40 @@ fn wait(state_and_queue: &AtomicUsize, mut current_state: usize) {
 /// }
 /// ```
 #[unstable(feature = "once_cell", issue = "68198")]
-pub struct Lazy<T, F = fn() -> T> {
-    cell: Once<T>,
+pub struct SyncLazy<T, F = fn() -> T> {
+    cell: SyncOnceCell<T>,
     init: Cell<Option<F>>,
 }
 
 #[unstable(feature = "once_cell", issue = "68198")]
-impl<T: fmt::Debug, F: fmt::Debug> fmt::Debug for Lazy<T, F> {
+impl<T: fmt::Debug, F: fmt::Debug> fmt::Debug for SyncLazy<T, F> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
     }
 }
 
-// We never create a `&F` from a `&Lazy<T, F>` so it is fine
+// 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 = "68198")]
-unsafe impl<T, F: Send> Sync for Lazy<T, F> where Once<T>: Sync {}
+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 = "68198")]
-impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where Once<T>: RefUnwindSafe {}
+impl<T, F: RefUnwindSafe> RefUnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: RefUnwindSafe {}
 
-impl<T, F> Lazy<T, F> {
+impl<T, F> SyncLazy<T, F> {
     /// Creates a new lazy value with the given initializing
     /// function.
     #[unstable(feature = "once_cell", issue = "68198")]
-    pub const fn new(f: F) -> Lazy<T, F> {
-        Lazy { cell: Once::new(), init: Cell::new(Some(f)) }
+    pub const fn new(f: F) -> SyncLazy<T, F> {
+        SyncLazy { cell: SyncOnceCell::new(), init: Cell::new(Some(f)) }
     }
 }
 
-impl<T, F: FnOnce() -> T> Lazy<T, 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.
@@ -717,15 +556,15 @@ impl<T, F: FnOnce() -> T> Lazy<T, F> {
     /// ```
     /// #![feature(once_cell)]
     ///
-    /// use std::lazy::Lazy;
+    /// use std::lazy::SyncLazy;
     ///
-    /// let lazy = Lazy::new(|| 92);
+    /// let lazy = SyncLazy::new(|| 92);
     ///
-    /// assert_eq!(Lazy::force(&lazy), &92);
+    /// assert_eq!(SyncLazy::force(&lazy), &92);
     /// assert_eq!(&*lazy, &92);
     /// ```
     #[unstable(feature = "once_cell", issue = "68198")]
-    pub fn force(this: &Lazy<T, F>) -> &T {
+    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"),
@@ -734,17 +573,17 @@ impl<T, F: FnOnce() -> T> Lazy<T, F> {
 }
 
 #[unstable(feature = "once_cell", issue = "68198")]
-impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
+impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {
     type Target = T;
     fn deref(&self) -> &T {
-        Lazy::force(self)
+        SyncLazy::force(self)
     }
 }
 
 #[unstable(feature = "once_cell", issue = "68198")]
-impl<T: Default> Default for Lazy<T> {
+impl<T: Default> Default for SyncLazy<T> {
     /// Creates a new lazy value using `Default` as the initializing function.
-    fn default() -> Lazy<T> {
-        Lazy::new(T::default)
+    fn default() -> SyncLazy<T> {
+        SyncLazy::new(T::default)
     }
 }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 06a581c27da62..a791d426c05cb 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -282,6 +282,7 @@
 #![feature(needs_panic_runtime)]
 #![feature(never_type)]
 #![feature(nll)]
+#![feature(once_cell)]
 #![feature(optin_builtin_traits)]
 #![feature(panic_info_message)]
 #![feature(panic_internals)]

From 2d2202c7eb4a52bf9e5c0f1b493df2ef4547178d Mon Sep 17 00:00:00 2001
From: Ashley Mannix <ashleymannix@live.com.au>
Date: Mon, 3 Feb 2020 18:17:17 +1000
Subject: [PATCH 5/6] Update src/libcore/lazy.rs

Co-Authored-By: Paul Dicker <pitdicker@users.noreply.github.com>
---
 src/libcore/lazy.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libcore/lazy.rs b/src/libcore/lazy.rs
index eb74faeaf11d3..bd6051d3c8962 100644
--- a/src/libcore/lazy.rs
+++ b/src/libcore/lazy.rs
@@ -7,7 +7,7 @@ use crate::ops::Deref;
 /// A cell which can be written to only once.
 ///
 /// Unlike `RefCell`, a `OnceCell` only provides shared `&T` references to its value.
-/// Unlike `Cell`, a `OnceCell` doesn't require `T: Copy` to access its value.
+/// Unlike `Cell`, a `OnceCell` doesn't require copying or replacing the value to access it.
 ///
 /// # Examples
 ///

From bde13db35d48179f3418eb91d06cbf4317be9e48 Mon Sep 17 00:00:00 2001
From: Ashley Mannix <ashleymannix@live.com.au>
Date: Mon, 3 Feb 2020 20:22:16 +1000
Subject: [PATCH 6/6] port once_cell tests

---
 src/libcore/tests/lazy.rs | 124 ++++++++++++++
 src/libcore/tests/lib.rs  |   2 +
 src/libstd/lazy.rs        | 338 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 464 insertions(+)
 create mode 100644 src/libcore/tests/lazy.rs

diff --git a/src/libcore/tests/lazy.rs b/src/libcore/tests/lazy.rs
new file mode 100644
index 0000000000000..1c0bddb9aef62
--- /dev/null
+++ b/src/libcore/tests/lazy.rs
@@ -0,0 +1,124 @@
+use core::{
+    cell::Cell,
+    lazy::{Lazy, OnceCell},
+    sync::atomic::{AtomicUsize, Ordering::SeqCst},
+};
+
+#[test]
+fn once_cell() {
+    let c = OnceCell::new();
+    assert!(c.get().is_none());
+    c.get_or_init(|| 92);
+    assert_eq!(c.get(), Some(&92));
+
+    c.get_or_init(|| panic!("Kabom!"));
+    assert_eq!(c.get(), Some(&92));
+}
+
+#[test]
+fn once_cell_get_mut() {
+    let mut c = OnceCell::new();
+    assert!(c.get_mut().is_none());
+    c.set(90).unwrap();
+    *c.get_mut().unwrap() += 2;
+    assert_eq!(c.get_mut(), Some(&mut 92));
+}
+
+#[test]
+fn once_cell_drop() {
+    static DROP_CNT: AtomicUsize = AtomicUsize::new(0);
+    struct Dropper;
+    impl Drop for Dropper {
+        fn drop(&mut self) {
+            DROP_CNT.fetch_add(1, SeqCst);
+        }
+    }
+
+    let x = OnceCell::new();
+    x.get_or_init(|| Dropper);
+    assert_eq!(DROP_CNT.load(SeqCst), 0);
+    drop(x);
+    assert_eq!(DROP_CNT.load(SeqCst), 1);
+}
+
+#[test]
+fn unsync_once_cell_drop_empty() {
+    let x = OnceCell::<&'static str>::new();
+    drop(x);
+}
+
+#[test]
+fn clone() {
+    let s = OnceCell::new();
+    let c = s.clone();
+    assert!(c.get().is_none());
+
+    s.set("hello").unwrap();
+    let c = s.clone();
+    assert_eq!(c.get().map(|c| *c), Some("hello"));
+}
+
+#[test]
+fn from_impl() {
+    assert_eq!(OnceCell::from("value").get(), Some(&"value"));
+    assert_ne!(OnceCell::from("foo").get(), Some(&"bar"));
+}
+
+#[test]
+fn partialeq_impl() {
+    assert!(OnceCell::from("value") == OnceCell::from("value"));
+    assert!(OnceCell::from("foo") != OnceCell::from("bar"));
+
+    assert!(OnceCell::<&'static str>::new() == OnceCell::new());
+    assert!(OnceCell::<&'static str>::new() != OnceCell::from("value"));
+}
+
+#[test]
+fn into_inner() {
+    let cell: OnceCell<&'static str> = OnceCell::new();
+    assert_eq!(cell.into_inner(), None);
+    let cell = OnceCell::new();
+    cell.set("hello").unwrap();
+    assert_eq!(cell.into_inner(), Some("hello"));
+}
+
+#[test]
+fn lazy_new() {
+    let called = Cell::new(0);
+    let x = Lazy::new(|| {
+        called.set(called.get() + 1);
+        92
+    });
+
+    assert_eq!(called.get(), 0);
+
+    let y = *x - 30;
+    assert_eq!(y, 62);
+    assert_eq!(called.get(), 1);
+
+    let y = *x - 30;
+    assert_eq!(y, 62);
+    assert_eq!(called.get(), 1);
+}
+
+#[test]
+fn aliasing_in_get() {
+    let x = OnceCell::new();
+    x.set(42).unwrap();
+    let at_x = x.get().unwrap(); // --- (shared) borrow of inner `Option<T>` --+
+    let _ = x.set(27); // <-- temporary (unique) borrow of inner `Option<T>`   |
+    println!("{}", at_x); // <------- up until here ---------------------------+
+}
+
+#[test]
+#[should_panic(expected = "reentrant init")]
+fn reentrant_init() {
+    let x: OnceCell<Box<i32>> = OnceCell::new();
+    let dangling_ref: Cell<Option<&i32>> = Cell::new(None);
+    x.get_or_init(|| {
+        let r = x.get_or_init(|| Box::new(92));
+        dangling_ref.set(Some(r));
+        Box::new(62)
+    });
+    eprintln!("use after free: {:?}", dangling_ref.get().unwrap());
+}
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 8fd19ef67fccf..4a108ae0f1225 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -14,6 +14,7 @@
 #![feature(try_find)]
 #![feature(is_sorted)]
 #![feature(iter_once_with)]
+#![feature(once_cell)]
 #![feature(pattern)]
 #![feature(range_is_empty)]
 #![feature(raw)]
@@ -59,6 +60,7 @@ mod fmt;
 mod hash;
 mod intrinsics;
 mod iter;
+mod lazy;
 mod manually_drop;
 mod mem;
 mod nonzero;
diff --git a/src/libstd/lazy.rs b/src/libstd/lazy.rs
index 4afd76107c1bd..be658727f2164 100644
--- a/src/libstd/lazy.rs
+++ b/src/libstd/lazy.rs
@@ -587,3 +587,341 @@ impl<T: Default> Default for SyncLazy<T> {
         SyncLazy::new(T::default)
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use crate::{
+        lazy::{Lazy, SyncLazy, SyncOnceCell},
+        panic,
+        sync::{
+            atomic::{AtomicUsize, Ordering::SeqCst},
+            mpsc::channel,
+            Mutex,
+        },
+    };
+
+    #[test]
+    fn lazy_default() {
+        static CALLED: AtomicUsize = AtomicUsize::new(0);
+
+        struct Foo(u8);
+        impl Default for Foo {
+            fn default() -> Self {
+                CALLED.fetch_add(1, SeqCst);
+                Foo(42)
+            }
+        }
+
+        let lazy: Lazy<Mutex<Foo>> = <_>::default();
+
+        assert_eq!(CALLED.load(SeqCst), 0);
+
+        assert_eq!(lazy.lock().unwrap().0, 42);
+        assert_eq!(CALLED.load(SeqCst), 1);
+
+        lazy.lock().unwrap().0 = 21;
+
+        assert_eq!(lazy.lock().unwrap().0, 21);
+        assert_eq!(CALLED.load(SeqCst), 1);
+    }
+
+    #[test]
+    fn lazy_poisoning() {
+        let x: Lazy<String> = Lazy::new(|| panic!("kaboom"));
+        for _ in 0..2 {
+            let res = panic::catch_unwind(panic::AssertUnwindSafe(|| x.len()));
+            assert!(res.is_err());
+        }
+    }
+
+    // miri doesn't support threads
+    #[cfg(not(miri))]
+    fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
+        crate::thread::spawn(f).join().unwrap()
+    }
+
+    #[cfg(not(miri))]
+    fn spawn(f: impl FnOnce() + Send + 'static) {
+        let _ = crate::thread::spawn(f);
+    }
+
+    // "stub threads" for Miri
+    #[cfg(miri)]
+    fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
+        f(())
+    }
+
+    #[cfg(miri)]
+    fn spawn(f: impl FnOnce() + Send + 'static) {
+        f(())
+    }
+
+    #[test]
+    fn sync_once_cell() {
+        static ONCE_CELL: SyncOnceCell<i32> = SyncOnceCell::new();
+
+        assert!(ONCE_CELL.get().is_none());
+
+        spawn_and_wait(|| {
+            ONCE_CELL.get_or_init(|| 92);
+            assert_eq!(ONCE_CELL.get(), Some(&92));
+        });
+
+        ONCE_CELL.get_or_init(|| panic!("Kabom!"));
+        assert_eq!(ONCE_CELL.get(), Some(&92));
+    }
+
+    #[test]
+    fn sync_once_cell_get_mut() {
+        let mut c = SyncOnceCell::new();
+        assert!(c.get_mut().is_none());
+        c.set(90).unwrap();
+        *c.get_mut().unwrap() += 2;
+        assert_eq!(c.get_mut(), Some(&mut 92));
+    }
+
+    #[test]
+    fn sync_once_cell_get_unchecked() {
+        let c = SyncOnceCell::new();
+        c.set(92).unwrap();
+        unsafe {
+            assert_eq!(c.get_unchecked(), &92);
+        }
+    }
+
+    #[test]
+    fn sync_once_cell_drop() {
+        static DROP_CNT: AtomicUsize = AtomicUsize::new(0);
+        struct Dropper;
+        impl Drop for Dropper {
+            fn drop(&mut self) {
+                DROP_CNT.fetch_add(1, SeqCst);
+            }
+        }
+
+        let x = SyncOnceCell::new();
+        spawn_and_wait(move || {
+            x.get_or_init(|| Dropper);
+            assert_eq!(DROP_CNT.load(SeqCst), 0);
+            drop(x);
+        });
+
+        assert_eq!(DROP_CNT.load(SeqCst), 1);
+    }
+
+    #[test]
+    fn sync_once_cell_drop_empty() {
+        let x = SyncOnceCell::<String>::new();
+        drop(x);
+    }
+
+    #[test]
+    fn clone() {
+        let s = SyncOnceCell::new();
+        let c = s.clone();
+        assert!(c.get().is_none());
+
+        s.set("hello".to_string()).unwrap();
+        let c = s.clone();
+        assert_eq!(c.get().map(String::as_str), Some("hello"));
+    }
+
+    #[test]
+    fn get_or_try_init() {
+        let cell: SyncOnceCell<String> = SyncOnceCell::new();
+        assert!(cell.get().is_none());
+
+        let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() }));
+        assert!(res.is_err());
+        assert!(cell.get().is_none());
+
+        assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
+
+        assert_eq!(
+            cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())),
+            Ok(&"hello".to_string())
+        );
+        assert_eq!(cell.get(), Some(&"hello".to_string()));
+    }
+
+    #[test]
+    fn from_impl() {
+        assert_eq!(SyncOnceCell::from("value").get(), Some(&"value"));
+        assert_ne!(SyncOnceCell::from("foo").get(), Some(&"bar"));
+    }
+
+    #[test]
+    fn partialeq_impl() {
+        assert!(SyncOnceCell::from("value") == SyncOnceCell::from("value"));
+        assert!(SyncOnceCell::from("foo") != SyncOnceCell::from("bar"));
+
+        assert!(SyncOnceCell::<String>::new() == SyncOnceCell::new());
+        assert!(SyncOnceCell::<String>::new() != SyncOnceCell::from("value".to_owned()));
+    }
+
+    #[test]
+    fn into_inner() {
+        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()));
+    }
+
+    #[test]
+    fn sync_lazy_new() {
+        static CALLED: AtomicUsize = AtomicUsize::new(0);
+        static SYNC_LAZY: SyncLazy<i32> = SyncLazy::new(|| {
+            CALLED.fetch_add(1, SeqCst);
+            92
+        });
+
+        assert_eq!(CALLED.load(SeqCst), 0);
+
+        spawn_and_wait(|| {
+            let y = *SYNC_LAZY - 30;
+            assert_eq!(y, 62);
+            assert_eq!(CALLED.load(SeqCst), 1);
+        });
+
+        let y = *SYNC_LAZY - 30;
+        assert_eq!(y, 62);
+        assert_eq!(CALLED.load(SeqCst), 1);
+    }
+
+    #[test]
+    fn sync_lazy_default() {
+        static CALLED: AtomicUsize = AtomicUsize::new(0);
+
+        struct Foo(u8);
+        impl Default for Foo {
+            fn default() -> Self {
+                CALLED.fetch_add(1, SeqCst);
+                Foo(42)
+            }
+        }
+
+        let lazy: SyncLazy<Mutex<Foo>> = <_>::default();
+
+        assert_eq!(CALLED.load(SeqCst), 0);
+
+        assert_eq!(lazy.lock().unwrap().0, 42);
+        assert_eq!(CALLED.load(SeqCst), 1);
+
+        lazy.lock().unwrap().0 = 21;
+
+        assert_eq!(lazy.lock().unwrap().0, 21);
+        assert_eq!(CALLED.load(SeqCst), 1);
+    }
+
+    #[test]
+    #[cfg_attr(miri, ignore)] // leaks memory
+    fn static_sync_lazy() {
+        static XS: SyncLazy<Vec<i32>> = SyncLazy::new(|| {
+            let mut xs = Vec::new();
+            xs.push(1);
+            xs.push(2);
+            xs.push(3);
+            xs
+        });
+
+        spawn_and_wait(|| {
+            assert_eq!(&*XS, &vec![1, 2, 3]);
+        });
+
+        assert_eq!(&*XS, &vec![1, 2, 3]);
+    }
+
+    #[test]
+    #[cfg_attr(miri, ignore)] // leaks memory
+    fn static_sync_lazy_via_fn() {
+        fn xs() -> &'static Vec<i32> {
+            static XS: SyncOnceCell<Vec<i32>> = SyncOnceCell::new();
+            XS.get_or_init(|| {
+                let mut xs = Vec::new();
+                xs.push(1);
+                xs.push(2);
+                xs.push(3);
+                xs
+            })
+        }
+        assert_eq!(xs(), &vec![1, 2, 3]);
+    }
+
+    #[test]
+    fn sync_lazy_poisoning() {
+        let x: SyncLazy<String> = SyncLazy::new(|| panic!("kaboom"));
+        for _ in 0..2 {
+            let res = panic::catch_unwind(|| x.len());
+            assert!(res.is_err());
+        }
+    }
+
+    #[test]
+    fn is_sync_send() {
+        fn assert_traits<T: Send + Sync>() {}
+        assert_traits::<SyncOnceCell<String>>();
+        assert_traits::<SyncLazy<String>>();
+    }
+
+    #[test]
+    fn eval_once_macro() {
+        macro_rules! eval_once {
+            (|| -> $ty:ty {
+                $($body:tt)*
+            }) => {{
+                static ONCE_CELL: SyncOnceCell<$ty> = SyncOnceCell::new();
+                fn init() -> $ty {
+                    $($body)*
+                }
+                ONCE_CELL.get_or_init(init)
+            }};
+        }
+
+        let fib: &'static Vec<i32> = eval_once! {
+            || -> Vec<i32> {
+                let mut res = vec![1, 1];
+                for i in 0..10 {
+                    let next = res[i] + res[i + 1];
+                    res.push(next);
+                }
+                res
+            }
+        };
+        assert_eq!(fib[5], 8)
+    }
+
+    #[test]
+    #[cfg_attr(miri, ignore)] // deadlocks without real threads
+    fn sync_once_cell_does_not_leak_partially_constructed_boxes() {
+        static ONCE_CELL: SyncOnceCell<String> = SyncOnceCell::new();
+
+        let n_readers = 10;
+        let n_writers = 3;
+        const MSG: &str = "Hello, World";
+
+        let (tx, rx) = channel();
+
+        for _ in 0..n_readers {
+            let tx = tx.clone();
+            spawn(move || {
+                loop {
+                    if let Some(msg) = ONCE_CELL.get() {
+                        tx.send(msg).unwrap();
+                        break;
+                    }
+                }
+            });
+        }
+        for _ in 0..n_writers {
+            spawn(move || {
+                let _ = ONCE_CELL.set(MSG.to_owned());
+            });
+        }
+
+        for _ in 0..n_readers {
+            let msg = rx.recv().unwrap();
+            assert_eq!(msg, MSG);
+        }
+    }
+}