diff --git a/src/libcore/lazy.rs b/src/libcore/lazy.rs
deleted file mode 100644
index 5cf7217ef11e8..0000000000000
--- a/src/libcore/lazy.rs
+++ /dev/null
@@ -1,379 +0,0 @@
-//! Lazy values and one-time initialization of static data.
-
-use crate::cell::{Cell, UnsafeCell};
-use crate::fmt;
-use crate::mem;
-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 copying or replacing the value to access it.
-///
-/// # 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 = "74465")]
-pub struct OnceCell<T> {
-    // Invariant: written to at most once.
-    inner: UnsafeCell<Option<T>>,
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T> Default for OnceCell<T> {
-    fn default() -> Self {
-        Self::new()
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-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 = "74465")]
-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 = "74465")]
-impl<T: PartialEq> PartialEq for OnceCell<T> {
-    fn eq(&self, other: &Self) -> bool {
-        self.get() == other.get()
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: Eq> Eq for OnceCell<T> {}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-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 = "74465")]
-    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 = "74465")]
-    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 = "74465")]
-    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 = "74465")]
-    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 = "74465")]
-    pub fn get_or_init<F>(&self, f: F) -> &T
-    where
-        F: FnOnce() -> T,
-    {
-        match self.get_or_try_init(|| Ok::<T, !>(f())) {
-            Ok(val) => val,
-        }
-    }
-
-    /// Gets the contents of the cell, initializing it with `f` if
-    /// the cell was empty. If the cell was empty and `f` failed, an
-    /// error is returned.
-    ///
-    /// # Panics
-    ///
-    /// If `f` panics, the panic is propagated to the caller, and the cell
-    /// remains uninitialized.
-    ///
-    /// It is an error to reentrantly initialize the cell from `f`. 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 = "74465")]
-    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 = "74465")]
-    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()
-    }
-
-    /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
-    ///
-    /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized.
-    ///
-    /// Safety is guaranteed by requiring a mutable reference.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::OnceCell;
-    ///
-    /// let mut cell: OnceCell<String> = OnceCell::new();
-    /// assert_eq!(cell.take(), None);
-    ///
-    /// let mut cell = OnceCell::new();
-    /// cell.set("hello".to_string()).unwrap();
-    /// assert_eq!(cell.take(), Some("hello".to_string()));
-    /// assert_eq!(cell.get(), None);
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn take(&mut self) -> Option<T> {
-        mem::take(self).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 = "74465")]
-pub struct Lazy<T, F = fn() -> T> {
-    cell: OnceCell<T>,
-    init: Cell<Option<F>>,
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: fmt::Debug, F> 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 = "74465")]
-    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 = "74465")]
-    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 = "74465")]
-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 = "74465")]
-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 2e443064706d2..8bf98b50acfed 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -240,8 +240,6 @@ pub mod char;
 pub mod ffi;
 #[cfg(not(test))] // See #65860
 pub mod iter;
-#[unstable(feature = "once_cell", issue = "74465")]
-pub mod lazy;
 pub mod option;
 pub mod panic;
 pub mod panicking;
diff --git a/src/libcore/tests/lazy.rs b/src/libcore/tests/lazy.rs
deleted file mode 100644
index 1c0bddb9aef62..0000000000000
--- a/src/libcore/tests/lazy.rs
+++ /dev/null
@@ -1,124 +0,0 @@
-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 47ed6db6c677b..090ce47174566 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -43,7 +43,6 @@
 #![feature(option_unwrap_none)]
 #![feature(peekable_next_if)]
 #![feature(partition_point)]
-#![feature(once_cell)]
 #![feature(unsafe_block_in_unsafe_fn)]
 #![deny(unsafe_op_in_unsafe_fn)]
 
@@ -63,7 +62,6 @@ 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
deleted file mode 100644
index 86e1cfae582e8..0000000000000
--- a/src/libstd/lazy.rs
+++ /dev/null
@@ -1,844 +0,0 @@
-//! Lazy values and one-time initialization of static data.
-
-use crate::{
-    cell::{Cell, UnsafeCell},
-    fmt,
-    mem::{self, MaybeUninit},
-    ops::{Deref, Drop},
-    panic::{RefUnwindSafe, UnwindSafe},
-    sync::Once,
-};
-
-#[doc(inline)]
-#[unstable(feature = "once_cell", issue = "74465")]
-pub use core::lazy::*;
-
-/// A synchronization primitive which can be written to only once.
-///
-/// This type is a thread-safe `OnceCell`.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(once_cell)]
-///
-/// use std::lazy::SyncOnceCell;
-///
-/// static CELL: SyncOnceCell<String> = SyncOnceCell::new();
-/// assert!(CELL.get().is_none());
-///
-/// std::thread::spawn(|| {
-///     let value: &String = CELL.get_or_init(|| {
-///         "Hello, World!".to_string()
-///     });
-///     assert_eq!(value, "Hello, World!");
-/// }).join().unwrap();
-///
-/// let value: Option<&String> = CELL.get();
-/// assert!(value.is_some());
-/// assert_eq!(value.unwrap().as_str(), "Hello, World!");
-/// ```
-#[unstable(feature = "once_cell", issue = "74465")]
-pub struct SyncOnceCell<T> {
-    once: Once,
-    // Whether or not the value is initialized is tracked by `state_and_queue`.
-    value: UnsafeCell<MaybeUninit<T>>,
-}
-
-// Why do we need `T: Send`?
-// Thread A creates a `SyncOnceCell` and shares it with
-// scoped thread B, which fills the cell, which is
-// then destroyed by A. That is, destructor observes
-// a sent value.
-#[unstable(feature = "once_cell", issue = "74465")]
-unsafe impl<T: Sync + Send> Sync for SyncOnceCell<T> {}
-#[unstable(feature = "once_cell", issue = "74465")]
-unsafe impl<T: Send> Send for SyncOnceCell<T> {}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T> Default for SyncOnceCell<T> {
-    fn default() -> SyncOnceCell<T> {
-        SyncOnceCell::new()
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: fmt::Debug> fmt::Debug for SyncOnceCell<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.get() {
-            Some(v) => f.debug_tuple("Once").field(v).finish(),
-            None => f.write_str("Once(Uninit)"),
-        }
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: Clone> Clone for SyncOnceCell<T> {
-    fn clone(&self) -> SyncOnceCell<T> {
-        let cell = Self::new();
-        if let Some(value) = self.get() {
-            match cell.set(value.clone()) {
-                Ok(()) => (),
-                Err(_) => unreachable!(),
-            }
-        }
-        cell
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T> From<T> for SyncOnceCell<T> {
-    fn from(value: T) -> Self {
-        let cell = Self::new();
-        match cell.set(value) {
-            Ok(()) => cell,
-            Err(_) => unreachable!(),
-        }
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: PartialEq> PartialEq for SyncOnceCell<T> {
-    fn eq(&self, other: &SyncOnceCell<T>) -> bool {
-        self.get() == other.get()
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: Eq> Eq for SyncOnceCell<T> {}
-
-impl<T> SyncOnceCell<T> {
-    /// Creates a new empty cell.
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub const fn new() -> SyncOnceCell<T> {
-        SyncOnceCell { once: Once::new(), value: UnsafeCell::new(MaybeUninit::uninit()) }
-    }
-
-    /// Gets the reference to the underlying value.
-    ///
-    /// Returns `None` if the cell is empty, or being initialized. This
-    /// method never blocks.
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn get(&self) -> Option<&T> {
-        if self.is_initialized() {
-            // Safe b/c checked is_initialized
-            Some(unsafe { self.get_unchecked() })
-        } else {
-            None
-        }
-    }
-
-    /// Gets the mutable reference to the underlying value.
-    ///
-    /// Returns `None` if the cell is empty. This method never blocks.
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn get_mut(&mut self) -> Option<&mut T> {
-        if self.is_initialized() {
-            // Safe b/c checked is_initialized and we have a unique access
-            Some(unsafe { self.get_unchecked_mut() })
-        } else {
-            None
-        }
-    }
-
-    /// Sets the contents of this cell to `value`.
-    ///
-    /// Returns `Ok(())` if the cell's value was updated.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// static CELL: SyncOnceCell<i32> = SyncOnceCell::new();
-    ///
-    /// fn main() {
-    ///     assert!(CELL.get().is_none());
-    ///
-    ///     std::thread::spawn(|| {
-    ///         assert_eq!(CELL.set(92), Ok(()));
-    ///     }).join().unwrap();
-    ///
-    ///     assert_eq!(CELL.set(62), Err(62));
-    ///     assert_eq!(CELL.get(), Some(&92));
-    /// }
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn set(&self, value: T) -> Result<(), T> {
-        let mut value = Some(value);
-        self.get_or_init(|| value.take().unwrap());
-        match value {
-            None => Ok(()),
-            Some(value) => Err(value),
-        }
-    }
-
-    /// Gets the contents of the cell, initializing it with `f` if the cell
-    /// was empty.
-    ///
-    /// Many threads may call `get_or_init` concurrently with different
-    /// initializing functions, but it is guaranteed that only one function
-    /// will be executed.
-    ///
-    /// # Panics
-    ///
-    /// If `f` panics, the panic is propagated to the caller, and the cell
-    /// remains uninitialized.
-    ///
-    /// It is an error to reentrantly initialize the cell from `f`. The
-    /// exact outcome is unspecified. Current implementation deadlocks, but
-    /// this may be changed to a panic in the future.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// let cell = SyncOnceCell::new();
-    /// let value = cell.get_or_init(|| 92);
-    /// assert_eq!(value, &92);
-    /// let value = cell.get_or_init(|| unreachable!());
-    /// assert_eq!(value, &92);
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn get_or_init<F>(&self, f: F) -> &T
-    where
-        F: FnOnce() -> T,
-    {
-        match self.get_or_try_init(|| Ok::<T, !>(f())) {
-            Ok(val) => val,
-        }
-    }
-
-    /// Gets the contents of the cell, initializing it with `f` if
-    /// the cell was empty. If the cell was empty and `f` failed, an
-    /// error is returned.
-    ///
-    /// # Panics
-    ///
-    /// If `f` panics, the panic is propagated to the caller, and
-    /// the cell remains uninitialized.
-    ///
-    /// It is an error to reentrantly initialize the cell from `f`.
-    /// The exact outcome is unspecified. Current implementation
-    /// deadlocks, but this may be changed to a panic in the future.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// let cell = SyncOnceCell::new();
-    /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
-    /// assert!(cell.get().is_none());
-    /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
-    ///     Ok(92)
-    /// });
-    /// assert_eq!(value, Ok(&92));
-    /// assert_eq!(cell.get(), Some(&92))
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
-    where
-        F: FnOnce() -> Result<T, E>,
-    {
-        // Fast path check
-        // NOTE: We need to perform an acquire on the state in this method
-        // in order to correctly synchronize `SyncLazy::force`. This is
-        // currently done by calling `self.get()`, which in turn calls
-        // `self.is_initialized()`, which in turn performs the acquire.
-        if let Some(value) = self.get() {
-            return Ok(value);
-        }
-        self.initialize(f)?;
-
-        debug_assert!(self.is_initialized());
-
-        // Safety: The inner value has been initialized
-        Ok(unsafe { self.get_unchecked() })
-    }
-
-    /// Consumes the `SyncOnceCell`, returning the wrapped value. Returns
-    /// `None` if the cell was empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// let cell: SyncOnceCell<String> = SyncOnceCell::new();
-    /// assert_eq!(cell.into_inner(), None);
-    ///
-    /// let cell = SyncOnceCell::new();
-    /// cell.set("hello".to_string()).unwrap();
-    /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn into_inner(mut self) -> Option<T> {
-        // Safety: Safe because we immediately free `self` without dropping
-        let inner = unsafe { self.take_inner() };
-
-        // Don't drop this `SyncOnceCell`. We just moved out one of the fields, but didn't set
-        // the state to uninitialized.
-        mem::ManuallyDrop::new(self);
-        inner
-    }
-
-    /// Takes the value out of this `SyncOnceCell`, moving it back to an uninitialized state.
-    ///
-    /// Has no effect and returns `None` if the `SyncOnceCell` hasn't been initialized.
-    ///
-    /// Safety is guaranteed by requiring a mutable reference.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncOnceCell;
-    ///
-    /// let mut cell: SyncOnceCell<String> = SyncOnceCell::new();
-    /// assert_eq!(cell.take(), None);
-    ///
-    /// let mut cell = SyncOnceCell::new();
-    /// cell.set("hello".to_string()).unwrap();
-    /// assert_eq!(cell.take(), Some("hello".to_string()));
-    /// assert_eq!(cell.get(), None);
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn take(&mut self) -> Option<T> {
-        mem::take(self).into_inner()
-    }
-
-    /// Takes the wrapped value out of a `SyncOnceCell`.
-    /// 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() {
-            let value = mem::replace(&mut self.value, UnsafeCell::new(MaybeUninit::uninit()));
-            Some(value.into_inner().assume_init())
-        } else {
-            None
-        }
-    }
-
-    #[inline]
-    fn is_initialized(&self) -> bool {
-        self.once.is_completed()
-    }
-
-    #[cold]
-    fn initialize<F, E>(&self, f: F) -> Result<(), E>
-    where
-        F: FnOnce() -> Result<T, E>,
-    {
-        let mut res: Result<(), E> = Ok(());
-        let slot = &self.value;
-
-        // Ignore poisoning from other threads
-        // If another thread panics, then we'll be able to run our closure
-        self.once.call_once_force(|p| {
-            match f() {
-                Ok(value) => {
-                    unsafe { (&mut *slot.get()).write(value) };
-                }
-                Err(e) => {
-                    res = Err(e);
-
-                    // Treat the underlying `Once` as poisoned since we
-                    // failed to initialize our value. Calls
-                    p.poison();
-                }
-            }
-        });
-        res
-    }
-
-    /// Safety: The value must be initialized
-    unsafe fn get_unchecked(&self) -> &T {
-        debug_assert!(self.is_initialized());
-        (&*self.value.get()).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 SyncOnceCell<T> {
-    fn drop(&mut self) {
-        // Safety: The cell is being dropped, so it can't be accessed again
-        unsafe { self.take_inner() };
-    }
-}
-
-/// A value which is initialized on the first access.
-///
-/// This type is a thread-safe `Lazy`, and can be used in statics.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(once_cell)]
-///
-/// use std::collections::HashMap;
-///
-/// use std::lazy::SyncLazy;
-///
-/// static HASHMAP: SyncLazy<HashMap<i32, String>> = SyncLazy::new(|| {
-///     println!("initializing");
-///     let mut m = HashMap::new();
-///     m.insert(13, "Spica".to_string());
-///     m.insert(74, "Hoyten".to_string());
-///     m
-/// });
-///
-/// fn main() {
-///     println!("ready");
-///     std::thread::spawn(|| {
-///         println!("{:?}", HASHMAP.get(&13));
-///     }).join().unwrap();
-///     println!("{:?}", HASHMAP.get(&74));
-///
-///     // Prints:
-///     //   ready
-///     //   initializing
-///     //   Some("Spica")
-///     //   Some("Hoyten")
-/// }
-/// ```
-#[unstable(feature = "once_cell", issue = "74465")]
-pub struct SyncLazy<T, F = fn() -> T> {
-    cell: SyncOnceCell<T>,
-    init: Cell<Option<F>>,
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: fmt::Debug, F> fmt::Debug for SyncLazy<T, F> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Lazy").field("cell", &self.cell).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.
-#[unstable(feature = "once_cell", issue = "74465")]
-unsafe impl<T, F: Send> Sync for SyncLazy<T, F> where SyncOnceCell<T>: Sync {}
-// auto-derived `Send` impl is OK.
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T, F: 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.
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub const fn new(f: F) -> SyncLazy<T, F> {
-        SyncLazy { cell: SyncOnceCell::new(), init: Cell::new(Some(f)) }
-    }
-}
-
-impl<T, F: FnOnce() -> T> SyncLazy<T, F> {
-    /// Forces the evaluation of this lazy value and
-    /// returns a reference to result. This is equivalent
-    /// to the `Deref` impl, but is explicit.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(once_cell)]
-    ///
-    /// use std::lazy::SyncLazy;
-    ///
-    /// let lazy = SyncLazy::new(|| 92);
-    ///
-    /// assert_eq!(SyncLazy::force(&lazy), &92);
-    /// assert_eq!(&*lazy, &92);
-    /// ```
-    #[unstable(feature = "once_cell", issue = "74465")]
-    pub fn force(this: &SyncLazy<T, F>) -> &T {
-        this.cell.get_or_init(|| match this.init.take() {
-            Some(f) => f(),
-            None => panic!("Lazy instance has previously been poisoned"),
-        })
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {
-    type Target = T;
-    fn deref(&self) -> &T {
-        SyncLazy::force(self)
-    }
-}
-
-#[unstable(feature = "once_cell", issue = "74465")]
-impl<T: Default> Default for SyncLazy<T> {
-    /// Creates a new lazy value using `Default` as the initializing function.
-    fn default() -> SyncLazy<T> {
-        SyncLazy::new(T::default)
-    }
-}
-
-#[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.is_initialized());
-        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);
-        }
-    }
-}
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 00f2fff94c9a1..5acc24c34fee6 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -284,7 +284,6 @@
 #![feature(linkage)]
 #![feature(llvm_asm)]
 #![feature(log_syntax)]
-#![feature(maybe_uninit_extra)]
 #![feature(maybe_uninit_ref)]
 #![feature(maybe_uninit_slice)]
 #![feature(min_specialization)]
@@ -292,7 +291,6 @@
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(nll)]
-#![feature(once_cell)]
 #![feature(optin_builtin_traits)]
 #![feature(or_patterns)]
 #![feature(panic_info_message)]
@@ -477,9 +475,6 @@ pub mod process;
 pub mod sync;
 pub mod time;
 
-#[unstable(feature = "once_cell", issue = "74465")]
-pub mod lazy;
-
 #[stable(feature = "futures_api", since = "1.36.0")]
 pub mod task {
     //! Types and Traits for working with asynchronous tasks.
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 64260990824b8..7dc822db3d027 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -132,7 +132,6 @@ unsafe impl Send for Once {}
 #[derive(Debug)]
 pub struct OnceState {
     poisoned: bool,
-    set_state_on_drop_to: Cell<usize>,
 }
 
 /// Initialization value for static [`Once`] values.
@@ -322,7 +321,7 @@ impl Once {
         }
 
         let mut f = Some(f);
-        self.call_inner(true, &mut |p| f.take().unwrap()(p));
+        self.call_inner(true, &mut |p| f.take().unwrap()(&OnceState { poisoned: p }));
     }
 
     /// Returns `true` if some `call_once` call has completed
@@ -386,7 +385,7 @@ impl Once {
     // currently no way to take an `FnOnce` and call it via virtual dispatch
     // without some allocation overhead.
     #[cold]
-    fn call_inner(&self, ignore_poisoning: bool, init: &mut dyn FnMut(&OnceState)) {
+    fn call_inner(&self, ignore_poisoning: bool, init: &mut dyn FnMut(bool)) {
         let mut state_and_queue = self.state_and_queue.load(Ordering::Acquire);
         loop {
             match state_and_queue {
@@ -414,12 +413,8 @@ impl Once {
                     };
                     // Run the initialization function, letting it know if we're
                     // poisoned or not.
-                    let init_state = OnceState {
-                        poisoned: state_and_queue == POISONED,
-                        set_state_on_drop_to: Cell::new(COMPLETE),
-                    };
-                    init(&init_state);
-                    waiter_queue.set_state_on_drop_to = init_state.set_state_on_drop_to.get();
+                    init(state_and_queue == POISONED);
+                    waiter_queue.set_state_on_drop_to = COMPLETE;
                     break;
                 }
                 _ => {
@@ -559,14 +554,6 @@ impl OnceState {
     pub fn poisoned(&self) -> bool {
         self.poisoned
     }
-
-    /// Poison the associated [`Once`] without explicitly panicking.
-    ///
-    /// [`Once`]: struct.Once.html
-    // NOTE: This is currently only exposed for the `lazy` module
-    pub(crate) fn poison(&self) {
-        self.set_state_on_drop_to.set(POISONED);
-    }
 }
 
 #[cfg(all(test, not(target_os = "emscripten")))]