about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/backtrace.rs38
-rw-r--r--library/std/src/collections/hash/map.rs5
-rw-r--r--library/std/src/collections/hash/map/tests.rs6
-rw-r--r--library/std/src/collections/hash/set.rs3
-rw-r--r--library/std/src/collections/hash/set/tests.rs6
-rw-r--r--library/std/src/env.rs2
-rw-r--r--library/std/src/error.rs1023
-rw-r--r--library/std/src/io/buffered/bufreader.rs8
-rw-r--r--library/std/src/io/buffered/bufreader/buffer.rs19
-rw-r--r--library/std/src/io/buffered/tests.rs24
-rw-r--r--library/std/src/io/error.rs7
-rw-r--r--library/std/src/io/error/tests.rs2
-rw-r--r--library/std/src/io/mod.rs5
-rw-r--r--library/std/src/io/readbuf.rs9
-rw-r--r--library/std/src/io/stdio.rs57
-rw-r--r--library/std/src/keyword_docs.rs151
-rw-r--r--library/std/src/lazy.rs1
-rw-r--r--library/std/src/lib.rs22
-rw-r--r--library/std/src/os/fd/mod.rs13
-rw-r--r--library/std/src/os/fd/owned.rs75
-rw-r--r--library/std/src/os/fd/raw.rs18
-rw-r--r--library/std/src/os/mod.rs4
-rw-r--r--library/std/src/os/unix/io/fd.rs8
-rw-r--r--library/std/src/os/unix/io/mod.rs11
-rw-r--r--library/std/src/os/unix/io/raw.rs6
-rw-r--r--library/std/src/os/unix/io/tests.rs (renamed from library/std/src/os/unix/io/fd/tests.rs)0
-rw-r--r--library/std/src/os/unix/mod.rs2
-rw-r--r--library/std/src/os/wasi/io/mod.rs12
-rw-r--r--library/std/src/os/watchos/fs.rs142
-rw-r--r--library/std/src/os/watchos/mod.rs6
-rw-r--r--library/std/src/os/watchos/raw.rs83
-rw-r--r--library/std/src/os/windows/io/handle.rs17
-rw-r--r--library/std/src/panicking.rs31
-rw-r--r--library/std/src/path.rs2
-rw-r--r--library/std/src/personality/dwarf/eh.rs5
-rw-r--r--library/std/src/process.rs18
-rw-r--r--library/std/src/rt.rs5
-rw-r--r--library/std/src/sync/once.rs312
-rw-r--r--library/std/src/sync/rwlock.rs64
-rw-r--r--library/std/src/sys/common/mod.rs4
-rw-r--r--library/std/src/sys/common/small_c_string.rs58
-rw-r--r--library/std/src/sys/common/tests.rs66
-rw-r--r--library/std/src/sys/hermit/args.rs74
-rw-r--r--library/std/src/sys/hermit/fs.rs13
-rw-r--r--library/std/src/sys/hermit/mod.rs4
-rw-r--r--library/std/src/sys/mod.rs2
-rw-r--r--library/std/src/sys/sgx/abi/tls/mod.rs1
-rw-r--r--library/std/src/sys/sgx/abi/usercalls/alloc.rs28
-rw-r--r--library/std/src/sys/sgx/thread_local_key.rs5
-rw-r--r--library/std/src/sys/solid/os.rs40
-rw-r--r--library/std/src/sys/solid/thread_local_key.rs5
-rw-r--r--library/std/src/sys/unix/fs.rs393
-rw-r--r--library/std/src/sys/unix/io.rs6
-rw-r--r--library/std/src/sys/unix/kernel_copy.rs2
-rw-r--r--library/std/src/sys/unix/os.rs51
-rw-r--r--library/std/src/sys/unix/process/process_fuchsia.rs2
-rw-r--r--library/std/src/sys/unix/rand.rs94
-rw-r--r--library/std/src/sys/unix/stdio.rs50
-rw-r--r--library/std/src/sys/unix/thread.rs13
-rw-r--r--library/std/src/sys/unix/thread_local_dtor.rs1
-rw-r--r--library/std/src/sys/unix/thread_local_key.rs5
-rw-r--r--library/std/src/sys/unix/thread_parker/darwin.rs131
-rw-r--r--library/std/src/sys/unix/thread_parker/mod.rs13
-rw-r--r--library/std/src/sys/unix/time.rs34
-rw-r--r--library/std/src/sys/unsupported/io.rs4
-rw-r--r--library/std/src/sys/unsupported/locks/condvar.rs1
-rw-r--r--library/std/src/sys/unsupported/locks/mutex.rs1
-rw-r--r--library/std/src/sys/unsupported/locks/rwlock.rs1
-rw-r--r--library/std/src/sys/unsupported/thread_local_dtor.rs1
-rw-r--r--library/std/src/sys/unsupported/thread_local_key.rs5
-rw-r--r--library/std/src/sys/wasi/fs.rs105
-rw-r--r--library/std/src/sys/wasi/io.rs6
-rw-r--r--library/std/src/sys/wasi/mod.rs3
-rw-r--r--library/std/src/sys/wasi/os.rs81
-rw-r--r--library/std/src/sys/wasi/stdio.rs23
-rw-r--r--library/std/src/sys/wasi/time.rs4
-rw-r--r--library/std/src/sys/windows/c.rs31
-rw-r--r--library/std/src/sys/windows/fs.rs8
-rw-r--r--library/std/src/sys/windows/io.rs69
-rw-r--r--library/std/src/sys/windows/process.rs6
-rw-r--r--library/std/src/sys/windows/rand.rs76
-rw-r--r--library/std/src/sys/windows/thread_local_key.rs196
-rw-r--r--library/std/src/sys/windows/thread_local_key/tests.rs53
-rw-r--r--library/std/src/sys_common/backtrace.rs9
-rw-r--r--library/std/src/sys_common/condvar.rs1
-rw-r--r--library/std/src/sys_common/condvar/check.rs1
-rw-r--r--library/std/src/sys_common/mod.rs10
-rw-r--r--library/std/src/sys_common/mutex.rs45
-rw-r--r--library/std/src/sys_common/net.rs20
-rw-r--r--library/std/src/sys_common/once/futex.rs134
-rw-r--r--library/std/src/sys_common/once/generic.rs282
-rw-r--r--library/std/src/sys_common/once/mod.rs43
-rw-r--r--library/std/src/sys_common/rwlock.rs1
-rw-r--r--library/std/src/sys_common/thread_local_key.rs24
-rw-r--r--library/std/src/thread/local.rs8
-rw-r--r--library/std/src/thread/mod.rs114
-rw-r--r--library/std/src/thread/tests.rs22
-rw-r--r--library/std/src/time.rs2
98 files changed, 2398 insertions, 2309 deletions
diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs
index 354200d4c95..9cb74f951dd 100644
--- a/library/std/src/backtrace.rs
+++ b/library/std/src/backtrace.rs
@@ -14,8 +14,8 @@
 //! Backtraces are attempted to be as accurate as possible, but no guarantees
 //! are provided about the exact accuracy of a backtrace. Instruction pointers,
 //! symbol names, filenames, line numbers, etc, may all be incorrect when
-//! reported. Accuracy is attempted on a best-effort basis, however, and bugs
-//! are always welcome to indicate areas of improvement!
+//! reported. Accuracy is attempted on a best-effort basis, however, any bug
+//! reports are always welcome to indicate areas of improvement!
 //!
 //! For most platforms a backtrace with a filename/line number requires that
 //! programs be compiled with debug information. Without debug information
@@ -39,7 +39,7 @@
 //! default. Its behavior is governed by two environment variables:
 //!
 //! * `RUST_LIB_BACKTRACE` - if this is set to `0` then `Backtrace::capture`
-//!   will never capture a backtrace. Any other value this is set to will enable
+//!   will never capture a backtrace. Any other value set will enable
 //!   `Backtrace::capture`.
 //!
 //! * `RUST_BACKTRACE` - if `RUST_LIB_BACKTRACE` is not set, then this variable
@@ -58,7 +58,7 @@
 //! `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` at runtime might not actually change
 //! how backtraces are captured.
 
-#![stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+#![stable(feature = "backtrace", since = "1.65.0")]
 
 #[cfg(test)]
 mod tests;
@@ -104,7 +104,7 @@ use crate::vec::Vec;
 /// previous point in time. In some instances the `Backtrace` type may
 /// internally be empty due to configuration. For more information see
 /// `Backtrace::capture`.
-#[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "backtrace", since = "1.65.0")]
 #[must_use]
 pub struct Backtrace {
     inner: Inner,
@@ -112,21 +112,21 @@ pub struct Backtrace {
 
 /// The current status of a backtrace, indicating whether it was captured or
 /// whether it is empty for some other reason.
-#[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "backtrace", since = "1.65.0")]
 #[non_exhaustive]
 #[derive(Debug, PartialEq, Eq)]
 pub enum BacktraceStatus {
     /// Capturing a backtrace is not supported, likely because it's not
     /// implemented for the current platform.
-    #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "backtrace", since = "1.65.0")]
     Unsupported,
     /// Capturing a backtrace has been disabled through either the
     /// `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` environment variables.
-    #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "backtrace", since = "1.65.0")]
     Disabled,
     /// A backtrace has been captured and the `Backtrace` should print
     /// reasonable information when rendered.
-    #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "backtrace", since = "1.65.0")]
     Captured,
 }
 
@@ -173,7 +173,7 @@ enum BytesOrWide {
     Wide(Vec<u16>),
 }
 
-#[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "backtrace", since = "1.65.0")]
 impl fmt::Debug for Backtrace {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         let capture = match &self.inner {
@@ -289,7 +289,7 @@ impl Backtrace {
     ///
     /// To forcibly capture a backtrace regardless of environment variables, use
     /// the `Backtrace::force_capture` function.
-    #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "backtrace", since = "1.65.0")]
     #[inline(never)] // want to make sure there's a frame here to remove
     pub fn capture() -> Backtrace {
         if !Backtrace::enabled() {
@@ -308,7 +308,7 @@ impl Backtrace {
     /// Note that capturing a backtrace can be an expensive operation on some
     /// platforms, so this should be used with caution in performance-sensitive
     /// parts of code.
-    #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "backtrace", since = "1.65.0")]
     #[inline(never)] // want to make sure there's a frame here to remove
     pub fn force_capture() -> Backtrace {
         Backtrace::create(Backtrace::force_capture as usize)
@@ -316,8 +316,8 @@ impl Backtrace {
 
     /// Forcibly captures a disabled backtrace, regardless of environment
     /// variable configuration.
-    #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "backtrace", since = "1.65.0")]
+    #[rustc_const_stable(feature = "backtrace", since = "1.65.0")]
     pub const fn disabled() -> Backtrace {
         Backtrace { inner: Inner::Disabled }
     }
@@ -325,8 +325,7 @@ impl Backtrace {
     // Capture a backtrace which start just before the function addressed by
     // `ip`
     fn create(ip: usize) -> Backtrace {
-        // SAFETY: We don't attempt to lock this reentrantly.
-        let _lock = unsafe { lock() };
+        let _lock = lock();
         let mut frames = Vec::new();
         let mut actual_start = None;
         unsafe {
@@ -361,7 +360,7 @@ impl Backtrace {
     /// Returns the status of this backtrace, indicating whether this backtrace
     /// request was unsupported, disabled, or a stack trace was actually
     /// captured.
-    #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "backtrace", since = "1.65.0")]
     #[must_use]
     pub fn status(&self) -> BacktraceStatus {
         match self.inner {
@@ -381,7 +380,7 @@ impl<'a> Backtrace {
     }
 }
 
-#[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "backtrace", since = "1.65.0")]
 impl fmt::Display for Backtrace {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         let capture = match &self.inner {
@@ -469,8 +468,7 @@ impl Capture {
         // Use the global backtrace lock to synchronize this as it's a
         // requirement of the `backtrace` crate, and then actually resolve
         // everything.
-        // SAFETY: We don't attempt to lock this reentrantly.
-        let _lock = unsafe { lock() };
+        let _lock = lock();
         for frame in self.frames.iter_mut() {
             let symbols = &mut frame.symbols;
             let frame = match &frame.frame {
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 9845d1faf9a..34983b976e3 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -9,7 +9,6 @@ use crate::borrow::Borrow;
 use crate::cell::Cell;
 use crate::collections::TryReserveError;
 use crate::collections::TryReserveErrorKind;
-#[cfg(not(bootstrap))]
 use crate::error::Error;
 use crate::fmt::{self, Debug};
 #[allow(deprecated)]
@@ -281,7 +280,8 @@ impl<K, V, S> HashMap<K, V, S> {
     /// ```
     #[inline]
     #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-    pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
+    #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")]
+    pub const fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
         HashMap { base: base::HashMap::with_hasher(hash_builder) }
     }
 
@@ -2160,7 +2160,6 @@ impl<'a, K: Debug, V: Debug> fmt::Display for OccupiedError<'a, K, V> {
     }
 }
 
-#[cfg(not(bootstrap))]
 #[unstable(feature = "map_try_insert", issue = "82766")]
 impl<'a, K: fmt::Debug, V: fmt::Debug> Error for OccupiedError<'a, K, V> {
     #[allow(deprecated)]
diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs
index cb3032719fa..65634f2063f 100644
--- a/library/std/src/collections/hash/map/tests.rs
+++ b/library/std/src/collections/hash/map/tests.rs
@@ -1115,3 +1115,9 @@ fn from_array() {
     // that's a problem!
     let _must_not_require_type_annotation = HashMap::from([(1, 2)]);
 }
+
+#[test]
+fn const_with_hasher() {
+    const X: HashMap<(), (), ()> = HashMap::with_hasher(());
+    assert_eq!(X.len(), 0);
+}
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 5b6a415fadc..c36eeae3388 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -376,7 +376,8 @@ impl<T, S> HashSet<T, S> {
     /// ```
     #[inline]
     #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-    pub fn with_hasher(hasher: S) -> HashSet<T, S> {
+    #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")]
+    pub const fn with_hasher(hasher: S) -> HashSet<T, S> {
         HashSet { base: base::HashSet::with_hasher(hasher) }
     }
 
diff --git a/library/std/src/collections/hash/set/tests.rs b/library/std/src/collections/hash/set/tests.rs
index 233db276b9e..941a0450cc7 100644
--- a/library/std/src/collections/hash/set/tests.rs
+++ b/library/std/src/collections/hash/set/tests.rs
@@ -496,3 +496,9 @@ fn from_array() {
     // that's a problem!
     let _must_not_require_type_annotation = HashSet::from([1, 2]);
 }
+
+#[test]
+fn const_with_hasher() {
+    const X: HashSet<(), ()> = HashSet::with_hasher(());
+    assert_eq!(X.len(), 0);
+}
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 463f714064c..6eb7cbea626 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -603,7 +603,7 @@ pub fn home_dir() -> Option<PathBuf> {
 /// # Platform-specific behavior
 ///
 /// On Unix, returns the value of the `TMPDIR` environment variable if it is
-/// set, otherwise for non-Android it returns `/tmp`. If Android, since there
+/// set, otherwise for non-Android it returns `/tmp`. On Android, since there
 /// is no global temporary folder (it is usually allocated per-app), it returns
 /// `/data/local/tmp`.
 /// On Windows, the behavior is equivalent to that of [`GetTempPath2`][GetTempPath2] /
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index e4505959536..05f8fd8de32 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -4,242 +4,12 @@
 #[cfg(test)]
 mod tests;
 
-#[cfg(bootstrap)]
-use core::array;
-#[cfg(bootstrap)]
-use core::convert::Infallible;
-
-#[cfg(bootstrap)]
-use crate::alloc::{AllocError, LayoutError};
-#[cfg(bootstrap)]
-use crate::any::Demand;
-#[cfg(bootstrap)]
-use crate::any::{Provider, TypeId};
 use crate::backtrace::Backtrace;
-#[cfg(bootstrap)]
-use crate::borrow::Cow;
-#[cfg(bootstrap)]
-use crate::cell;
-#[cfg(bootstrap)]
-use crate::char;
-#[cfg(bootstrap)]
-use crate::fmt::Debug;
-#[cfg(bootstrap)]
-use crate::fmt::Display;
 use crate::fmt::{self, Write};
-#[cfg(bootstrap)]
-use crate::io;
-#[cfg(bootstrap)]
-use crate::mem::transmute;
-#[cfg(bootstrap)]
-use crate::num;
-#[cfg(bootstrap)]
-use crate::str;
-#[cfg(bootstrap)]
-use crate::string;
-#[cfg(bootstrap)]
-use crate::sync::Arc;
-#[cfg(bootstrap)]
-use crate::time;
 
-#[cfg(not(bootstrap))]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::error::Error;
 
-/// `Error` is a trait representing the basic expectations for error values,
-/// i.e., values of type `E` in [`Result<T, E>`].
-///
-/// Errors must describe themselves through the [`Display`] and [`Debug`]
-/// traits. Error messages are typically concise lowercase sentences without
-/// trailing punctuation:
-///
-/// ```
-/// let err = "NaN".parse::<u32>().unwrap_err();
-/// assert_eq!(err.to_string(), "invalid digit found in string");
-/// ```
-///
-/// Errors may provide cause information. [`Error::source()`] is generally
-/// used when errors cross "abstraction boundaries". If one module must report
-/// an error that is caused by an error from a lower-level module, it can allow
-/// accessing that error via [`Error::source()`]. This makes it possible for the
-/// high-level module to provide its own errors while also revealing some of the
-/// implementation for debugging.
-#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(test), rustc_diagnostic_item = "Error")]
-#[cfg(bootstrap)]
-pub trait Error: Debug + Display {
-    /// The lower-level source of this error, if any.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::error::Error;
-    /// use std::fmt;
-    ///
-    /// #[derive(Debug)]
-    /// struct SuperError {
-    ///     source: SuperErrorSideKick,
-    /// }
-    ///
-    /// impl fmt::Display for SuperError {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "SuperError is here!")
-    ///     }
-    /// }
-    ///
-    /// impl Error for SuperError {
-    ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
-    ///         Some(&self.source)
-    ///     }
-    /// }
-    ///
-    /// #[derive(Debug)]
-    /// struct SuperErrorSideKick;
-    ///
-    /// impl fmt::Display for SuperErrorSideKick {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "SuperErrorSideKick is here!")
-    ///     }
-    /// }
-    ///
-    /// impl Error for SuperErrorSideKick {}
-    ///
-    /// fn get_super_error() -> Result<(), SuperError> {
-    ///     Err(SuperError { source: SuperErrorSideKick })
-    /// }
-    ///
-    /// fn main() {
-    ///     match get_super_error() {
-    ///         Err(e) => {
-    ///             println!("Error: {e}");
-    ///             println!("Caused by: {}", e.source().unwrap());
-    ///         }
-    ///         _ => println!("No error"),
-    ///     }
-    /// }
-    /// ```
-    #[stable(feature = "error_source", since = "1.30.0")]
-    fn source(&self) -> Option<&(dyn Error + 'static)> {
-        None
-    }
-
-    /// Gets the `TypeId` of `self`.
-    #[doc(hidden)]
-    #[unstable(
-        feature = "error_type_id",
-        reason = "this is memory-unsafe to override in user code",
-        issue = "60784"
-    )]
-    fn type_id(&self, _: private::Internal) -> TypeId
-    where
-        Self: 'static,
-    {
-        TypeId::of::<Self>()
-    }
-
-    /// ```
-    /// if let Err(e) = "xc".parse::<u32>() {
-    ///     // Print `e` itself, no need for description().
-    ///     eprintln!("Error: {e}");
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.42.0", note = "use the Display impl or to_string()")]
-    fn description(&self) -> &str {
-        "description() is deprecated; use Display"
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(
-        since = "1.33.0",
-        note = "replaced by Error::source, which can support downcasting"
-    )]
-    #[allow(missing_docs)]
-    fn cause(&self) -> Option<&dyn Error> {
-        self.source()
-    }
-
-    /// Provides type based access to context intended for error reports.
-    ///
-    /// Used in conjunction with [`Demand::provide_value`] and [`Demand::provide_ref`] to extract
-    /// references to member variables from `dyn Error` trait objects.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// #![feature(provide_any)]
-    /// #![feature(error_generic_member_access)]
-    /// use core::fmt;
-    /// use core::any::Demand;
-    ///
-    /// #[derive(Debug)]
-    /// struct MyBacktrace {
-    ///     // ...
-    /// }
-    ///
-    /// impl MyBacktrace {
-    ///     fn new() -> MyBacktrace {
-    ///         // ...
-    ///         # MyBacktrace {}
-    ///     }
-    /// }
-    ///
-    /// #[derive(Debug)]
-    /// struct SourceError {
-    ///     // ...
-    /// }
-    ///
-    /// impl fmt::Display for SourceError {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "Example Source Error")
-    ///     }
-    /// }
-    ///
-    /// impl std::error::Error for SourceError {}
-    ///
-    /// #[derive(Debug)]
-    /// struct Error {
-    ///     source: SourceError,
-    ///     backtrace: MyBacktrace,
-    /// }
-    ///
-    /// impl fmt::Display for Error {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "Example Error")
-    ///     }
-    /// }
-    ///
-    /// impl std::error::Error for Error {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         demand
-    ///             .provide_ref::<MyBacktrace>(&self.backtrace)
-    ///             .provide_ref::<dyn std::error::Error + 'static>(&self.source);
-    ///     }
-    /// }
-    ///
-    /// fn main() {
-    ///     let backtrace = MyBacktrace::new();
-    ///     let source = SourceError {};
-    ///     let error = Error { source, backtrace };
-    ///     let dyn_error = &error as &dyn std::error::Error;
-    ///     let backtrace_ref = dyn_error.request_ref::<MyBacktrace>().unwrap();
-    ///
-    ///     assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
-    /// }
-    /// ```
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    #[allow(unused_variables)]
-    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {}
-}
-
-#[cfg(bootstrap)]
-#[unstable(feature = "error_generic_member_access", issue = "99301")]
-impl<'b> Provider for dyn Error + 'b {
-    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-        self.provide(demand)
-    }
-}
-
 mod private {
     // This is a hack to prevent `type_id` from being overridden by `Error`
     // implementations, since that can enable unsound downcasting.
@@ -248,799 +18,6 @@ mod private {
     pub struct Internal;
 }
 
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
-    /// Converts a type of [`Error`] into a box of dyn [`Error`].
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::error::Error;
-    /// use std::fmt;
-    /// use std::mem;
-    ///
-    /// #[derive(Debug)]
-    /// struct AnError;
-    ///
-    /// impl fmt::Display for AnError {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "An error")
-    ///     }
-    /// }
-    ///
-    /// impl Error for AnError {}
-    ///
-    /// let an_error = AnError;
-    /// assert!(0 == mem::size_of_val(&an_error));
-    /// let a_boxed_error = Box::<dyn Error>::from(an_error);
-    /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
-    /// ```
-    fn from(err: E) -> Box<dyn Error + 'a> {
-        Box::new(err)
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
-    /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
-    /// dyn [`Error`] + [`Send`] + [`Sync`].
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::error::Error;
-    /// use std::fmt;
-    /// use std::mem;
-    ///
-    /// #[derive(Debug)]
-    /// struct AnError;
-    ///
-    /// impl fmt::Display for AnError {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "An error")
-    ///     }
-    /// }
-    ///
-    /// impl Error for AnError {}
-    ///
-    /// unsafe impl Send for AnError {}
-    ///
-    /// unsafe impl Sync for AnError {}
-    ///
-    /// let an_error = AnError;
-    /// assert!(0 == mem::size_of_val(&an_error));
-    /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
-    /// assert!(
-    ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
-    /// ```
-    fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
-        Box::new(err)
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl From<String> for Box<dyn Error + Send + Sync> {
-    /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::error::Error;
-    /// use std::mem;
-    ///
-    /// let a_string_error = "a string error".to_string();
-    /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
-    /// assert!(
-    ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
-    /// ```
-    #[inline]
-    fn from(err: String) -> Box<dyn Error + Send + Sync> {
-        struct StringError(String);
-
-        impl Error for StringError {
-            #[allow(deprecated)]
-            fn description(&self) -> &str {
-                &self.0
-            }
-        }
-
-        impl Display for StringError {
-            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                Display::fmt(&self.0, f)
-            }
-        }
-
-        // Purposefully skip printing "StringError(..)"
-        impl Debug for StringError {
-            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                Debug::fmt(&self.0, f)
-            }
-        }
-
-        Box::new(StringError(err))
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "string_box_error", since = "1.6.0")]
-impl From<String> for Box<dyn Error> {
-    /// Converts a [`String`] into a box of dyn [`Error`].
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::error::Error;
-    /// use std::mem;
-    ///
-    /// let a_string_error = "a string error".to_string();
-    /// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
-    /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
-    /// ```
-    fn from(str_err: String) -> Box<dyn Error> {
-        let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
-        let err2: Box<dyn Error> = err1;
-        err2
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
-    /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
-    ///
-    /// [`str`]: prim@str
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::error::Error;
-    /// use std::mem;
-    ///
-    /// let a_str_error = "a str error";
-    /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
-    /// assert!(
-    ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
-    /// ```
-    #[inline]
-    fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
-        From::from(String::from(err))
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "string_box_error", since = "1.6.0")]
-impl From<&str> for Box<dyn Error> {
-    /// Converts a [`str`] into a box of dyn [`Error`].
-    ///
-    /// [`str`]: prim@str
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::error::Error;
-    /// use std::mem;
-    ///
-    /// let a_str_error = "a str error";
-    /// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
-    /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
-    /// ```
-    fn from(err: &str) -> Box<dyn Error> {
-        From::from(String::from(err))
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "cow_box_error", since = "1.22.0")]
-impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
-    /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::error::Error;
-    /// use std::mem;
-    /// use std::borrow::Cow;
-    ///
-    /// let a_cow_str_error = Cow::from("a str error");
-    /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
-    /// assert!(
-    ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
-    /// ```
-    fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
-        From::from(String::from(err))
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "cow_box_error", since = "1.22.0")]
-impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
-    /// Converts a [`Cow`] into a box of dyn [`Error`].
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::error::Error;
-    /// use std::mem;
-    /// use std::borrow::Cow;
-    ///
-    /// let a_cow_str_error = Cow::from("a str error");
-    /// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
-    /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
-    /// ```
-    fn from(err: Cow<'a, str>) -> Box<dyn Error> {
-        From::from(String::from(err))
-    }
-}
-
-#[cfg(bootstrap)]
-#[unstable(feature = "never_type", issue = "35121")]
-impl Error for ! {}
-
-#[cfg(bootstrap)]
-#[unstable(
-    feature = "allocator_api",
-    reason = "the precise API and guarantees it provides may be tweaked.",
-    issue = "32838"
-)]
-impl Error for AllocError {}
-
-#[cfg(bootstrap)]
-#[stable(feature = "alloc_layout", since = "1.28.0")]
-impl Error for LayoutError {}
-
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for str::ParseBoolError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "failed to parse bool"
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for str::Utf8Error {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "invalid utf-8: corrupt contents"
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for num::ParseIntError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        self.__description()
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "try_from", since = "1.34.0")]
-impl Error for num::TryFromIntError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        self.__description()
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "try_from", since = "1.34.0")]
-impl Error for array::TryFromSliceError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        self.__description()
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for num::ParseFloatError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        self.__description()
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for string::FromUtf8Error {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "invalid utf-8"
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for string::FromUtf16Error {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "invalid utf-16"
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "str_parse_error2", since = "1.8.0")]
-impl Error for Infallible {
-    fn description(&self) -> &str {
-        match *self {}
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "decode_utf16", since = "1.9.0")]
-impl Error for char::DecodeUtf16Error {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "unpaired surrogate found"
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "u8_from_char", since = "1.59.0")]
-impl Error for char::TryFromCharError {}
-
-#[cfg(bootstrap)]
-#[unstable(feature = "map_try_insert", issue = "82766")]
-impl<'a, K: Debug + Ord, V: Debug> Error
-    for crate::collections::btree_map::OccupiedError<'a, K, V>
-{
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "key already exists"
-    }
-}
-
-#[cfg(bootstrap)]
-#[unstable(feature = "map_try_insert", issue = "82766")]
-impl<'a, K: Debug, V: Debug> Error for crate::collections::hash_map::OccupiedError<'a, K, V> {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "key already exists"
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "box_error", since = "1.8.0")]
-impl<T: Error> Error for Box<T> {
-    #[allow(deprecated, deprecated_in_future)]
-    fn description(&self) -> &str {
-        Error::description(&**self)
-    }
-
-    #[allow(deprecated)]
-    fn cause(&self) -> Option<&dyn Error> {
-        Error::cause(&**self)
-    }
-
-    fn source(&self) -> Option<&(dyn Error + 'static)> {
-        Error::source(&**self)
-    }
-}
-
-#[cfg(bootstrap)]
-#[unstable(feature = "thin_box", issue = "92791")]
-impl<T: ?Sized + crate::error::Error> crate::error::Error for crate::boxed::ThinBox<T> {
-    fn source(&self) -> Option<&(dyn crate::error::Error + 'static)> {
-        use core::ops::Deref;
-        self.deref().source()
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "error_by_ref", since = "1.51.0")]
-impl<'a, T: Error + ?Sized> Error for &'a T {
-    #[allow(deprecated, deprecated_in_future)]
-    fn description(&self) -> &str {
-        Error::description(&**self)
-    }
-
-    #[allow(deprecated)]
-    fn cause(&self) -> Option<&dyn Error> {
-        Error::cause(&**self)
-    }
-
-    fn source(&self) -> Option<&(dyn Error + 'static)> {
-        Error::source(&**self)
-    }
-
-    fn provide<'b>(&'b self, demand: &mut Demand<'b>) {
-        Error::provide(&**self, demand);
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "arc_error", since = "1.52.0")]
-impl<T: Error + ?Sized> Error for Arc<T> {
-    #[allow(deprecated, deprecated_in_future)]
-    fn description(&self) -> &str {
-        Error::description(&**self)
-    }
-
-    #[allow(deprecated)]
-    fn cause(&self) -> Option<&dyn Error> {
-        Error::cause(&**self)
-    }
-
-    fn source(&self) -> Option<&(dyn Error + 'static)> {
-        Error::source(&**self)
-    }
-
-    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-        Error::provide(&**self, demand);
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "fmt_error", since = "1.11.0")]
-impl Error for fmt::Error {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "an error occurred when formatting an argument"
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "try_borrow", since = "1.13.0")]
-impl Error for cell::BorrowError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "already mutably borrowed"
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "try_borrow", since = "1.13.0")]
-impl Error for cell::BorrowMutError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "already borrowed"
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "try_from", since = "1.34.0")]
-impl Error for char::CharTryFromError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "converted integer out of range for `char`"
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "char_from_str", since = "1.20.0")]
-impl Error for char::ParseCharError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        self.__description()
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "try_reserve", since = "1.57.0")]
-impl Error for alloc::collections::TryReserveError {}
-
-#[cfg(bootstrap)]
-#[unstable(feature = "duration_checked_float", issue = "83400")]
-impl Error for time::FromFloatSecsError {}
-
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for alloc::ffi::NulError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "nul byte found in data"
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl From<alloc::ffi::NulError> for io::Error {
-    /// Converts a [`alloc::ffi::NulError`] into a [`io::Error`].
-    fn from(_: alloc::ffi::NulError) -> io::Error {
-        io::const_io_error!(io::ErrorKind::InvalidInput, "data provided contains a nul byte")
-    }
-}
-
-#[cfg(bootstrap)]
-#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
-impl Error for core::ffi::FromBytesWithNulError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        self.__description()
-    }
-}
-
-#[cfg(bootstrap)]
-#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
-impl Error for core::ffi::FromBytesUntilNulError {}
-
-#[cfg(bootstrap)]
-#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
-impl Error for alloc::ffi::FromVecWithNulError {}
-
-#[cfg(bootstrap)]
-#[stable(feature = "cstring_into", since = "1.7.0")]
-impl Error for alloc::ffi::IntoStringError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "C string contained non-utf8 bytes"
-    }
-
-    fn source(&self) -> Option<&(dyn Error + 'static)> {
-        Some(self.__source())
-    }
-}
-
-#[cfg(bootstrap)]
-impl<'a> dyn Error + 'a {
-    /// Request a reference of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_ref<T: ?Sized + 'static>(&'a self) -> Option<&'a T> {
-        core::any::request_ref(self)
-    }
-
-    /// Request a value of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_value<T: 'static>(&'a self) -> Option<T> {
-        core::any::request_value(self)
-    }
-}
-
-// Copied from `any.rs`.
-#[cfg(bootstrap)]
-impl dyn Error + 'static {
-    /// Returns `true` if the inner type is the same as `T`.
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    #[inline]
-    pub fn is<T: Error + 'static>(&self) -> bool {
-        // Get `TypeId` of the type this function is instantiated with.
-        let t = TypeId::of::<T>();
-
-        // Get `TypeId` of the type in the trait object (`self`).
-        let concrete = self.type_id(private::Internal);
-
-        // Compare both `TypeId`s on equality.
-        t == concrete
-    }
-
-    /// Returns some reference to the inner value if it is of type `T`, or
-    /// `None` if it isn't.
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    #[inline]
-    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
-        if self.is::<T>() {
-            unsafe { Some(&*(self as *const dyn Error as *const T)) }
-        } else {
-            None
-        }
-    }
-
-    /// Returns some mutable reference to the inner value if it is of type `T`, or
-    /// `None` if it isn't.
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    #[inline]
-    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
-        if self.is::<T>() {
-            unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) }
-        } else {
-            None
-        }
-    }
-}
-
-#[cfg(bootstrap)]
-impl dyn Error + 'static + Send {
-    /// Forwards to the method defined on the type `dyn Error`.
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    #[inline]
-    pub fn is<T: Error + 'static>(&self) -> bool {
-        <dyn Error + 'static>::is::<T>(self)
-    }
-
-    /// Forwards to the method defined on the type `dyn Error`.
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    #[inline]
-    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
-        <dyn Error + 'static>::downcast_ref::<T>(self)
-    }
-
-    /// Forwards to the method defined on the type `dyn Error`.
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    #[inline]
-    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
-        <dyn Error + 'static>::downcast_mut::<T>(self)
-    }
-
-    /// Request a reference of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
-        <dyn Error>::request_ref(self)
-    }
-
-    /// Request a value of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_value<T: 'static>(&self) -> Option<T> {
-        <dyn Error>::request_value(self)
-    }
-}
-
-#[cfg(bootstrap)]
-impl dyn Error + 'static + Send + Sync {
-    /// Forwards to the method defined on the type `dyn Error`.
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    #[inline]
-    pub fn is<T: Error + 'static>(&self) -> bool {
-        <dyn Error + 'static>::is::<T>(self)
-    }
-
-    /// Forwards to the method defined on the type `dyn Error`.
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    #[inline]
-    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
-        <dyn Error + 'static>::downcast_ref::<T>(self)
-    }
-
-    /// Forwards to the method defined on the type `dyn Error`.
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    #[inline]
-    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
-        <dyn Error + 'static>::downcast_mut::<T>(self)
-    }
-
-    /// Request a reference of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
-        <dyn Error>::request_ref(self)
-    }
-
-    /// Request a value of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_value<T: 'static>(&self) -> Option<T> {
-        <dyn Error>::request_value(self)
-    }
-}
-
-#[cfg(bootstrap)]
-impl dyn Error {
-    #[inline]
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    /// Attempts to downcast the box to a concrete type.
-    pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {
-        if self.is::<T>() {
-            unsafe {
-                let raw: *mut dyn Error = Box::into_raw(self);
-                Ok(Box::from_raw(raw as *mut T))
-            }
-        } else {
-            Err(self)
-        }
-    }
-
-    /// Returns an iterator starting with the current error and continuing with
-    /// recursively calling [`Error::source`].
-    ///
-    /// If you want to omit the current error and only use its sources,
-    /// use `skip(1)`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(error_iter)]
-    /// use std::error::Error;
-    /// use std::fmt;
-    ///
-    /// #[derive(Debug)]
-    /// struct A;
-    ///
-    /// #[derive(Debug)]
-    /// struct B(Option<Box<dyn Error + 'static>>);
-    ///
-    /// impl fmt::Display for A {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "A")
-    ///     }
-    /// }
-    ///
-    /// impl fmt::Display for B {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "B")
-    ///     }
-    /// }
-    ///
-    /// impl Error for A {}
-    ///
-    /// impl Error for B {
-    ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
-    ///         self.0.as_ref().map(|e| e.as_ref())
-    ///     }
-    /// }
-    ///
-    /// let b = B(Some(Box::new(A)));
-    ///
-    /// // let err : Box<Error> = b.into(); // or
-    /// let err = &b as &(dyn Error);
-    ///
-    /// let mut iter = err.sources();
-    ///
-    /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
-    /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
-    /// assert!(iter.next().is_none());
-    /// assert!(iter.next().is_none());
-    /// ```
-    #[unstable(feature = "error_iter", issue = "58520")]
-    #[inline]
-    pub fn sources(&self) -> Sources<'_> {
-        // You may think this method would be better in the Error trait, and you'd be right.
-        // Unfortunately that doesn't work, not because of the object safety rules but because we
-        // save a reference to self in Sources below as a trait object. If this method was
-        // declared in Error, then self would have the type &T where T is some concrete type which
-        // implements Error. We would need to coerce self to have type &dyn Error, but that requires
-        // that Self has a known size (i.e., Self: Sized). We can't put that bound on Error
-        // since that would forbid Error trait objects, and we can't put that bound on the method
-        // because that means the method can't be called on trait objects (we'd also need the
-        // 'static bound, but that isn't allowed because methods with bounds on Self other than
-        // Sized are not object-safe). Requiring an Unsize bound is not backwards compatible.
-
-        Sources { current: Some(self) }
-    }
-}
-
-/// An iterator over an [`Error`] and its sources.
-///
-/// If you want to omit the initial error and only process
-/// its sources, use `skip(1)`.
-#[unstable(feature = "error_iter", issue = "58520")]
-#[derive(Clone, Debug)]
-#[cfg(bootstrap)]
-pub struct Sources<'a> {
-    current: Option<&'a (dyn Error + 'static)>,
-}
-
-#[cfg(bootstrap)]
-#[unstable(feature = "error_iter", issue = "58520")]
-impl<'a> Iterator for Sources<'a> {
-    type Item = &'a (dyn Error + 'static);
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let current = self.current;
-        self.current = self.current.and_then(Error::source);
-        current
-    }
-}
-
-#[cfg(bootstrap)]
-impl dyn Error + Send {
-    #[inline]
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    /// Attempts to downcast the box to a concrete type.
-    pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
-        let err: Box<dyn Error> = self;
-        <dyn Error>::downcast(err).map_err(|s| unsafe {
-            // Reapply the `Send` marker.
-            transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
-        })
-    }
-}
-
-#[cfg(bootstrap)]
-impl dyn Error + Send + Sync {
-    #[inline]
-    #[stable(feature = "error_downcast", since = "1.3.0")]
-    /// Attempts to downcast the box to a concrete type.
-    pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
-        let err: Box<dyn Error> = self;
-        <dyn Error>::downcast(err).map_err(|s| unsafe {
-            // Reapply the `Send + Sync` marker.
-            transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
-        })
-    }
-}
-
 /// An error reporter that prints an error and its sources.
 ///
 /// Report also exposes configuration options for formatting the error sources, either entirely on a
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index 88ad92d8a98..4f339a18a48 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -224,6 +224,14 @@ impl<R> BufReader<R> {
     }
 }
 
+// This is only used by a test which asserts that the initialization-tracking is correct.
+#[cfg(test)]
+impl<R> BufReader<R> {
+    pub fn initialized(&self) -> usize {
+        self.buf.initialized()
+    }
+}
+
 impl<R: Seek> BufReader<R> {
     /// Seeks relative to the current position. If the new position lies within the buffer,
     /// the buffer will not be flushed, allowing for more efficient seeks.
diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs
index 867c22c6041..e9e29d60ca2 100644
--- a/library/std/src/io/buffered/bufreader/buffer.rs
+++ b/library/std/src/io/buffered/bufreader/buffer.rs
@@ -20,13 +20,19 @@ pub struct Buffer {
     // Each call to `fill_buf` sets `filled` to indicate how many bytes at the start of `buf` are
     // initialized with bytes from a read.
     filled: usize,
+    // This is the max number of bytes returned across all `fill_buf` calls. We track this so that we
+    // can accurately tell `read_buf` how many bytes of buf are initialized, to bypass as much of its
+    // defensive initialization as possible. Note that while this often the same as `filled`, it
+    // doesn't need to be. Calls to `fill_buf` are not required to actually fill the buffer, and
+    // omitting this is a huge perf regression for `Read` impls that do not.
+    initialized: usize,
 }
 
 impl Buffer {
     #[inline]
     pub fn with_capacity(capacity: usize) -> Self {
         let buf = Box::new_uninit_slice(capacity);
-        Self { buf, pos: 0, filled: 0 }
+        Self { buf, pos: 0, filled: 0, initialized: 0 }
     }
 
     #[inline]
@@ -51,6 +57,12 @@ impl Buffer {
         self.pos
     }
 
+    // This is only used by a test which asserts that the initialization-tracking is correct.
+    #[cfg(test)]
+    pub fn initialized(&self) -> usize {
+        self.initialized
+    }
+
     #[inline]
     pub fn discard_buffer(&mut self) {
         self.pos = 0;
@@ -96,13 +108,14 @@ impl Buffer {
             let mut buf = BorrowedBuf::from(&mut *self.buf);
             // SAFETY: `self.filled` bytes will always have been initialized.
             unsafe {
-                buf.set_init(self.filled);
+                buf.set_init(self.initialized);
             }
 
             reader.read_buf(buf.unfilled())?;
 
-            self.filled = buf.len();
             self.pos = 0;
+            self.filled = buf.len();
+            self.initialized = buf.init_len();
         }
         Ok(self.buffer())
     }
diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs
index bd6d95242ad..f4e688eb926 100644
--- a/library/std/src/io/buffered/tests.rs
+++ b/library/std/src/io/buffered/tests.rs
@@ -1039,3 +1039,27 @@ fn single_formatted_write() {
     writeln!(&mut writer, "{}, {}!", "hello", "world").unwrap();
     assert_eq!(writer.get_ref().events, [RecordedEvent::Write("hello, world!\n".to_string())]);
 }
+
+#[test]
+fn bufreader_full_initialize() {
+    struct OneByteReader;
+    impl Read for OneByteReader {
+        fn read(&mut self, buf: &mut [u8]) -> crate::io::Result<usize> {
+            if buf.len() > 0 {
+                buf[0] = 0;
+                Ok(1)
+            } else {
+                Ok(0)
+            }
+        }
+    }
+    let mut reader = BufReader::new(OneByteReader);
+    // Nothing is initialized yet.
+    assert_eq!(reader.initialized(), 0);
+
+    let buf = reader.fill_buf().unwrap();
+    // We read one byte...
+    assert_eq!(buf.len(), 1);
+    // But we initialized the whole buffer!
+    assert_eq!(reader.initialized(), reader.capacity());
+}
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index 29b09fcc527..3cabf24492e 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -76,7 +76,6 @@ impl fmt::Debug for Error {
     }
 }
 
-#[cfg(not(bootstrap))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl From<alloc::ffi::NulError> for Error {
     /// Converts a [`alloc::ffi::NulError`] into a [`Error`].
@@ -388,7 +387,7 @@ pub enum ErrorKind {
 impl ErrorKind {
     pub(crate) fn as_str(&self) -> &'static str {
         use ErrorKind::*;
-        // Strictly alphabetical, please.  (Sadly rustfmt cannot do this yet.)
+        // tidy-alphabetical-start
         match *self {
             AddrInUse => "address in use",
             AddrNotAvailable => "address not available",
@@ -432,6 +431,7 @@ impl ErrorKind {
             WouldBlock => "operation would block",
             WriteZero => "write zero",
         }
+        // tidy-alphabetical-end
     }
 }
 
@@ -482,6 +482,7 @@ impl Error {
     /// originate from the OS itself. The `error` argument is an arbitrary
     /// payload which will be contained in this [`Error`].
     ///
+    /// Note that this function allocates memory on the heap.
     /// If no extra payload is required, use the `From` conversion from
     /// `ErrorKind`.
     ///
@@ -496,7 +497,7 @@ impl Error {
     /// // errors can also be created from other errors
     /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
     ///
-    /// // creating an error without payload
+    /// // creating an error without payload (and without memory allocation)
     /// let eof_error = Error::from(ErrorKind::UnexpectedEof);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs
index c897a5e8701..16c634e9afd 100644
--- a/library/std/src/io/error/tests.rs
+++ b/library/std/src/io/error/tests.rs
@@ -86,7 +86,7 @@ fn test_errorkind_packing() {
     assert_eq!(Error::from(ErrorKind::NotFound).kind(), ErrorKind::NotFound);
     assert_eq!(Error::from(ErrorKind::PermissionDenied).kind(), ErrorKind::PermissionDenied);
     assert_eq!(Error::from(ErrorKind::Uncategorized).kind(), ErrorKind::Uncategorized);
-    // Check that the innards look like like what we want.
+    // Check that the innards look like what we want.
     assert_matches!(
         Error::from(ErrorKind::OutOfMemory).repr.data(),
         ErrorData::Simple(ErrorKind::OutOfMemory),
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 01a3873c75c..0c29b001f01 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -262,9 +262,12 @@ use crate::sys_common::memchr;
 
 #[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
 pub use self::buffered::WriterPanicked;
+pub(crate) use self::stdio::attempt_print_to_stderr;
 #[unstable(feature = "internal_output_capture", issue = "none")]
 #[doc(no_inline, hidden)]
 pub use self::stdio::set_output_capture;
+#[unstable(feature = "is_terminal", issue = "98070")]
+pub use self::stdio::IsTerminal;
 #[unstable(feature = "print_internals", issue = "none")]
 pub use self::stdio::{_eprint, _print};
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1045,7 +1048,7 @@ pub trait Read {
 ///     Ok(())
 /// }
 /// ```
-#[stable(feature = "io_read_to_string", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "io_read_to_string", since = "1.65.0")]
 pub fn read_to_string<R: Read>(mut reader: R) -> Result<String> {
     let mut buf = String::new();
     reader.read_to_string(&mut buf)?;
diff --git a/library/std/src/io/readbuf.rs b/library/std/src/io/readbuf.rs
index b1a84095f13..4800eeda022 100644
--- a/library/std/src/io/readbuf.rs
+++ b/library/std/src/io/readbuf.rs
@@ -3,10 +3,10 @@
 #[cfg(test)]
 mod tests;
 
-use crate::cmp;
 use crate::fmt::{self, Debug, Formatter};
 use crate::io::{Result, Write};
 use crate::mem::{self, MaybeUninit};
+use crate::{cmp, ptr};
 
 /// A borrowed byte buffer which is incrementally filled and initialized.
 ///
@@ -250,8 +250,11 @@ impl<'a> BorrowedCursor<'a> {
     /// Initializes all bytes in the cursor.
     #[inline]
     pub fn ensure_init(&mut self) -> &mut Self {
-        for byte in self.uninit_mut() {
-            byte.write(0);
+        let uninit = self.uninit_mut();
+        // SAFETY: 0 is a valid value for MaybeUninit<u8> and the length matches the allocation
+        // since it is comes from a slice reference.
+        unsafe {
+            ptr::write_bytes(uninit.as_mut_ptr(), 0, uninit.len());
         }
         self.buf.init = self.buf.capacity();
 
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 2dc12a18a8a..1141a957d87 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -7,6 +7,7 @@ use crate::io::prelude::*;
 
 use crate::cell::{Cell, RefCell};
 use crate::fmt;
+use crate::fs::File;
 use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines};
 use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sync::{Arc, Mutex, MutexGuard, OnceLock};
@@ -999,7 +1000,18 @@ fn print_to<T>(args: fmt::Arguments<'_>, global_s: fn() -> T, label: &str)
 where
     T: Write,
 {
-    if OUTPUT_CAPTURE_USED.load(Ordering::Relaxed)
+    if print_to_buffer_if_capture_used(args) {
+        // Successfully wrote to capture buffer.
+        return;
+    }
+
+    if let Err(e) = global_s().write_fmt(args) {
+        panic!("failed printing to {label}: {e}");
+    }
+}
+
+fn print_to_buffer_if_capture_used(args: fmt::Arguments<'_>) -> bool {
+    OUTPUT_CAPTURE_USED.load(Ordering::Relaxed)
         && OUTPUT_CAPTURE.try_with(|s| {
             // Note that we completely remove a local sink to write to in case
             // our printing recursively panics/prints, so the recursive
@@ -1009,16 +1021,49 @@ where
                 s.set(Some(w));
             })
         }) == Ok(Some(()))
-    {
-        // Successfully wrote to capture buffer.
+}
+
+/// Used by impl Termination for Result to print error after `main` or a test
+/// has returned. Should avoid panicking, although we can't help it if one of
+/// the Display impls inside args decides to.
+pub(crate) fn attempt_print_to_stderr(args: fmt::Arguments<'_>) {
+    if print_to_buffer_if_capture_used(args) {
         return;
     }
 
-    if let Err(e) = global_s().write_fmt(args) {
-        panic!("failed printing to {label}: {e}");
-    }
+    // Ignore error if the write fails, for example because stderr is already
+    // closed. There is not much point panicking at this point.
+    let _ = stderr().write_fmt(args);
 }
 
+/// Trait to determine if a descriptor/handle refers to a terminal/tty.
+#[unstable(feature = "is_terminal", issue = "98070")]
+pub trait IsTerminal: crate::sealed::Sealed {
+    /// Returns `true` if the descriptor/handle refers to a terminal/tty.
+    ///
+    /// On platforms where Rust does not know how to detect a terminal yet, this will return
+    /// `false`. This will also return `false` if an unexpected error occurred, such as from
+    /// passing an invalid file descriptor.
+    fn is_terminal(&self) -> bool;
+}
+
+macro_rules! impl_is_terminal {
+    ($($t:ty),*$(,)?) => {$(
+        #[unstable(feature = "sealed", issue = "none")]
+        impl crate::sealed::Sealed for $t {}
+
+        #[unstable(feature = "is_terminal", issue = "98070")]
+        impl IsTerminal for $t {
+            #[inline]
+            fn is_terminal(&self) -> bool {
+                crate::sys::io::is_terminal(self)
+            }
+        }
+    )*}
+}
+
+impl_is_terminal!(File, Stdin, StdinLock<'_>, Stdout, StdoutLock<'_>, Stderr, StderrLock<'_>);
+
 #[unstable(
     feature = "print_internals",
     reason = "implementation detail which may disappear or be replaced at any time",
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index a4b0522b050..e35145c4ade 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -1867,11 +1867,15 @@ mod type_keyword {}
 /// Code or interfaces whose [memory safety] cannot be verified by the type
 /// system.
 ///
-/// The `unsafe` keyword has two uses: to declare the existence of contracts the
-/// compiler can't check (`unsafe fn` and `unsafe trait`), and to declare that a
-/// programmer has checked that these contracts have been upheld (`unsafe {}`
-/// and `unsafe impl`, but also `unsafe fn` -- see below). They are not mutually
-/// exclusive, as can be seen in `unsafe fn`.
+/// The `unsafe` keyword has two uses:
+/// - to declare the existence of contracts the compiler can't check (`unsafe fn` and `unsafe
+/// trait`),
+/// - and to declare that a programmer has checked that these contracts have been upheld (`unsafe
+/// {}` and `unsafe impl`, but also `unsafe fn` -- see below).
+///
+/// They are not mutually exclusive, as can be seen in `unsafe fn`: the body of an `unsafe fn` is,
+/// by default, treated like an unsafe block. The `unsafe_op_in_unsafe_fn` lint can be enabled to
+/// change that.
 ///
 /// # Unsafe abilities
 ///
@@ -1914,12 +1918,12 @@ mod type_keyword {}
 /// - `unsafe impl`: the contract necessary to implement the trait has been
 /// checked by the programmer and is guaranteed to be respected.
 ///
-/// `unsafe fn` also acts like an `unsafe {}` block
+/// By default, `unsafe fn` also acts like an `unsafe {}` block
 /// around the code inside the function. This means it is not just a signal to
 /// the caller, but also promises that the preconditions for the operations
-/// inside the function are upheld. Mixing these two meanings can be confusing
-/// and [proposal]s exist to use `unsafe {}` blocks inside such functions when
-/// making `unsafe` operations.
+/// inside the function are upheld. Mixing these two meanings can be confusing, so the
+/// `unsafe_op_in_unsafe_fn` lint can be enabled to warn against that and require explicit unsafe
+/// blocks even inside `unsafe fn`.
 ///
 /// See the [Rustnomicon] and the [Reference] for more information.
 ///
@@ -1987,13 +1991,16 @@ mod type_keyword {}
 ///
 /// ```rust
 /// # #![allow(dead_code)]
+/// #![deny(unsafe_op_in_unsafe_fn)]
+///
 /// /// Dereference the given pointer.
 /// ///
 /// /// # Safety
 /// ///
 /// /// `ptr` must be aligned and must not be dangling.
 /// unsafe fn deref_unchecked(ptr: *const i32) -> i32 {
-///     *ptr
+///     // SAFETY: the caller is required to ensure that `ptr` is aligned and dereferenceable.
+///     unsafe { *ptr }
 /// }
 ///
 /// let a = 3;
@@ -2003,35 +2010,118 @@ mod type_keyword {}
 /// unsafe { assert_eq!(*b, deref_unchecked(b)); };
 /// ```
 ///
-/// Traits marked as `unsafe` must be [`impl`]emented using `unsafe impl`. This
-/// makes a guarantee to other `unsafe` code that the implementation satisfies
-/// the trait's safety contract. The [Send] and [Sync] traits are examples of
-/// this behaviour in the standard library.
+/// ## `unsafe` and traits
+///
+/// The interactions of `unsafe` and traits can be surprising, so let us contrast the
+/// two combinations of safe `fn` in `unsafe trait` and `unsafe fn` in safe trait using two
+/// examples:
+///
+/// ```rust
+/// /// # Safety
+/// ///
+/// /// `make_even` must return an even number.
+/// unsafe trait MakeEven {
+///     fn make_even(&self) -> i32;
+/// }
+///
+/// // SAFETY: Our `make_even` always returns something even.
+/// unsafe impl MakeEven for i32 {
+///     fn make_even(&self) -> i32 {
+///         self << 1
+///     }
+/// }
+///
+/// fn use_make_even(x: impl MakeEven) {
+///     if x.make_even() % 2 == 1 {
+///         // SAFETY: this can never happen, because all `MakeEven` implementations
+///         // ensure that `make_even` returns something even.
+///         unsafe { std::hint::unreachable_unchecked() };
+///     }
+/// }
+/// ```
+///
+/// Note how the safety contract of the trait is upheld by the implementation, and is itself used to
+/// uphold the safety contract of the unsafe function `unreachable_unchecked` called by
+/// `use_make_even`. `make_even` itself is a safe function because its *callers* do not have to
+/// worry about any contract, only the *implementation* of `MakeEven` is required to uphold a
+/// certain contract. `use_make_even` is safe because it can use the promise made by `MakeEven`
+/// implementations to uphold the safety contract of the `unsafe fn unreachable_unchecked` it calls.
+///
+/// It is also possible to have `unsafe fn` in a regular safe `trait`:
 ///
 /// ```rust
-/// /// Implementors of this trait must guarantee an element is always
-/// /// accessible with index 3.
-/// unsafe trait ThreeIndexable<T> {
-///     /// Returns a reference to the element with index 3 in `&self`.
-///     fn three(&self) -> &T;
+/// # #![feature(never_type)]
+/// #![deny(unsafe_op_in_unsafe_fn)]
+///
+/// trait Indexable {
+///     const LEN: usize;
+///
+///     /// # Safety
+///     ///
+///     /// The caller must ensure that `idx < LEN`.
+///     unsafe fn idx_unchecked(&self, idx: usize) -> i32;
 /// }
 ///
-/// // The implementation of `ThreeIndexable` for `[T; 4]` is `unsafe`
-/// // because the implementor must abide by a contract the compiler cannot
-/// // check but as a programmer we know there will always be a valid element
-/// // at index 3 to access.
-/// unsafe impl<T> ThreeIndexable<T> for [T; 4] {
-///     fn three(&self) -> &T {
-///         // SAFETY: implementing the trait means there always is an element
-///         // with index 3 accessible.
-///         unsafe { self.get_unchecked(3) }
+/// // The implementation for `i32` doesn't need to do any contract reasoning.
+/// impl Indexable for i32 {
+///     const LEN: usize = 1;
+///
+///     unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
+///         debug_assert_eq!(idx, 0);
+///         *self
 ///     }
 /// }
 ///
-/// let a = [1, 2, 4, 8];
-/// assert_eq!(a.three(), &8);
+/// // The implementation for arrays exploits the function contract to
+/// // make use of `get_unchecked` on slices and avoid a run-time check.
+/// impl Indexable for [i32; 42] {
+///     const LEN: usize = 42;
+///
+///     unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
+///         // SAFETY: As per this trait's documentation, the caller ensures
+///         // that `idx < 42`.
+///         unsafe { *self.get_unchecked(idx) }
+///     }
+/// }
+///
+/// // The implementation for the never type declares a length of 0,
+/// // which means `idx_unchecked` can never be called.
+/// impl Indexable for ! {
+///     const LEN: usize = 0;
+///
+///     unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
+///         // SAFETY: As per this trait's documentation, the caller ensures
+///         // that `idx < 0`, which is impossible, so this is dead code.
+///         unsafe { std::hint::unreachable_unchecked() }
+///     }
+/// }
+///
+/// fn use_indexable<I: Indexable>(x: I, idx: usize) -> i32 {
+///     if idx < I::LEN {
+///         // SAFETY: We have checked that `idx < I::LEN`.
+///         unsafe { x.idx_unchecked(idx) }
+///     } else {
+///         panic!("index out-of-bounds")
+///     }
+/// }
 /// ```
 ///
+/// This time, `use_indexable` is safe because it uses a run-time check to discharge the safety
+/// contract of `idx_unchecked`. Implementing `Indexable` is safe because when writing
+/// `idx_unchecked`, we don't have to worry: our *callers* need to discharge a proof obligation
+/// (like `use_indexable` does), but the *implementation* of `get_unchecked` has no proof obligation
+/// to contend with. Of course, the implementation of `Indexable` may choose to call other unsafe
+/// operations, and then it needs an `unsafe` *block* to indicate it discharged the proof
+/// obligations of its callees. (We enabled `unsafe_op_in_unsafe_fn`, so the body of `idx_unchecked`
+/// is not implicitly an unsafe block.) For that purpose it can make use of the contract that all
+/// its callers must uphold -- the fact that `idx < LEN`.
+///
+/// Formally speaking, an `unsafe fn` in a trait is a function with *preconditions* that go beyond
+/// those encoded by the argument types (such as `idx < LEN`), whereas an `unsafe trait` can declare
+/// that some of its functions have *postconditions* that go beyond those encoded in the return type
+/// (such as returning an even integer). If a trait needs a function with both extra precondition
+/// and extra postcondition, then it needs an `unsafe fn` in an `unsafe trait`.
+///
 /// [`extern`]: keyword.extern.html
 /// [`trait`]: keyword.trait.html
 /// [`static`]: keyword.static.html
@@ -2043,7 +2133,6 @@ mod type_keyword {}
 /// [nomicon-soundness]: ../nomicon/safe-unsafe-meaning.html
 /// [soundness]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library
 /// [Reference]: ../reference/unsafety.html
-/// [proposal]: https://github.com/rust-lang/rfcs/pull/2585
 /// [discussion on Rust Internals]: https://internals.rust-lang.org/t/what-does-unsafe-mean/6696
 mod unsafe_keyword {}
 
diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs
deleted file mode 100644
index f8c06c3f9ae..00000000000
--- a/library/std/src/lazy.rs
+++ /dev/null
@@ -1 +0,0 @@
-//! Lazy values and one-time initialization of static data.
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 07b40f64ac2..78838adb8dd 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -145,8 +145,8 @@
 //! abstracting over differences in common platforms, most notably Windows and
 //! Unix derivatives.
 //!
-//! Common types of I/O, including [files], [TCP], [UDP], are defined in the
-//! [`io`], [`fs`], and [`net`] modules.
+//! Common types of I/O, including [files], [TCP], and [UDP], are defined in
+//! the [`io`], [`fs`], and [`net`] modules.
 //!
 //! The [`thread`] module contains Rust's threading abstractions. [`sync`]
 //! contains further primitive shared memory types, including [`atomic`] and
@@ -251,11 +251,11 @@
 #![feature(doc_notable_trait)]
 #![feature(dropck_eyepatch)]
 #![feature(exhaustive_patterns)]
+#![feature(if_let_guard)]
 #![feature(intra_doc_pointers)]
-#![cfg_attr(bootstrap, feature(label_break_value))]
+#![feature(is_terminal)]
 #![feature(lang_items)]
 #![feature(let_chains)]
-#![cfg_attr(bootstrap, feature(let_else))]
 #![feature(linkage)]
 #![feature(link_cfg)]
 #![feature(min_specialization)]
@@ -282,9 +282,9 @@
 #![feature(cstr_internals)]
 #![feature(duration_checked_float)]
 #![feature(duration_constants)]
-#![cfg_attr(not(bootstrap), feature(error_generic_member_access))]
-#![cfg_attr(not(bootstrap), feature(error_in_core))]
-#![cfg_attr(not(bootstrap), feature(error_iter))]
+#![feature(error_generic_member_access)]
+#![feature(error_in_core)]
+#![feature(error_iter)]
 #![feature(exact_size_is_empty)]
 #![feature(exclusive_wrapper)]
 #![feature(extend_one)]
@@ -293,10 +293,9 @@
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
 #![feature(int_error_internals)]
-#![feature(is_some_with)]
+#![feature(is_some_and)]
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_write_slice)]
-#![feature(mixed_integer_ops)]
 #![feature(nonnull_slice_from_raw_parts)]
 #![feature(panic_can_unwind)]
 #![feature(panic_info_message)]
@@ -351,9 +350,9 @@
 #![feature(trace_macros)]
 //
 // Only used in tests/benchmarks:
-#![feature(bench_black_box)]
 //
 // Only for const-ness:
+#![feature(const_collections_with_hasher)]
 #![feature(const_io_structs)]
 #![feature(const_ip)]
 #![feature(const_ipv4)]
@@ -531,9 +530,6 @@ pub mod process;
 pub mod sync;
 pub mod time;
 
-#[unstable(feature = "once_cell", issue = "74465")]
-pub mod lazy;
-
 // Pull in `std_float` crate  into libstd. The contents of
 // `std_float` are in a different repository: rust-lang/portable-simd.
 #[path = "../../portable-simd/crates/std_float/src/lib.rs"]
diff --git a/library/std/src/os/fd/mod.rs b/library/std/src/os/fd/mod.rs
index a456947534a..c6aa7c77dbc 100644
--- a/library/std/src/os/fd/mod.rs
+++ b/library/std/src/os/fd/mod.rs
@@ -1,16 +1,25 @@
 //! Owned and borrowed Unix-like file descriptors.
+//!
+//! This module is supported on Unix platforms and WASI, which both use a
+//! similar file descriptor system for referencing OS resources.
 
 #![stable(feature = "io_safety", since = "1.63.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
 
 // `RawFd`, `AsRawFd`, etc.
-pub mod raw;
+mod raw;
 
 // `OwnedFd`, `AsFd`, etc.
-pub mod owned;
+mod owned;
 
 // Implementations for `AsRawFd` etc. for network types.
 mod net;
 
 #[cfg(test)]
 mod tests;
+
+// Export the types and traits for the public API.
+#[unstable(feature = "os_fd", issue = "98699")]
+pub use owned::*;
+#[unstable(feature = "os_fd", issue = "98699")]
+pub use raw::*;
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 71e33fb9ed8..c16518577f7 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -6,6 +6,7 @@
 use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
 use crate::fmt;
 use crate::fs;
+use crate::io;
 use crate::marker::PhantomData;
 use crate::mem::forget;
 #[cfg(not(any(target_arch = "wasm32", target_env = "sgx")))]
@@ -192,6 +193,23 @@ impl fmt::Debug for OwnedFd {
     }
 }
 
+macro_rules! impl_is_terminal {
+    ($($t:ty),*$(,)?) => {$(
+        #[unstable(feature = "sealed", issue = "none")]
+        impl crate::sealed::Sealed for $t {}
+
+        #[unstable(feature = "is_terminal", issue = "98070")]
+        impl crate::io::IsTerminal for $t {
+            #[inline]
+            fn is_terminal(&self) -> bool {
+                crate::sys::io::is_terminal(self)
+            }
+        }
+    )*}
+}
+
+impl_is_terminal!(BorrowedFd<'_>, OwnedFd);
+
 /// A trait to borrow the file descriptor from an underlying object.
 ///
 /// This is only available on unix platforms and must be imported in order to
@@ -206,10 +224,8 @@ pub trait AsFd {
     /// ```rust,no_run
     /// use std::fs::File;
     /// # use std::io;
-    /// # #[cfg(target_os = "wasi")]
-    /// # use std::os::wasi::io::{AsFd, BorrowedFd};
-    /// # #[cfg(unix)]
-    /// # use std::os::unix::io::{AsFd, BorrowedFd};
+    /// # #[cfg(any(unix, target_os = "wasi"))]
+    /// # use std::os::fd::{AsFd, BorrowedFd};
     ///
     /// let mut f = File::open("foo.txt")?;
     /// # #[cfg(any(unix, target_os = "wasi"))]
@@ -387,3 +403,54 @@ impl<T: AsFd> AsFd for Box<T> {
         (**self).as_fd()
     }
 }
+
+#[stable(feature = "io_safety", since = "1.63.0")]
+impl AsFd for io::Stdin {
+    #[inline]
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        unsafe { BorrowedFd::borrow_raw(0) }
+    }
+}
+
+#[stable(feature = "io_safety", since = "1.63.0")]
+impl<'a> AsFd for io::StdinLock<'a> {
+    #[inline]
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        // SAFETY: user code should not close stdin out from under the standard library
+        unsafe { BorrowedFd::borrow_raw(0) }
+    }
+}
+
+#[stable(feature = "io_safety", since = "1.63.0")]
+impl AsFd for io::Stdout {
+    #[inline]
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        unsafe { BorrowedFd::borrow_raw(1) }
+    }
+}
+
+#[stable(feature = "io_safety", since = "1.63.0")]
+impl<'a> AsFd for io::StdoutLock<'a> {
+    #[inline]
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        // SAFETY: user code should not close stdout out from under the standard library
+        unsafe { BorrowedFd::borrow_raw(1) }
+    }
+}
+
+#[stable(feature = "io_safety", since = "1.63.0")]
+impl AsFd for io::Stderr {
+    #[inline]
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        unsafe { BorrowedFd::borrow_raw(2) }
+    }
+}
+
+#[stable(feature = "io_safety", since = "1.63.0")]
+impl<'a> AsFd for io::StderrLock<'a> {
+    #[inline]
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        // SAFETY: user code should not close stderr out from under the standard library
+        unsafe { BorrowedFd::borrow_raw(2) }
+    }
+}
diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs
index 1b3d110426f..f92a0506670 100644
--- a/library/std/src/os/fd/raw.rs
+++ b/library/std/src/os/fd/raw.rs
@@ -42,10 +42,8 @@ pub trait AsRawFd {
     /// ```no_run
     /// use std::fs::File;
     /// # use std::io;
-    /// #[cfg(unix)]
-    /// use std::os::unix::io::{AsRawFd, RawFd};
-    /// #[cfg(target_os = "wasi")]
-    /// use std::os::wasi::io::{AsRawFd, RawFd};
+    /// #[cfg(any(unix, target_os = "wasi"))]
+    /// use std::os::fd::{AsRawFd, RawFd};
     ///
     /// let mut f = File::open("foo.txt")?;
     /// // Note that `raw_fd` is only valid as long as `f` exists.
@@ -83,10 +81,8 @@ pub trait FromRawFd {
     /// ```no_run
     /// use std::fs::File;
     /// # use std::io;
-    /// #[cfg(unix)]
-    /// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd};
-    /// #[cfg(target_os = "wasi")]
-    /// use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd};
+    /// #[cfg(any(unix, target_os = "wasi"))]
+    /// use std::os::fd::{FromRawFd, IntoRawFd, RawFd};
     ///
     /// let f = File::open("foo.txt")?;
     /// # #[cfg(any(unix, target_os = "wasi"))]
@@ -121,10 +117,8 @@ pub trait IntoRawFd {
     /// ```no_run
     /// use std::fs::File;
     /// # use std::io;
-    /// #[cfg(unix)]
-    /// use std::os::unix::io::{IntoRawFd, RawFd};
-    /// #[cfg(target_os = "wasi")]
-    /// use std::os::wasi::io::{IntoRawFd, RawFd};
+    /// #[cfg(any(unix, target_os = "wasi"))]
+    /// use std::os::fd::{IntoRawFd, RawFd};
     ///
     /// let f = File::open("foo.txt")?;
     /// #[cfg(any(unix, target_os = "wasi"))]
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index 18c64b51007..42773805cdb 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -145,9 +145,11 @@ pub mod solaris;
 pub mod solid;
 #[cfg(target_os = "vxworks")]
 pub mod vxworks;
+#[cfg(target_os = "watchos")]
+pub(crate) mod watchos;
 
 #[cfg(any(unix, target_os = "wasi", doc))]
-mod fd;
+pub mod fd;
 
 #[cfg(any(target_os = "linux", target_os = "android", doc))]
 mod net;
diff --git a/library/std/src/os/unix/io/fd.rs b/library/std/src/os/unix/io/fd.rs
deleted file mode 100644
index d4cb696459b..00000000000
--- a/library/std/src/os/unix/io/fd.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//! Owned and borrowed file descriptors.
-
-// Tests for this module
-#[cfg(test)]
-mod tests;
-
-#[stable(feature = "io_safety", since = "1.63.0")]
-pub use crate::os::fd::owned::*;
diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs
index 3ab5606f889..25b5dbff14f 100644
--- a/library/std/src/os/unix/io/mod.rs
+++ b/library/std/src/os/unix/io/mod.rs
@@ -77,10 +77,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-mod fd;
-mod raw;
-
-#[stable(feature = "io_safety", since = "1.63.0")]
-pub use fd::*;
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use raw::*;
+pub use crate::os::fd::*;
+
+// Tests for this module
+#[cfg(test)]
+mod tests;
diff --git a/library/std/src/os/unix/io/raw.rs b/library/std/src/os/unix/io/raw.rs
deleted file mode 100644
index a4d2ba797d9..00000000000
--- a/library/std/src/os/unix/io/raw.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//! Unix-specific extensions to general I/O primitives.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use crate::os::fd::raw::*;
diff --git a/library/std/src/os/unix/io/fd/tests.rs b/library/std/src/os/unix/io/tests.rs
index 84d2a7a1a91..84d2a7a1a91 100644
--- a/library/std/src/os/unix/io/fd/tests.rs
+++ b/library/std/src/os/unix/io/tests.rs
diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs
index 411cc0925c4..f97fa0fb06f 100644
--- a/library/std/src/os/unix/mod.rs
+++ b/library/std/src/os/unix/mod.rs
@@ -73,6 +73,8 @@ mod platform {
     pub use crate::os::solaris::*;
     #[cfg(target_os = "vxworks")]
     pub use crate::os::vxworks::*;
+    #[cfg(target_os = "watchos")]
+    pub use crate::os::watchos::*;
 }
 
 pub mod ffi;
diff --git a/library/std/src/os/wasi/io/mod.rs b/library/std/src/os/wasi/io/mod.rs
index 6c884e2eaf4..57bd842a50c 100644
--- a/library/std/src/os/wasi/io/mod.rs
+++ b/library/std/src/os/wasi/io/mod.rs
@@ -1,12 +1,6 @@
 //! WASI-specific extensions to general I/O primitives.
 
-#![deny(unsafe_op_in_unsafe_fn)]
-#![unstable(feature = "wasi_ext", issue = "71213")]
+#![stable(feature = "io_safety", since = "1.63.0")]
 
-mod fd;
-mod raw;
-
-#[unstable(feature = "wasi_ext", issue = "71213")]
-pub use fd::*;
-#[unstable(feature = "wasi_ext", issue = "71213")]
-pub use raw::*;
+#[stable(feature = "io_safety", since = "1.63.0")]
+pub use crate::os::fd::*;
diff --git a/library/std/src/os/watchos/fs.rs b/library/std/src/os/watchos/fs.rs
new file mode 100644
index 00000000000..a14fe35a77c
--- /dev/null
+++ b/library/std/src/os/watchos/fs.rs
@@ -0,0 +1,142 @@
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use crate::fs::Metadata;
+use crate::sys_common::AsInner;
+
+#[allow(deprecated)]
+use crate::os::watchos::raw;
+
+/// OS-specific extensions to [`fs::Metadata`].
+///
+/// [`fs::Metadata`]: crate::fs::Metadata
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+pub trait MetadataExt {
+    /// Gain a reference to the underlying `stat` structure which contains
+    /// the raw information returned by the OS.
+    ///
+    /// The contents of the returned `stat` are **not** consistent across
+    /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
+    /// cross-Unix abstractions contained within the raw stat.
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    #[deprecated(
+        since = "1.8.0",
+        note = "deprecated in favor of the accessor \
+                  methods of this trait"
+    )]
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat;
+
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_dev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ino(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mode(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_nlink(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_uid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_rdev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_size(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_birthtime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_birthtime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blksize(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blocks(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_flags(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gen(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_lspare(&self) -> u32;
+}
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+impl MetadataExt for Metadata {
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat {
+        unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }
+    }
+    fn st_dev(&self) -> u64 {
+        self.as_inner().as_inner().st_dev as u64
+    }
+    fn st_ino(&self) -> u64 {
+        self.as_inner().as_inner().st_ino as u64
+    }
+    fn st_mode(&self) -> u32 {
+        self.as_inner().as_inner().st_mode as u32
+    }
+    fn st_nlink(&self) -> u64 {
+        self.as_inner().as_inner().st_nlink as u64
+    }
+    fn st_uid(&self) -> u32 {
+        self.as_inner().as_inner().st_uid as u32
+    }
+    fn st_gid(&self) -> u32 {
+        self.as_inner().as_inner().st_gid as u32
+    }
+    fn st_rdev(&self) -> u64 {
+        self.as_inner().as_inner().st_rdev as u64
+    }
+    fn st_size(&self) -> u64 {
+        self.as_inner().as_inner().st_size as u64
+    }
+    fn st_atime(&self) -> i64 {
+        self.as_inner().as_inner().st_atime as i64
+    }
+    fn st_atime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_atime_nsec as i64
+    }
+    fn st_mtime(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime as i64
+    }
+    fn st_mtime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime_nsec as i64
+    }
+    fn st_ctime(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime as i64
+    }
+    fn st_ctime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime_nsec as i64
+    }
+    fn st_birthtime(&self) -> i64 {
+        self.as_inner().as_inner().st_birthtime as i64
+    }
+    fn st_birthtime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_birthtime_nsec as i64
+    }
+    fn st_blksize(&self) -> u64 {
+        self.as_inner().as_inner().st_blksize as u64
+    }
+    fn st_blocks(&self) -> u64 {
+        self.as_inner().as_inner().st_blocks as u64
+    }
+    fn st_gen(&self) -> u32 {
+        self.as_inner().as_inner().st_gen as u32
+    }
+    fn st_flags(&self) -> u32 {
+        self.as_inner().as_inner().st_flags as u32
+    }
+    fn st_lspare(&self) -> u32 {
+        self.as_inner().as_inner().st_lspare as u32
+    }
+}
diff --git a/library/std/src/os/watchos/mod.rs b/library/std/src/os/watchos/mod.rs
new file mode 100644
index 00000000000..cd6454ebbf9
--- /dev/null
+++ b/library/std/src/os/watchos/mod.rs
@@ -0,0 +1,6 @@
+//! watchOS-specific definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+
+pub mod fs;
+pub mod raw;
diff --git a/library/std/src/os/watchos/raw.rs b/library/std/src/os/watchos/raw.rs
new file mode 100644
index 00000000000..630a533d9aa
--- /dev/null
+++ b/library/std/src/os/watchos/raw.rs
@@ -0,0 +1,83 @@
+//! watchOS-specific raw type definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+#![deprecated(
+    since = "1.8.0",
+    note = "these type aliases are no longer supported by \
+              the standard library, the `libc` crate on \
+              crates.io should be used instead for the correct \
+              definitions"
+)]
+#![allow(deprecated)]
+
+use crate::os::raw::c_long;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blkcnt_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blksize_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type dev_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type ino_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type mode_t = u32;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type nlink_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type off_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type time_t = i64;
+
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = usize;
+
+#[repr(C)]
+#[derive(Clone)]
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub struct stat {
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_dev: i32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mode: u16,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_nlink: u16,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ino: u64,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_uid: u32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_gid: u32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_rdev: i32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_atime: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_atime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mtime: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mtime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ctime: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ctime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_birthtime: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_birthtime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_size: i64,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blocks: i64,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blksize: i32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_flags: u32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_gen: u32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_lspare: i32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_qspare: [i64; 2],
+}
diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index 16cc8fa2783..1dfecc57338 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -384,6 +384,23 @@ impl fmt::Debug for OwnedHandle {
     }
 }
 
+macro_rules! impl_is_terminal {
+    ($($t:ty),*$(,)?) => {$(
+        #[unstable(feature = "sealed", issue = "none")]
+        impl crate::sealed::Sealed for $t {}
+
+        #[unstable(feature = "is_terminal", issue = "98070")]
+        impl crate::io::IsTerminal for $t {
+            #[inline]
+            fn is_terminal(&self) -> bool {
+                crate::sys::io::is_terminal(self)
+            }
+        }
+    )*}
+}
+
+impl_is_terminal!(BorrowedHandle<'_>, OwnedHandle);
+
 /// A trait to borrow the handle from an underlying object.
 #[stable(feature = "io_safety", since = "1.63.0")]
 pub trait AsHandle {
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 38dcf6cbf7d..d4976a469cc 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -300,7 +300,7 @@ pub mod panic_count {
     thread_local! { static LOCAL_PANIC_COUNT: Cell<usize> = const { Cell::new(0) } }
 
     // Sum of panic counts from all threads. The purpose of this is to have
-    // a fast path in `is_zero` (which is used by `panicking`). In any particular
+    // a fast path in `count_is_zero` (which is used by `panicking`). In any particular
     // thread, if that thread currently views `GLOBAL_PANIC_COUNT` as being zero,
     // then `LOCAL_PANIC_COUNT` in that thread is zero. This invariant holds before
     // and after increase and decrease, but not necessarily during their execution.
@@ -308,6 +308,14 @@ pub mod panic_count {
     // Additionally, the top bit of GLOBAL_PANIC_COUNT (GLOBAL_ALWAYS_ABORT_FLAG)
     // records whether panic::always_abort() has been called.  This can only be
     // set, never cleared.
+    // panic::always_abort() is usually called to prevent memory allocations done by
+    // the panic handling in the child created by `libc::fork`.
+    // Memory allocations performed in  a child created with `libc::fork` are undefined
+    // behavior in most operating systems.
+    // Accessing LOCAL_PANIC_COUNT in a child created by `libc::fork` would lead to a memory
+    // allocation. Only GLOBAL_PANIC_COUNT can be accessed in this situation. This is
+    // sufficient because a child process will always have exactly one thread only.
+    // See also #85261 for details.
     //
     // This could be viewed as a struct containing a single bit and an n-1-bit
     // value, but if we wrote it like that it would be more than a single word,
@@ -318,15 +326,26 @@ pub mod panic_count {
     // panicking thread consumes at least 2 bytes of address space.
     static GLOBAL_PANIC_COUNT: AtomicUsize = AtomicUsize::new(0);
 
+    // Return the state of the ALWAYS_ABORT_FLAG and number of panics.
+    //
+    // If ALWAYS_ABORT_FLAG is not set, the number is determined on a per-thread
+    // base (stored in LOCAL_PANIC_COUNT), i.e. it is the amount of recursive calls
+    // of the calling thread.
+    // If ALWAYS_ABORT_FLAG is set, the number equals the *global* number of panic
+    // calls. See above why LOCAL_PANIC_COUNT is not used.
     pub fn increase() -> (bool, usize) {
-        (
-            GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed) & ALWAYS_ABORT_FLAG != 0,
+        let global_count = GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed);
+        let must_abort = global_count & ALWAYS_ABORT_FLAG != 0;
+        let panics = if must_abort {
+            global_count & !ALWAYS_ABORT_FLAG
+        } else {
             LOCAL_PANIC_COUNT.with(|c| {
                 let next = c.get() + 1;
                 c.set(next);
                 next
-            }),
-        )
+            })
+        };
+        (must_abort, panics)
     }
 
     pub fn decrease() {
@@ -369,7 +388,7 @@ pub mod panic_count {
     }
 
     // Slow path is in a separate function to reduce the amount of code
-    // inlined from `is_zero`.
+    // inlined from `count_is_zero`.
     #[inline(never)]
     #[cold]
     fn is_zero_slow_path() -> bool {
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 4f9dff1ef03..9d63281627d 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -2158,6 +2158,7 @@ impl Path {
     /// assert_eq!(grand_parent.parent(), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[doc(alias = "dirname")]
     #[must_use]
     pub fn parent(&self) -> Option<&Path> {
         let mut comps = self.components();
@@ -2225,6 +2226,7 @@ impl Path {
     /// assert_eq!(None, Path::new("/").file_name());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[doc(alias = "basename")]
     #[must_use]
     pub fn file_name(&self) -> Option<&OsStr> {
         self.components().next_back().and_then(|p| match p {
diff --git a/library/std/src/personality/dwarf/eh.rs b/library/std/src/personality/dwarf/eh.rs
index 8799137b78f..27b50c13b77 100644
--- a/library/std/src/personality/dwarf/eh.rs
+++ b/library/std/src/personality/dwarf/eh.rs
@@ -98,9 +98,8 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
                 }
             }
         }
-        // Ip is not present in the table.  This should not happen... but it does: issue #35011.
-        // So rather than returning EHAction::Terminate, we do this.
-        Ok(EHAction::None)
+        // Ip is not present in the table. This indicates a nounwind call.
+        Ok(EHAction::Terminate)
     } else {
         // SjLj version:
         // The "IP" is an index into the call-site table, with two exceptions:
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index d91d4fa64ca..400d25beb26 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1629,7 +1629,7 @@ impl ExitStatusError {
     ///
     /// This is exactly like [`code()`](Self::code), except that it returns a `NonZeroI32`.
     ///
-    /// Plain `code`, returning a plain integer, is provided because is is often more convenient.
+    /// Plain `code`, returning a plain integer, is provided because it is often more convenient.
     /// The returned value from `code()` is indeed also nonzero; use `code_nonzero()` when you want
     /// a type-level guarantee of nonzeroness.
     ///
@@ -2154,8 +2154,16 @@ pub fn id() -> u32 {
 #[cfg_attr(not(test), lang = "termination")]
 #[stable(feature = "termination_trait_lib", since = "1.61.0")]
 #[rustc_on_unimplemented(
-    message = "`main` has invalid return type `{Self}`",
-    label = "`main` can only return types that implement `{Termination}`"
+    on(
+        all(not(bootstrap), cause = "MainFunctionType"),
+        message = "`main` has invalid return type `{Self}`",
+        label = "`main` can only return types that implement `{Termination}`"
+    ),
+    on(
+        bootstrap,
+        message = "`main` has invalid return type `{Self}`",
+        label = "`main` can only return types that implement `{Termination}`"
+    )
 )]
 pub trait Termination {
     /// Is called to get the representation of the value as status code.
@@ -2200,9 +2208,7 @@ impl<T: Termination, E: fmt::Debug> Termination for Result<T, E> {
         match self {
             Ok(val) => val.report(),
             Err(err) => {
-                // Ignore error if the write fails, for example because stderr is
-                // already closed. There is not much point panicking at this point.
-                let _ = writeln!(io::stderr(), "Error: {err:?}");
+                io::attempt_print_to_stderr(format_args_nl!("Error: {err:?}"));
                 ExitCode::FAILURE
             }
         }
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 98f6cc7aa3e..b8bcdbece0a 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -160,15 +160,12 @@ fn lang_start<T: crate::process::Termination + 'static>(
     main: fn() -> T,
     argc: isize,
     argv: *const *const u8,
-    #[cfg(not(bootstrap))] sigpipe: u8,
+    sigpipe: u8,
 ) -> isize {
     let Ok(v) = lang_start_internal(
         &move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report().to_i32(),
         argc,
         argv,
-        #[cfg(bootstrap)]
-        2, // Temporary inlining of sigpipe::DEFAULT until bootstrap stops being special
-        #[cfg(not(bootstrap))]
         sigpipe,
     );
     v
diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs
index a7feea58859..0f25417d6b5 100644
--- a/library/std/src/sync/once.rs
+++ b/library/std/src/sync/once.rs
@@ -3,99 +3,12 @@
 //! This primitive is meant to be used to run one-time initialization. An
 //! example use case would be for initializing an FFI library.
 
-// A "once" is a relatively simple primitive, and it's also typically provided
-// by the OS as well (see `pthread_once` or `InitOnceExecuteOnce`). The OS
-// primitives, however, tend to have surprising restrictions, such as the Unix
-// one doesn't allow an argument to be passed to the function.
-//
-// As a result, we end up implementing it ourselves in the standard library.
-// This also gives us the opportunity to optimize the implementation a bit which
-// should help the fast path on call sites. Consequently, let's explain how this
-// primitive works now!
-//
-// So to recap, the guarantees of a Once are that it will call the
-// initialization closure at most once, and it will never return until the one
-// that's running has finished running. This means that we need some form of
-// blocking here while the custom callback is running at the very least.
-// Additionally, we add on the restriction of **poisoning**. Whenever an
-// initialization closure panics, the Once enters a "poisoned" state which means
-// that all future calls will immediately panic as well.
-//
-// So to implement this, one might first reach for a `Mutex`, but those cannot
-// be put into a `static`. It also gets a lot harder with poisoning to figure
-// out when the mutex needs to be deallocated because it's not after the closure
-// finishes, but after the first successful closure finishes.
-//
-// All in all, this is instead implemented with atomics and lock-free
-// operations! Whee! Each `Once` has one word of atomic state, and this state is
-// CAS'd on to determine what to do. There are four possible state of a `Once`:
-//
-// * Incomplete - no initialization has run yet, and no thread is currently
-//                using the Once.
-// * Poisoned - some thread has previously attempted to initialize the Once, but
-//              it panicked, so the Once is now poisoned. There are no other
-//              threads currently accessing this Once.
-// * Running - some thread is currently attempting to run initialization. It may
-//             succeed, so all future threads need to wait for it to finish.
-//             Note that this state is accompanied with a payload, described
-//             below.
-// * Complete - initialization has completed and all future calls should finish
-//              immediately.
-//
-// With 4 states we need 2 bits to encode this, and we use the remaining bits
-// in the word we have allocated as a queue of threads waiting for the thread
-// responsible for entering the RUNNING state. This queue is just a linked list
-// of Waiter nodes which is monotonically increasing in size. Each node is
-// allocated on the stack, and whenever the running closure finishes it will
-// consume the entire queue and notify all waiters they should try again.
-//
-// You'll find a few more details in the implementation, but that's the gist of
-// it!
-//
-// Atomic orderings:
-// When running `Once` we deal with multiple atomics:
-// `Once.state_and_queue` and an unknown number of `Waiter.signaled`.
-// * `state_and_queue` is used (1) as a state flag, (2) for synchronizing the
-//   result of the `Once`, and (3) for synchronizing `Waiter` nodes.
-//     - At the end of the `call_inner` function we have to make sure the result
-//       of the `Once` is acquired. So every load which can be the only one to
-//       load COMPLETED must have at least Acquire ordering, which means all
-//       three of them.
-//     - `WaiterQueue::Drop` is the only place that may store COMPLETED, and
-//       must do so with Release ordering to make the result available.
-//     - `wait` inserts `Waiter` nodes as a pointer in `state_and_queue`, and
-//       needs to make the nodes available with Release ordering. The load in
-//       its `compare_exchange` can be Relaxed because it only has to compare
-//       the atomic, not to read other data.
-//     - `WaiterQueue::Drop` must see the `Waiter` nodes, so it must load
-//       `state_and_queue` with Acquire ordering.
-//     - There is just one store where `state_and_queue` is used only as a
-//       state flag, without having to synchronize data: switching the state
-//       from INCOMPLETE to RUNNING in `call_inner`. This store can be Relaxed,
-//       but the read has to be Acquire because of the requirements mentioned
-//       above.
-// * `Waiter.signaled` is both used as a flag, and to protect a field with
-//   interior mutability in `Waiter`. `Waiter.thread` is changed in
-//   `WaiterQueue::Drop` which then sets `signaled` with Release ordering.
-//   After `wait` loads `signaled` with Acquire and sees it is true, it needs to
-//   see the changes to drop the `Waiter` struct correctly.
-// * There is one place where the two atomics `Once.state_and_queue` and
-//   `Waiter.signaled` come together, and might be reordered by the compiler or
-//   processor. Because both use Acquire ordering such a reordering is not
-//   allowed, so no need for SeqCst.
-
 #[cfg(all(test, not(target_os = "emscripten")))]
 mod tests;
 
-use crate::cell::Cell;
 use crate::fmt;
-use crate::marker;
 use crate::panic::{RefUnwindSafe, UnwindSafe};
-use crate::ptr;
-use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
-use crate::thread::{self, Thread};
-
-type Masked = ();
+use crate::sys_common::once as sys;
 
 /// A synchronization primitive which can be used to run a one-time global
 /// initialization. Useful for one-time initialization for FFI or related
@@ -114,19 +27,9 @@ type Masked = ();
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Once {
-    // `state_and_queue` is actually a pointer to a `Waiter` with extra state
-    // bits, so we add the `PhantomData` appropriately.
-    state_and_queue: AtomicPtr<Masked>,
-    _marker: marker::PhantomData<*const Waiter>,
+    inner: sys::Once,
 }
 
-// The `PhantomData` of a raw pointer removes these two auto traits, but we
-// enforce both below in the implementation so this should be safe to add.
-#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl Sync for Once {}
-#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl Send for Once {}
-
 #[stable(feature = "sync_once_unwind_safe", since = "1.59.0")]
 impl UnwindSafe for Once {}
 
@@ -136,10 +39,8 @@ impl RefUnwindSafe for Once {}
 /// State yielded to [`Once::call_once_force()`]’s closure parameter. The state
 /// can be used to query the poison status of the [`Once`].
 #[stable(feature = "once_poison", since = "1.51.0")]
-#[derive(Debug)]
 pub struct OnceState {
-    poisoned: bool,
-    set_state_on_drop_to: Cell<*mut Masked>,
+    pub(crate) inner: sys::OnceState,
 }
 
 /// Initialization value for static [`Once`] values.
@@ -159,38 +60,6 @@ pub struct OnceState {
 )]
 pub const ONCE_INIT: Once = Once::new();
 
-// Four states that a Once can be in, encoded into the lower bits of
-// `state_and_queue` in the Once structure.
-const INCOMPLETE: usize = 0x0;
-const POISONED: usize = 0x1;
-const RUNNING: usize = 0x2;
-const COMPLETE: usize = 0x3;
-
-// Mask to learn about the state. All other bits are the queue of waiters if
-// this is in the RUNNING state.
-const STATE_MASK: usize = 0x3;
-
-// Representation of a node in the linked list of waiters, used while in the
-// RUNNING state.
-// Note: `Waiter` can't hold a mutable pointer to the next thread, because then
-// `wait` would both hand out a mutable reference to its `Waiter` node, and keep
-// a shared reference to check `signaled`. Instead we hold shared references and
-// use interior mutability.
-#[repr(align(4))] // Ensure the two lower bits are free to use as state bits.
-struct Waiter {
-    thread: Cell<Option<Thread>>,
-    signaled: AtomicBool,
-    next: *const Waiter,
-}
-
-// Head of a linked list of waiters.
-// Every node is a struct on the stack of a waiting thread.
-// Will wake up the waiters when it gets dropped, i.e. also on panic.
-struct WaiterQueue<'a> {
-    state_and_queue: &'a AtomicPtr<Masked>,
-    set_state_on_drop_to: *mut Masked,
-}
-
 impl Once {
     /// Creates a new `Once` value.
     #[inline]
@@ -198,10 +67,7 @@ impl Once {
     #[rustc_const_stable(feature = "const_once_new", since = "1.32.0")]
     #[must_use]
     pub const fn new() -> Once {
-        Once {
-            state_and_queue: AtomicPtr::new(ptr::invalid_mut(INCOMPLETE)),
-            _marker: marker::PhantomData,
-        }
+        Once { inner: sys::Once::new() }
     }
 
     /// Performs an initialization routine once and only once. The given closure
@@ -261,6 +127,7 @@ impl Once {
     /// This is similar to [poisoning with mutexes][poison].
     ///
     /// [poison]: struct.Mutex.html#poisoning
+    #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[track_caller]
     pub fn call_once<F>(&self, f: F)
@@ -268,12 +135,12 @@ impl Once {
         F: FnOnce(),
     {
         // Fast path check
-        if self.is_completed() {
+        if self.inner.is_completed() {
             return;
         }
 
         let mut f = Some(f);
-        self.call_inner(false, &mut |_| f.take().unwrap()());
+        self.inner.call(false, &mut |_| f.take().unwrap()());
     }
 
     /// Performs the same function as [`call_once()`] except ignores poisoning.
@@ -320,18 +187,19 @@ impl Once {
     /// // once any success happens, we stop propagating the poison
     /// INIT.call_once(|| {});
     /// ```
+    #[inline]
     #[stable(feature = "once_poison", since = "1.51.0")]
     pub fn call_once_force<F>(&self, f: F)
     where
         F: FnOnce(&OnceState),
     {
         // Fast path check
-        if self.is_completed() {
+        if self.inner.is_completed() {
             return;
         }
 
         let mut f = Some(f);
-        self.call_inner(true, &mut |p| f.take().unwrap()(p));
+        self.inner.call(true, &mut |p| f.take().unwrap()(p));
     }
 
     /// Returns `true` if some [`call_once()`] call has completed
@@ -378,119 +246,7 @@ impl Once {
     #[stable(feature = "once_is_completed", since = "1.43.0")]
     #[inline]
     pub fn is_completed(&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
-        // `Release` operations on the slow path.
-        self.state_and_queue.load(Ordering::Acquire).addr() == COMPLETE
-    }
-
-    // This is a non-generic function to reduce the monomorphization cost of
-    // using `call_once` (this isn't exactly a trivial or small implementation).
-    //
-    // Additionally, this is tagged with `#[cold]` as it should indeed be cold
-    // and it helps let LLVM know that calls to this function should be off the
-    // fast path. Essentially, this should help generate more straight line code
-    // in LLVM.
-    //
-    // Finally, this takes an `FnMut` instead of a `FnOnce` because there's
-    // currently no way to take an `FnOnce` and call it via virtual dispatch
-    // without some allocation overhead.
-    #[cold]
-    #[track_caller]
-    fn call_inner(&self, ignore_poisoning: bool, init: &mut dyn FnMut(&OnceState)) {
-        let mut state_and_queue = self.state_and_queue.load(Ordering::Acquire);
-        loop {
-            match state_and_queue.addr() {
-                COMPLETE => break,
-                POISONED if !ignore_poisoning => {
-                    // Panic to propagate the poison.
-                    panic!("Once instance has previously been poisoned");
-                }
-                POISONED | INCOMPLETE => {
-                    // Try to register this thread as the one RUNNING.
-                    let exchange_result = self.state_and_queue.compare_exchange(
-                        state_and_queue,
-                        ptr::invalid_mut(RUNNING),
-                        Ordering::Acquire,
-                        Ordering::Acquire,
-                    );
-                    if let Err(old) = exchange_result {
-                        state_and_queue = old;
-                        continue;
-                    }
-                    // `waiter_queue` will manage other waiting threads, and
-                    // wake them up on drop.
-                    let mut waiter_queue = WaiterQueue {
-                        state_and_queue: &self.state_and_queue,
-                        set_state_on_drop_to: ptr::invalid_mut(POISONED),
-                    };
-                    // Run the initialization function, letting it know if we're
-                    // poisoned or not.
-                    let init_state = OnceState {
-                        poisoned: state_and_queue.addr() == POISONED,
-                        set_state_on_drop_to: Cell::new(ptr::invalid_mut(COMPLETE)),
-                    };
-                    init(&init_state);
-                    waiter_queue.set_state_on_drop_to = init_state.set_state_on_drop_to.get();
-                    break;
-                }
-                _ => {
-                    // All other values must be RUNNING with possibly a
-                    // pointer to the waiter queue in the more significant bits.
-                    assert!(state_and_queue.addr() & STATE_MASK == RUNNING);
-                    wait(&self.state_and_queue, state_and_queue);
-                    state_and_queue = self.state_and_queue.load(Ordering::Acquire);
-                }
-            }
-        }
-    }
-}
-
-fn wait(state_and_queue: &AtomicPtr<Masked>, mut current_state: *mut Masked) {
-    // Note: the following code was carefully written to avoid creating a
-    // mutable reference to `node` that gets aliased.
-    loop {
-        // Don't queue this thread if the status is no longer running,
-        // otherwise we will not be woken up.
-        if current_state.addr() & STATE_MASK != RUNNING {
-            return;
-        }
-
-        // Create the node for our current thread.
-        let node = Waiter {
-            thread: Cell::new(Some(thread::current())),
-            signaled: AtomicBool::new(false),
-            next: current_state.with_addr(current_state.addr() & !STATE_MASK) as *const Waiter,
-        };
-        let me = &node as *const Waiter as *const Masked as *mut Masked;
-
-        // Try to slide in the node at the head of the linked list, making sure
-        // that another thread didn't just replace the head of the linked list.
-        let exchange_result = state_and_queue.compare_exchange(
-            current_state,
-            me.with_addr(me.addr() | RUNNING),
-            Ordering::Release,
-            Ordering::Relaxed,
-        );
-        if let Err(old) = exchange_result {
-            current_state = old;
-            continue;
-        }
-
-        // We have enqueued ourselves, now lets wait.
-        // It is important not to return before being signaled, otherwise we
-        // would drop our `Waiter` node and leave a hole in the linked list
-        // (and a dangling reference). Guard against spurious wakeups by
-        // reparking ourselves until we are signaled.
-        while !node.signaled.load(Ordering::Acquire) {
-            // If the managing thread happens to signal and unpark us before we
-            // can park ourselves, the result could be this thread never gets
-            // unparked. Luckily `park` comes with the guarantee that if it got
-            // an `unpark` just before on an unparked thread it does not park.
-            thread::park();
-        }
-        break;
+        self.inner.is_completed()
     }
 }
 
@@ -501,37 +257,6 @@ impl fmt::Debug for Once {
     }
 }
 
-impl Drop for WaiterQueue<'_> {
-    fn drop(&mut self) {
-        // Swap out our state with however we finished.
-        let state_and_queue =
-            self.state_and_queue.swap(self.set_state_on_drop_to, Ordering::AcqRel);
-
-        // We should only ever see an old state which was RUNNING.
-        assert_eq!(state_and_queue.addr() & STATE_MASK, RUNNING);
-
-        // Walk the entire linked list of waiters and wake them up (in lifo
-        // order, last to register is first to wake up).
-        unsafe {
-            // Right after setting `node.signaled = true` the other thread may
-            // free `node` if there happens to be has a spurious wakeup.
-            // So we have to take out the `thread` field and copy the pointer to
-            // `next` first.
-            let mut queue =
-                state_and_queue.with_addr(state_and_queue.addr() & !STATE_MASK) as *const Waiter;
-            while !queue.is_null() {
-                let next = (*queue).next;
-                let thread = (*queue).thread.take().unwrap();
-                (*queue).signaled.store(true, Ordering::Release);
-                // ^- FIXME (maybe): This is another case of issue #55005
-                // `store()` has a potentially dangling ref to `signaled`.
-                queue = next;
-                thread.unpark();
-            }
-        }
-    }
-}
-
 impl OnceState {
     /// Returns `true` if the associated [`Once`] was poisoned prior to the
     /// invocation of the closure passed to [`Once::call_once_force()`].
@@ -568,13 +293,22 @@ impl OnceState {
     ///     assert!(!state.is_poisoned());
     /// });
     #[stable(feature = "once_poison", since = "1.51.0")]
+    #[inline]
     pub fn is_poisoned(&self) -> bool {
-        self.poisoned
+        self.inner.is_poisoned()
     }
 
     /// Poison the associated [`Once`] without explicitly panicking.
-    // NOTE: This is currently only exposed for the `lazy` module
+    // NOTE: This is currently only exposed for `OnceLock`.
+    #[inline]
     pub(crate) fn poison(&self) {
-        self.set_state_on_drop_to.set(ptr::invalid_mut(POISONED));
+        self.inner.poison();
+    }
+}
+
+#[stable(feature = "std_debug", since = "1.16.0")]
+impl fmt::Debug for OnceState {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("OnceState").field("poisoned", &self.is_poisoned()).finish()
     }
 }
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index 9ab781561e9..8b387760768 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -76,6 +76,7 @@ use crate::sys_common::rwlock as sys;
 ///
 /// [`Mutex`]: super::Mutex
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "RwLock")]
 pub struct RwLock<T: ?Sized> {
     inner: sys::MovableRwLock,
     poison: poison::Flag,
@@ -166,7 +167,7 @@ impl<T> RwLock<T> {
 }
 
 impl<T: ?Sized> RwLock<T> {
-    /// Locks this rwlock with shared read access, blocking the current thread
+    /// Locks this `RwLock` with shared read access, blocking the current thread
     /// until it can be acquired.
     ///
     /// The calling thread will be blocked until there are no more writers which
@@ -180,9 +181,10 @@ impl<T: ?Sized> RwLock<T> {
     ///
     /// # Errors
     ///
-    /// This function will return an error if the RwLock is poisoned. An RwLock
-    /// is poisoned whenever a writer panics while holding an exclusive lock.
-    /// The failure will occur immediately after the lock has been acquired.
+    /// This function will return an error if the `RwLock` is poisoned. An
+    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
+    /// lock. The failure will occur immediately after the lock has been
+    /// acquired.
     ///
     /// # Panics
     ///
@@ -214,7 +216,7 @@ impl<T: ?Sized> RwLock<T> {
         }
     }
 
-    /// Attempts to acquire this rwlock with shared read access.
+    /// Attempts to acquire this `RwLock` with shared read access.
     ///
     /// If the access could not be granted at this time, then `Err` is returned.
     /// Otherwise, an RAII guard is returned which will release the shared access
@@ -227,13 +229,13 @@ impl<T: ?Sized> RwLock<T> {
     ///
     /// # Errors
     ///
-    /// This function will return the [`Poisoned`] error if the RwLock is poisoned.
-    /// An RwLock is poisoned whenever a writer panics while holding an exclusive
-    /// lock. `Poisoned` will only be returned if the lock would have otherwise been
-    /// acquired.
+    /// This function will return the [`Poisoned`] error if the `RwLock` is
+    /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
+    /// an exclusive lock. `Poisoned` will only be returned if the lock would
+    /// have otherwise been acquired.
     ///
-    /// This function will return the [`WouldBlock`] error if the RwLock could not
-    /// be acquired because it was already locked exclusively.
+    /// This function will return the [`WouldBlock`] error if the `RwLock` could
+    /// not be acquired because it was already locked exclusively.
     ///
     /// [`Poisoned`]: TryLockError::Poisoned
     /// [`WouldBlock`]: TryLockError::WouldBlock
@@ -262,20 +264,20 @@ impl<T: ?Sized> RwLock<T> {
         }
     }
 
-    /// Locks this rwlock with exclusive write access, blocking the current
+    /// Locks this `RwLock` with exclusive write access, blocking the current
     /// thread until it can be acquired.
     ///
     /// This function will not return while other writers or other readers
     /// currently have access to the lock.
     ///
-    /// Returns an RAII guard which will drop the write access of this rwlock
+    /// Returns an RAII guard which will drop the write access of this `RwLock`
     /// when dropped.
     ///
     /// # Errors
     ///
-    /// This function will return an error if the RwLock is poisoned. An RwLock
-    /// is poisoned whenever a writer panics while holding an exclusive lock.
-    /// An error will be returned when the lock is acquired.
+    /// This function will return an error if the `RwLock` is poisoned. An
+    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
+    /// lock. An error will be returned when the lock is acquired.
     ///
     /// # Panics
     ///
@@ -302,7 +304,7 @@ impl<T: ?Sized> RwLock<T> {
         }
     }
 
-    /// Attempts to lock this rwlock with exclusive write access.
+    /// Attempts to lock this `RwLock` with exclusive write access.
     ///
     /// If the lock could not be acquired at this time, then `Err` is returned.
     /// Otherwise, an RAII guard is returned which will release the lock when
@@ -315,13 +317,13 @@ impl<T: ?Sized> RwLock<T> {
     ///
     /// # Errors
     ///
-    /// This function will return the [`Poisoned`] error if the RwLock is
-    /// poisoned. An RwLock is poisoned whenever a writer panics while holding
-    /// an exclusive lock. `Poisoned` will only be returned if the lock would have
-    /// otherwise been acquired.
+    /// This function will return the [`Poisoned`] error if the `RwLock` is
+    /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
+    /// an exclusive lock. `Poisoned` will only be returned if the lock would
+    /// have otherwise been acquired.
     ///
-    /// This function will return the [`WouldBlock`] error if the RwLock could not
-    /// be acquired because it was already locked exclusively.
+    /// This function will return the [`WouldBlock`] error if the `RwLock` could
+    /// not be acquired because it was already locked exclusively.
     ///
     /// [`Poisoned`]: TryLockError::Poisoned
     /// [`WouldBlock`]: TryLockError::WouldBlock
@@ -421,10 +423,10 @@ impl<T: ?Sized> RwLock<T> {
     ///
     /// # Errors
     ///
-    /// This function will return an error if the RwLock is poisoned. An RwLock
-    /// is poisoned whenever a writer panics while holding an exclusive lock. An
-    /// error will only be returned if the lock would have otherwise been
-    /// acquired.
+    /// This function will return an error if the `RwLock` is poisoned. An
+    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
+    /// lock. An error will only be returned if the lock would have otherwise
+    /// been acquired.
     ///
     /// # Examples
     ///
@@ -454,10 +456,10 @@ impl<T: ?Sized> RwLock<T> {
     ///
     /// # Errors
     ///
-    /// This function will return an error if the RwLock is poisoned. An RwLock
-    /// is poisoned whenever a writer panics while holding an exclusive lock. An
-    /// error will only be returned if the lock would have otherwise been
-    /// acquired.
+    /// This function will return an error if the `RwLock` is poisoned. An
+    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
+    /// lock. An error will only be returned if the lock would have otherwise
+    /// been acquired.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/sys/common/mod.rs b/library/std/src/sys/common/mod.rs
index ff64d2aa825..29fc0835d76 100644
--- a/library/std/src/sys/common/mod.rs
+++ b/library/std/src/sys/common/mod.rs
@@ -11,3 +11,7 @@
 #![allow(dead_code)]
 
 pub mod alloc;
+pub mod small_c_string;
+
+#[cfg(test)]
+mod tests;
diff --git a/library/std/src/sys/common/small_c_string.rs b/library/std/src/sys/common/small_c_string.rs
new file mode 100644
index 00000000000..01acd519135
--- /dev/null
+++ b/library/std/src/sys/common/small_c_string.rs
@@ -0,0 +1,58 @@
+use crate::ffi::{CStr, CString};
+use crate::mem::MaybeUninit;
+use crate::path::Path;
+use crate::slice;
+use crate::{io, ptr};
+
+// Make sure to stay under 4096 so the compiler doesn't insert a probe frame:
+// https://docs.rs/compiler_builtins/latest/compiler_builtins/probestack/index.html
+#[cfg(not(target_os = "espidf"))]
+const MAX_STACK_ALLOCATION: usize = 384;
+#[cfg(target_os = "espidf")]
+const MAX_STACK_ALLOCATION: usize = 32;
+
+const NUL_ERR: io::Error =
+    io::const_io_error!(io::ErrorKind::InvalidInput, "file name contained an unexpected NUL byte");
+
+#[inline]
+pub fn run_path_with_cstr<T, F>(path: &Path, f: F) -> io::Result<T>
+where
+    F: FnOnce(&CStr) -> io::Result<T>,
+{
+    run_with_cstr(path.as_os_str().bytes(), f)
+}
+
+#[inline]
+pub fn run_with_cstr<T, F>(bytes: &[u8], f: F) -> io::Result<T>
+where
+    F: FnOnce(&CStr) -> io::Result<T>,
+{
+    if bytes.len() >= MAX_STACK_ALLOCATION {
+        return run_with_cstr_allocating(bytes, f);
+    }
+
+    let mut buf = MaybeUninit::<[u8; MAX_STACK_ALLOCATION]>::uninit();
+    let buf_ptr = buf.as_mut_ptr() as *mut u8;
+
+    unsafe {
+        ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len());
+        buf_ptr.add(bytes.len()).write(0);
+    }
+
+    match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) {
+        Ok(s) => f(s),
+        Err(_) => Err(NUL_ERR),
+    }
+}
+
+#[cold]
+#[inline(never)]
+fn run_with_cstr_allocating<T, F>(bytes: &[u8], f: F) -> io::Result<T>
+where
+    F: FnOnce(&CStr) -> io::Result<T>,
+{
+    match CString::new(bytes) {
+        Ok(s) => f(&s),
+        Err(_) => Err(NUL_ERR),
+    }
+}
diff --git a/library/std/src/sys/common/tests.rs b/library/std/src/sys/common/tests.rs
new file mode 100644
index 00000000000..fb6f5d6af83
--- /dev/null
+++ b/library/std/src/sys/common/tests.rs
@@ -0,0 +1,66 @@
+use crate::ffi::CString;
+use crate::hint::black_box;
+use crate::path::Path;
+use crate::sys::common::small_c_string::run_path_with_cstr;
+use core::iter::repeat;
+
+#[test]
+fn stack_allocation_works() {
+    let path = Path::new("abc");
+    let result = run_path_with_cstr(path, |p| {
+        assert_eq!(p, &*CString::new(path.as_os_str().bytes()).unwrap());
+        Ok(42)
+    });
+    assert_eq!(result.unwrap(), 42);
+}
+
+#[test]
+fn stack_allocation_fails() {
+    let path = Path::new("ab\0");
+    assert!(run_path_with_cstr::<(), _>(path, |_| unreachable!()).is_err());
+}
+
+#[test]
+fn heap_allocation_works() {
+    let path = repeat("a").take(384).collect::<String>();
+    let path = Path::new(&path);
+    let result = run_path_with_cstr(path, |p| {
+        assert_eq!(p, &*CString::new(path.as_os_str().bytes()).unwrap());
+        Ok(42)
+    });
+    assert_eq!(result.unwrap(), 42);
+}
+
+#[test]
+fn heap_allocation_fails() {
+    let mut path = repeat("a").take(384).collect::<String>();
+    path.push('\0');
+    let path = Path::new(&path);
+    assert!(run_path_with_cstr::<(), _>(path, |_| unreachable!()).is_err());
+}
+
+#[bench]
+fn bench_stack_path_alloc(b: &mut test::Bencher) {
+    let path = repeat("a").take(383).collect::<String>();
+    let p = Path::new(&path);
+    b.iter(|| {
+        run_path_with_cstr(p, |cstr| {
+            black_box(cstr);
+            Ok(())
+        })
+        .unwrap();
+    });
+}
+
+#[bench]
+fn bench_heap_path_alloc(b: &mut test::Bencher) {
+    let path = repeat("a").take(384).collect::<String>();
+    let p = Path::new(&path);
+    b.iter(|| {
+        run_path_with_cstr(p, |cstr| {
+            black_box(cstr);
+            Ok(())
+        })
+        .unwrap();
+    });
+}
diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs
index 1c7e1dd8d57..afcae6c90ee 100644
--- a/library/std/src/sys/hermit/args.rs
+++ b/library/std/src/sys/hermit/args.rs
@@ -1,20 +1,37 @@
-use crate::ffi::OsString;
+use crate::ffi::{c_char, CStr, OsString};
 use crate::fmt;
+use crate::os::unix::ffi::OsStringExt;
+use crate::ptr;
+use crate::sync::atomic::{
+    AtomicIsize, AtomicPtr,
+    Ordering::{Acquire, Relaxed, Release},
+};
 use crate::vec;
 
+static ARGC: AtomicIsize = AtomicIsize::new(0);
+static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
+
 /// One-time global initialization.
 pub unsafe fn init(argc: isize, argv: *const *const u8) {
-    imp::init(argc, argv)
-}
-
-/// One-time global cleanup.
-pub unsafe fn cleanup() {
-    imp::cleanup()
+    ARGC.store(argc, Relaxed);
+    // Use release ordering here to broadcast writes by the OS.
+    ARGV.store(argv as *mut *const u8, Release);
 }
 
 /// Returns the command line arguments
 pub fn args() -> Args {
-    imp::args()
+    // Synchronize with the store above.
+    let argv = ARGV.load(Acquire);
+    // If argv has not been initialized yet, do not return any arguments.
+    let argc = if argv.is_null() { 0 } else { ARGC.load(Relaxed) };
+    let args: Vec<OsString> = (0..argc)
+        .map(|i| unsafe {
+            let cstr = CStr::from_ptr(*argv.offset(i) as *const c_char);
+            OsStringExt::from_vec(cstr.to_bytes().to_vec())
+        })
+        .collect();
+
+    Args { iter: args.into_iter() }
 }
 
 pub struct Args {
@@ -51,44 +68,3 @@ impl DoubleEndedIterator for Args {
         self.iter.next_back()
     }
 }
-
-mod imp {
-    use super::Args;
-    use crate::ffi::{CStr, OsString};
-    use crate::os::unix::ffi::OsStringExt;
-    use crate::ptr;
-
-    use crate::sys_common::mutex::StaticMutex;
-
-    static mut ARGC: isize = 0;
-    static mut ARGV: *const *const u8 = ptr::null();
-    static LOCK: StaticMutex = StaticMutex::new();
-
-    pub unsafe fn init(argc: isize, argv: *const *const u8) {
-        let _guard = LOCK.lock();
-        ARGC = argc;
-        ARGV = argv;
-    }
-
-    pub unsafe fn cleanup() {
-        let _guard = LOCK.lock();
-        ARGC = 0;
-        ARGV = ptr::null();
-    }
-
-    pub fn args() -> Args {
-        Args { iter: clone().into_iter() }
-    }
-
-    fn clone() -> Vec<OsString> {
-        unsafe {
-            let _guard = LOCK.lock();
-            (0..ARGC)
-                .map(|i| {
-                    let cstr = CStr::from_ptr(*ARGV.offset(i) as *const i8);
-                    OsStringExt::from_vec(cstr.to_bytes().to_vec())
-                })
-                .collect()
-        }
-    }
-}
diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs
index f921839cf52..af297ff1ec7 100644
--- a/library/std/src/sys/hermit/fs.rs
+++ b/library/std/src/sys/hermit/fs.rs
@@ -1,3 +1,4 @@
+use crate::convert::TryFrom;
 use crate::ffi::{CStr, CString, OsString};
 use crate::fmt;
 use crate::hash::{Hash, Hasher};
@@ -5,6 +6,7 @@ use crate::io::{self, Error, ErrorKind};
 use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
 use crate::os::unix::ffi::OsStrExt;
 use crate::path::{Path, PathBuf};
+use crate::sys::common::small_c_string::run_path_with_cstr;
 use crate::sys::cvt;
 use crate::sys::hermit::abi;
 use crate::sys::hermit::abi::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
@@ -15,10 +17,6 @@ use crate::sys::unsupported;
 pub use crate::sys_common::fs::{copy, try_exists};
 //pub use crate::sys_common::fs::remove_dir_all;
 
-fn cstr(path: &Path) -> io::Result<CString> {
-    Ok(CString::new(path.as_os_str().as_bytes())?)
-}
-
 #[derive(Debug)]
 pub struct File(FileDesc);
 
@@ -272,8 +270,7 @@ impl OpenOptions {
 
 impl File {
     pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
-        let path = cstr(path)?;
-        File::open_c(&path, opts)
+        run_path_with_cstr(path, |path| File::open_c(&path, opts))
     }
 
     pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> {
@@ -373,9 +370,7 @@ pub fn readdir(_p: &Path) -> io::Result<ReadDir> {
 }
 
 pub fn unlink(path: &Path) -> io::Result<()> {
-    let name = cstr(path)?;
-    let _ = unsafe { cvt(abi::unlink(name.as_ptr()))? };
-    Ok(())
+    run_path_with_cstr(path, |path| cvt(unsafe { abi::unlink(path.as_ptr()) }).map(|_| ()))
 }
 
 pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> {
diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs
index 827d82900ea..e6534df8938 100644
--- a/library/std/src/sys/hermit/mod.rs
+++ b/library/std/src/sys/hermit/mod.rs
@@ -106,9 +106,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {
 
 // SAFETY: must be called only once during runtime cleanup.
 // NOTE: this is not guaranteed to run, for example when the program aborts.
-pub unsafe fn cleanup() {
-    args::cleanup();
-}
+pub unsafe fn cleanup() {}
 
 #[cfg(not(test))]
 #[no_mangle]
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index 167c918c94c..c080c176a2a 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -22,7 +22,7 @@
 
 #![allow(missing_debug_implementations)]
 
-mod common;
+pub mod common;
 
 cfg_if::cfg_if! {
     if #[cfg(unix)] {
diff --git a/library/std/src/sys/sgx/abi/tls/mod.rs b/library/std/src/sys/sgx/abi/tls/mod.rs
index 13d96e9a633..09c4ab3d3e9 100644
--- a/library/std/src/sys/sgx/abi/tls/mod.rs
+++ b/library/std/src/sys/sgx/abi/tls/mod.rs
@@ -111,6 +111,7 @@ impl Tls {
             rtabort!("TLS limit exceeded")
         };
         TLS_DESTRUCTOR[index].store(dtor.map_or(0, |f| f as usize), Ordering::Relaxed);
+        unsafe { Self::current() }.data[index].set(ptr::null_mut());
         Key::from_index(index)
     }
 
diff --git a/library/std/src/sys/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/sgx/abi/usercalls/alloc.rs
index 5409bd1777c..0d934318c22 100644
--- a/library/std/src/sys/sgx/abi/usercalls/alloc.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/alloc.rs
@@ -316,9 +316,9 @@ where
 //   | small1 | Chunk smaller than 8 bytes
 //   +--------+
 fn region_as_aligned_chunks(ptr: *const u8, len: usize) -> (usize, usize, usize) {
-    let small0_size = if ptr as usize % 8 == 0 { 0 } else { 8 - ptr as usize % 8 };
-    let small1_size = (len - small0_size as usize) % 8;
-    let big_size = len - small0_size as usize - small1_size as usize;
+    let small0_size = if ptr.is_aligned_to(8) { 0 } else { 8 - ptr.addr() % 8 };
+    let small1_size = (len - small0_size) % 8;
+    let big_size = len - small0_size - small1_size;
 
     (small0_size, big_size, small1_size)
 }
@@ -364,8 +364,8 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize)
                     mfence
                     lfence
                     ",
-                    val = in(reg_byte) *src.offset(off as isize),
-                    dst = in(reg) dst.offset(off as isize),
+                    val = in(reg_byte) *src.add(off),
+                    dst = in(reg) dst.add(off),
                     seg_sel = in(reg) &mut seg_sel,
                     options(nostack, att_syntax)
                 );
@@ -378,8 +378,8 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize)
     assert!(is_enclave_range(src, len));
     assert!(is_user_range(dst, len));
     assert!(len < isize::MAX as usize);
-    assert!(!(src as usize).overflowing_add(len).1);
-    assert!(!(dst as usize).overflowing_add(len).1);
+    assert!(!src.addr().overflowing_add(len).1);
+    assert!(!dst.addr().overflowing_add(len).1);
 
     if len < 8 {
         // Can't align on 8 byte boundary: copy safely byte per byte
@@ -404,17 +404,17 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize)
 
         unsafe {
             // Copy small0
-            copy_bytewise_to_userspace(src, dst, small0_size as _);
+            copy_bytewise_to_userspace(src, dst, small0_size);
 
             // Copy big
-            let big_src = src.offset(small0_size as _);
-            let big_dst = dst.offset(small0_size as _);
-            copy_quadwords(big_src as _, big_dst, big_size);
+            let big_src = src.add(small0_size);
+            let big_dst = dst.add(small0_size);
+            copy_quadwords(big_src, big_dst, big_size);
 
             // Copy small1
-            let small1_src = src.offset(big_size as isize + small0_size as isize);
-            let small1_dst = dst.offset(big_size as isize + small0_size as isize);
-            copy_bytewise_to_userspace(small1_src, small1_dst, small1_size as _);
+            let small1_src = src.add(big_size + small0_size);
+            let small1_dst = dst.add(big_size + small0_size);
+            copy_bytewise_to_userspace(small1_src, small1_dst, small1_size);
         }
     }
 }
diff --git a/library/std/src/sys/sgx/thread_local_key.rs b/library/std/src/sys/sgx/thread_local_key.rs
index b21784475f0..c7a57d3a3d4 100644
--- a/library/std/src/sys/sgx/thread_local_key.rs
+++ b/library/std/src/sys/sgx/thread_local_key.rs
@@ -21,8 +21,3 @@ pub unsafe fn get(key: Key) -> *mut u8 {
 pub unsafe fn destroy(key: Key) {
     Tls::destroy(AbiKey::from_usize(key))
 }
-
-#[inline]
-pub fn requires_synchronized_create() -> bool {
-    false
-}
diff --git a/library/std/src/sys/solid/os.rs b/library/std/src/sys/solid/os.rs
index eecb347e599..4906c62689d 100644
--- a/library/std/src/sys/solid/os.rs
+++ b/library/std/src/sys/solid/os.rs
@@ -1,4 +1,5 @@
 use super::unsupported;
+use crate::convert::TryFrom;
 use crate::error::Error as StdError;
 use crate::ffi::{CStr, CString, OsStr, OsString};
 use crate::fmt;
@@ -9,6 +10,7 @@ use crate::os::{
 };
 use crate::path::{self, PathBuf};
 use crate::sync::RwLock;
+use crate::sys::common::small_c_string::run_with_cstr;
 use crate::vec;
 
 use super::{error, itron, memchr};
@@ -139,35 +141,33 @@ pub fn env() -> Env {
 pub fn getenv(k: &OsStr) -> Option<OsString> {
     // environment variables with a nul byte can't be set, so their value is
     // always None as well
-    let k = CString::new(k.as_bytes()).ok()?;
-    unsafe {
+    let s = run_with_cstr(k.as_bytes(), |k| {
         let _guard = ENV_LOCK.read();
-        let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
-        if s.is_null() {
-            None
-        } else {
-            Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
-        }
+        Ok(unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char)
+    })
+    .ok()?;
+
+    if s.is_null() {
+        None
+    } else {
+        Some(OsStringExt::from_vec(unsafe { CStr::from_ptr(s) }.to_bytes().to_vec()))
     }
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
-    let k = CString::new(k.as_bytes())?;
-    let v = CString::new(v.as_bytes())?;
-
-    unsafe {
-        let _guard = ENV_LOCK.write();
-        cvt_env(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop)
-    }
+    run_with_cstr(k.as_bytes(), |k| {
+        run_with_cstr(v.as_bytes(), |v| {
+            let _guard = ENV_LOCK.write();
+            cvt_env(unsafe { libc::setenv(k.as_ptr(), v.as_ptr(), 1) }).map(drop)
+        })
+    })
 }
 
 pub fn unsetenv(n: &OsStr) -> io::Result<()> {
-    let nbuf = CString::new(n.as_bytes())?;
-
-    unsafe {
+    run_with_cstr(n.as_bytes(), |nbuf| {
         let _guard = ENV_LOCK.write();
-        cvt_env(libc::unsetenv(nbuf.as_ptr())).map(drop)
-    }
+        cvt_env(unsafe { libc::unsetenv(nbuf.as_ptr()) }).map(drop)
+    })
 }
 
 /// In kmclib, `setenv` and `unsetenv` don't always set `errno`, so this
diff --git a/library/std/src/sys/solid/thread_local_key.rs b/library/std/src/sys/solid/thread_local_key.rs
index b17521f701d..b37bf999698 100644
--- a/library/std/src/sys/solid/thread_local_key.rs
+++ b/library/std/src/sys/solid/thread_local_key.rs
@@ -19,8 +19,3 @@ pub unsafe fn get(_key: Key) -> *mut u8 {
 pub unsafe fn destroy(_key: Key) {
     panic!("should not be used on the solid target");
 }
-
-#[inline]
-pub fn requires_synchronized_create() -> bool {
-    panic!("should not be used on the solid target");
-}
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index cc347e3586a..780f46f8c11 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -1,6 +1,6 @@
 use crate::os::unix::prelude::*;
 
-use crate::ffi::{CStr, CString, OsStr, OsString};
+use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt;
 use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem;
@@ -8,6 +8,7 @@ use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd};
 use crate::path::{Path, PathBuf};
 use crate::ptr;
 use crate::sync::Arc;
+use crate::sys::common::small_c_string::run_path_with_cstr;
 use crate::sys::fd::FileDesc;
 use crate::sys::time::SystemTime;
 use crate::sys::{cvt, cvt_r};
@@ -260,7 +261,7 @@ pub struct DirEntry {
     // We need to store an owned copy of the entry name on platforms that use
     // readdir() (not readdir_r()), because a) struct dirent may use a flexible
     // array to store the name, b) it lives only until the next readdir() call.
-    name: CString,
+    name: crate::ffi::CString,
 }
 
 // Define a minimal subset of fields we need from `dirent64`, especially since
@@ -313,8 +314,11 @@ pub struct FilePermissions {
     mode: mode_t,
 }
 
-#[derive(Copy, Clone)]
-pub struct FileTimes([libc::timespec; 2]);
+#[derive(Copy, Clone, Debug, Default)]
+pub struct FileTimes {
+    accessed: Option<SystemTime>,
+    modified: Option<SystemTime>,
+}
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct FileType {
@@ -512,45 +516,11 @@ impl FilePermissions {
 
 impl FileTimes {
     pub fn set_accessed(&mut self, t: SystemTime) {
-        self.0[0] = t.t.to_timespec().expect("Invalid system time");
+        self.accessed = Some(t);
     }
 
     pub fn set_modified(&mut self, t: SystemTime) {
-        self.0[1] = t.t.to_timespec().expect("Invalid system time");
-    }
-}
-
-struct TimespecDebugAdapter<'a>(&'a libc::timespec);
-
-impl fmt::Debug for TimespecDebugAdapter<'_> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("timespec")
-            .field("tv_sec", &self.0.tv_sec)
-            .field("tv_nsec", &self.0.tv_nsec)
-            .finish()
-    }
-}
-
-impl fmt::Debug for FileTimes {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("FileTimes")
-            .field("accessed", &TimespecDebugAdapter(&self.0[0]))
-            .field("modified", &TimespecDebugAdapter(&self.0[1]))
-            .finish()
-    }
-}
-
-impl Default for FileTimes {
-    fn default() -> Self {
-        // Redox doesn't appear to support `UTIME_OMIT`, so we stub it out here, and always return
-        // an error in `set_times`.
-        // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
-        // the same as for Redox.
-        #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))]
-        let omit = libc::timespec { tv_sec: 0, tv_nsec: 0 };
-        #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
-        let omit = libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ };
-        Self([omit; 2])
+        self.modified = Some(t);
     }
 }
 
@@ -704,7 +674,10 @@ impl DirEntry {
         self.file_name_os_str().to_os_string()
     }
 
-    #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))]
+    #[cfg(all(
+        any(target_os = "linux", target_os = "emscripten", target_os = "android"),
+        not(miri)
+    ))]
     pub fn metadata(&self) -> io::Result<FileAttr> {
         let fd = cvt(unsafe { dirfd(self.dir.dirp.0) })?;
         let name = self.name_cstr().as_ptr();
@@ -725,7 +698,10 @@ impl DirEntry {
         Ok(FileAttr::from_stat64(stat))
     }
 
-    #[cfg(not(any(target_os = "linux", target_os = "emscripten", target_os = "android")))]
+    #[cfg(any(
+        not(any(target_os = "linux", target_os = "emscripten", target_os = "android")),
+        miri
+    ))]
     pub fn metadata(&self) -> io::Result<FileAttr> {
         lstat(&self.path())
     }
@@ -931,8 +907,7 @@ impl OpenOptions {
 
 impl File {
     pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
-        let path = cstr(path)?;
-        File::open_c(&path, opts)
+        run_path_with_cstr(path, |path| File::open_c(path, opts))
     }
 
     pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> {
@@ -1084,6 +1059,17 @@ impl File {
     }
 
     pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
+        #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
+        let to_timespec = |time: Option<SystemTime>| {
+            match time {
+                Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts),
+                Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time")),
+                Some(_) => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too small to set as a file time")),
+                None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
+            }
+        };
+        #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
+        let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
         cfg_if::cfg_if! {
             if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] {
                 // Redox doesn't appear to support `UTIME_OMIT`.
@@ -1099,7 +1085,7 @@ impl File {
                 cvt(unsafe {
                     weak!(fn futimens(c_int, *const libc::timespec) -> c_int);
                     match futimens.get() {
-                        Some(futimens) => futimens(self.as_raw_fd(), times.0.as_ptr()),
+                        Some(futimens) => futimens(self.as_raw_fd(), times.as_ptr()),
                         #[cfg(target_os = "macos")]
                         None => {
                             fn ts_to_tv(ts: &libc::timespec) -> libc::timeval {
@@ -1108,7 +1094,7 @@ impl File {
                                     tv_usec: (ts.tv_nsec / 1000) as _
                                 }
                             }
-                            let timevals = [ts_to_tv(&times.0[0]), ts_to_tv(&times.0[1])];
+                            let timevals = [ts_to_tv(&times[0]), ts_to_tv(&times[1])];
                             libc::futimes(self.as_raw_fd(), timevals.as_ptr())
                         }
                         // futimes requires even newer Android.
@@ -1121,7 +1107,7 @@ impl File {
                 })?;
                 Ok(())
             } else {
-                cvt(unsafe { libc::futimens(self.as_raw_fd(), times.0.as_ptr()) })?;
+                cvt(unsafe { libc::futimens(self.as_raw_fd(), times.as_ptr()) })?;
                 Ok(())
             }
         }
@@ -1134,9 +1120,7 @@ impl DirBuilder {
     }
 
     pub fn mkdir(&self, p: &Path) -> io::Result<()> {
-        let p = cstr(p)?;
-        cvt(unsafe { libc::mkdir(p.as_ptr(), self.mode) })?;
-        Ok(())
+        run_path_with_cstr(p, |p| cvt(unsafe { libc::mkdir(p.as_ptr(), self.mode) }).map(|_| ()))
     }
 
     pub fn set_mode(&mut self, mode: u32) {
@@ -1144,10 +1128,6 @@ impl DirBuilder {
     }
 }
 
-fn cstr(path: &Path) -> io::Result<CString> {
-    Ok(CString::new(path.as_os_str().as_bytes())?)
-}
-
 impl AsInner<FileDesc> for File {
     fn as_inner(&self) -> &FileDesc {
         &self.0
@@ -1198,7 +1178,12 @@ impl FromRawFd for File {
 
 impl fmt::Debug for File {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        #[cfg(any(target_os = "linux", target_os = "netbsd"))]
+        #[cfg(any(
+            target_os = "linux",
+            target_os = "netbsd",
+            target_os = "illumos",
+            target_os = "solaris"
+        ))]
         fn get_path(fd: c_int) -> Option<PathBuf> {
             let mut p = PathBuf::from("/proc/self/fd");
             p.push(&fd.to_string());
@@ -1253,14 +1238,23 @@ impl fmt::Debug for File {
             target_os = "macos",
             target_os = "vxworks",
             all(target_os = "freebsd", target_arch = "x86_64"),
-            target_os = "netbsd"
+            target_os = "netbsd",
+            target_os = "illumos",
+            target_os = "solaris"
         )))]
         fn get_path(_fd: c_int) -> Option<PathBuf> {
             // FIXME(#24570): implement this for other Unix platforms
             None
         }
 
-        #[cfg(any(target_os = "linux", target_os = "macos", target_os = "vxworks"))]
+        #[cfg(any(
+            target_os = "linux",
+            target_os = "macos",
+            target_os = "freebsd",
+            target_os = "netbsd",
+            target_os = "openbsd",
+            target_os = "vxworks"
+        ))]
         fn get_mode(fd: c_int) -> Option<(bool, bool)> {
             let mode = unsafe { libc::fcntl(fd, libc::F_GETFL) };
             if mode == -1 {
@@ -1274,7 +1268,14 @@ impl fmt::Debug for File {
             }
         }
 
-        #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "vxworks")))]
+        #[cfg(not(any(
+            target_os = "linux",
+            target_os = "macos",
+            target_os = "freebsd",
+            target_os = "netbsd",
+            target_os = "openbsd",
+            target_os = "vxworks"
+        )))]
         fn get_mode(_fd: c_int) -> Option<(bool, bool)> {
             // FIXME(#24570): implement this for other Unix platforms
             None
@@ -1293,173 +1294,170 @@ impl fmt::Debug for File {
     }
 }
 
-pub fn readdir(p: &Path) -> io::Result<ReadDir> {
-    let root = p.to_path_buf();
-    let p = cstr(p)?;
-    unsafe {
-        let ptr = libc::opendir(p.as_ptr());
-        if ptr.is_null() {
-            Err(Error::last_os_error())
-        } else {
-            let inner = InnerReadDir { dirp: Dir(ptr), root };
-            Ok(ReadDir {
-                inner: Arc::new(inner),
-                #[cfg(not(any(
-                    target_os = "android",
-                    target_os = "linux",
-                    target_os = "solaris",
-                    target_os = "illumos",
-                    target_os = "fuchsia",
-                    target_os = "redox",
-                )))]
-                end_of_stream: false,
-            })
-        }
+pub fn readdir(path: &Path) -> io::Result<ReadDir> {
+    let ptr = run_path_with_cstr(path, |p| unsafe { Ok(libc::opendir(p.as_ptr())) })?;
+    if ptr.is_null() {
+        Err(Error::last_os_error())
+    } else {
+        let root = path.to_path_buf();
+        let inner = InnerReadDir { dirp: Dir(ptr), root };
+        Ok(ReadDir {
+            inner: Arc::new(inner),
+            #[cfg(not(any(
+                target_os = "android",
+                target_os = "linux",
+                target_os = "solaris",
+                target_os = "illumos",
+                target_os = "fuchsia",
+                target_os = "redox",
+            )))]
+            end_of_stream: false,
+        })
     }
 }
 
 pub fn unlink(p: &Path) -> io::Result<()> {
-    let p = cstr(p)?;
-    cvt(unsafe { libc::unlink(p.as_ptr()) })?;
-    Ok(())
+    run_path_with_cstr(p, |p| cvt(unsafe { libc::unlink(p.as_ptr()) }).map(|_| ()))
 }
 
 pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
-    let old = cstr(old)?;
-    let new = cstr(new)?;
-    cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) })?;
-    Ok(())
+    run_path_with_cstr(old, |old| {
+        run_path_with_cstr(new, |new| {
+            cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }).map(|_| ())
+        })
+    })
 }
 
 pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
-    let p = cstr(p)?;
-    cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) })?;
-    Ok(())
+    run_path_with_cstr(p, |p| cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }).map(|_| ()))
 }
 
 pub fn rmdir(p: &Path) -> io::Result<()> {
-    let p = cstr(p)?;
-    cvt(unsafe { libc::rmdir(p.as_ptr()) })?;
-    Ok(())
+    run_path_with_cstr(p, |p| cvt(unsafe { libc::rmdir(p.as_ptr()) }).map(|_| ()))
 }
 
 pub fn readlink(p: &Path) -> io::Result<PathBuf> {
-    let c_path = cstr(p)?;
-    let p = c_path.as_ptr();
+    run_path_with_cstr(p, |c_path| {
+        let p = c_path.as_ptr();
 
-    let mut buf = Vec::with_capacity(256);
+        let mut buf = Vec::with_capacity(256);
 
-    loop {
-        let buf_read =
-            cvt(unsafe { libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) })? as usize;
+        loop {
+            let buf_read =
+                cvt(unsafe { libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) })?
+                    as usize;
 
-        unsafe {
-            buf.set_len(buf_read);
-        }
+            unsafe {
+                buf.set_len(buf_read);
+            }
 
-        if buf_read != buf.capacity() {
-            buf.shrink_to_fit();
+            if buf_read != buf.capacity() {
+                buf.shrink_to_fit();
 
-            return Ok(PathBuf::from(OsString::from_vec(buf)));
-        }
+                return Ok(PathBuf::from(OsString::from_vec(buf)));
+            }
 
-        // Trigger the internal buffer resizing logic of `Vec` by requiring
-        // more space than the current capacity. The length is guaranteed to be
-        // the same as the capacity due to the if statement above.
-        buf.reserve(1);
-    }
+            // Trigger the internal buffer resizing logic of `Vec` by requiring
+            // more space than the current capacity. The length is guaranteed to be
+            // the same as the capacity due to the if statement above.
+            buf.reserve(1);
+        }
+    })
 }
 
 pub fn symlink(original: &Path, link: &Path) -> io::Result<()> {
-    let original = cstr(original)?;
-    let link = cstr(link)?;
-    cvt(unsafe { libc::symlink(original.as_ptr(), link.as_ptr()) })?;
-    Ok(())
+    run_path_with_cstr(original, |original| {
+        run_path_with_cstr(link, |link| {
+            cvt(unsafe { libc::symlink(original.as_ptr(), link.as_ptr()) }).map(|_| ())
+        })
+    })
 }
 
 pub fn link(original: &Path, link: &Path) -> io::Result<()> {
-    let original = cstr(original)?;
-    let link = cstr(link)?;
-    cfg_if::cfg_if! {
-        if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon"))] {
-            // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves
-            // it implementation-defined whether `link` follows symlinks, so rely on the
-            // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior.
-            // Android has `linkat` on newer versions, but we happen to know `link`
-            // always has the correct behavior, so it's here as well.
-            cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
-        } else if #[cfg(target_os = "macos")] {
-            // On MacOS, older versions (<=10.9) lack support for linkat while newer
-            // versions have it. We want to use linkat if it is available, so we use weak!
-            // to check. `linkat` is preferable to `link` because it gives us a flag to
-            // specify how symlinks should be handled. We pass 0 as the flags argument,
-            // meaning it shouldn't follow symlinks.
-            weak!(fn linkat(c_int, *const c_char, c_int, *const c_char, c_int) -> c_int);
-
-            if let Some(f) = linkat.get() {
-                cvt(unsafe { f(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
-            } else {
-                cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
-            };
-        } else {
-            // Where we can, use `linkat` instead of `link`; see the comment above
-            // this one for details on why.
-            cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
-        }
-    }
-    Ok(())
+    run_path_with_cstr(original, |original| {
+        run_path_with_cstr(link, |link| {
+            cfg_if::cfg_if! {
+                if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon"))] {
+                    // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves
+                    // it implementation-defined whether `link` follows symlinks, so rely on the
+                    // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior.
+                    // Android has `linkat` on newer versions, but we happen to know `link`
+                    // always has the correct behavior, so it's here as well.
+                    cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
+                } else if #[cfg(target_os = "macos")] {
+                    // On MacOS, older versions (<=10.9) lack support for linkat while newer
+                    // versions have it. We want to use linkat if it is available, so we use weak!
+                    // to check. `linkat` is preferable to `link` because it gives us a flag to
+                    // specify how symlinks should be handled. We pass 0 as the flags argument,
+                    // meaning it shouldn't follow symlinks.
+                    weak!(fn linkat(c_int, *const c_char, c_int, *const c_char, c_int) -> c_int);
+
+                    if let Some(f) = linkat.get() {
+                        cvt(unsafe { f(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
+                    } else {
+                        cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
+                    };
+                } else {
+                    // Where we can, use `linkat` instead of `link`; see the comment above
+                    // this one for details on why.
+                    cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
+                }
+            }
+            Ok(())
+        })
+    })
 }
 
 pub fn stat(p: &Path) -> io::Result<FileAttr> {
-    let p = cstr(p)?;
-
-    cfg_has_statx! {
-        if let Some(ret) = unsafe { try_statx(
-            libc::AT_FDCWD,
-            p.as_ptr(),
-            libc::AT_STATX_SYNC_AS_STAT,
-            libc::STATX_ALL,
-        ) } {
-            return ret;
+    run_path_with_cstr(p, |p| {
+        cfg_has_statx! {
+            if let Some(ret) = unsafe { try_statx(
+                libc::AT_FDCWD,
+                p.as_ptr(),
+                libc::AT_STATX_SYNC_AS_STAT,
+                libc::STATX_ALL,
+            ) } {
+                return ret;
+            }
         }
-    }
 
-    let mut stat: stat64 = unsafe { mem::zeroed() };
-    cvt(unsafe { stat64(p.as_ptr(), &mut stat) })?;
-    Ok(FileAttr::from_stat64(stat))
+        let mut stat: stat64 = unsafe { mem::zeroed() };
+        cvt(unsafe { stat64(p.as_ptr(), &mut stat) })?;
+        Ok(FileAttr::from_stat64(stat))
+    })
 }
 
 pub fn lstat(p: &Path) -> io::Result<FileAttr> {
-    let p = cstr(p)?;
-
-    cfg_has_statx! {
-        if let Some(ret) = unsafe { try_statx(
-            libc::AT_FDCWD,
-            p.as_ptr(),
-            libc::AT_SYMLINK_NOFOLLOW | libc::AT_STATX_SYNC_AS_STAT,
-            libc::STATX_ALL,
-        ) } {
-            return ret;
+    run_path_with_cstr(p, |p| {
+        cfg_has_statx! {
+            if let Some(ret) = unsafe { try_statx(
+                libc::AT_FDCWD,
+                p.as_ptr(),
+                libc::AT_SYMLINK_NOFOLLOW | libc::AT_STATX_SYNC_AS_STAT,
+                libc::STATX_ALL,
+            ) } {
+                return ret;
+            }
         }
-    }
 
-    let mut stat: stat64 = unsafe { mem::zeroed() };
-    cvt(unsafe { lstat64(p.as_ptr(), &mut stat) })?;
-    Ok(FileAttr::from_stat64(stat))
+        let mut stat: stat64 = unsafe { mem::zeroed() };
+        cvt(unsafe { lstat64(p.as_ptr(), &mut stat) })?;
+        Ok(FileAttr::from_stat64(stat))
+    })
 }
 
 pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
-    let path = CString::new(p.as_os_str().as_bytes())?;
-    let buf;
-    unsafe {
-        let r = libc::realpath(path.as_ptr(), ptr::null_mut());
-        if r.is_null() {
-            return Err(io::Error::last_os_error());
-        }
-        buf = CStr::from_ptr(r).to_bytes().to_vec();
-        libc::free(r as *mut _);
+    let r = run_path_with_cstr(p, |path| unsafe {
+        Ok(libc::realpath(path.as_ptr(), ptr::null_mut()))
+    })?;
+    if r.is_null() {
+        return Err(io::Error::last_os_error());
     }
-    Ok(PathBuf::from(OsString::from_vec(buf)))
+    Ok(PathBuf::from(OsString::from_vec(unsafe {
+        let buf = CStr::from_ptr(r).to_bytes().to_vec();
+        libc::free(r as *mut _);
+        buf
+    })))
 }
 
 fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> {
@@ -1609,9 +1607,9 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     // Opportunistically attempt to create a copy-on-write clone of `from`
     // using `fclonefileat`.
     if HAS_FCLONEFILEAT.load(Ordering::Relaxed) {
-        let to = cstr(to)?;
-        let clonefile_result =
-            cvt(unsafe { fclonefileat(reader.as_raw_fd(), libc::AT_FDCWD, to.as_ptr(), 0) });
+        let clonefile_result = run_path_with_cstr(to, |to| {
+            cvt(unsafe { fclonefileat(reader.as_raw_fd(), libc::AT_FDCWD, to.as_ptr(), 0) })
+        });
         match clonefile_result {
             Ok(_) => return Ok(reader_metadata.len()),
             Err(err) => match err.raw_os_error() {
@@ -1655,9 +1653,10 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
 }
 
 pub fn chown(path: &Path, uid: u32, gid: u32) -> io::Result<()> {
-    let path = cstr(path)?;
-    cvt(unsafe { libc::chown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })?;
-    Ok(())
+    run_path_with_cstr(path, |path| {
+        cvt(unsafe { libc::chown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })
+            .map(|_| ())
+    })
 }
 
 pub fn fchown(fd: c_int, uid: u32, gid: u32) -> io::Result<()> {
@@ -1666,16 +1665,15 @@ pub fn fchown(fd: c_int, uid: u32, gid: u32) -> io::Result<()> {
 }
 
 pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> {
-    let path = cstr(path)?;
-    cvt(unsafe { libc::lchown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })?;
-    Ok(())
+    run_path_with_cstr(path, |path| {
+        cvt(unsafe { libc::lchown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })
+            .map(|_| ())
+    })
 }
 
 #[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))]
 pub fn chroot(dir: &Path) -> io::Result<()> {
-    let dir = cstr(dir)?;
-    cvt(unsafe { libc::chroot(dir.as_ptr()) })?;
-    Ok(())
+    run_path_with_cstr(dir, |dir| cvt(unsafe { libc::chroot(dir.as_ptr()) }).map(|_| ()))
 }
 
 pub use remove_dir_impl::remove_dir_all;
@@ -1689,13 +1687,14 @@ mod remove_dir_impl {
 // Modern implementation using openat(), unlinkat() and fdopendir()
 #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon", miri)))]
 mod remove_dir_impl {
-    use super::{cstr, lstat, Dir, DirEntry, InnerReadDir, ReadDir};
+    use super::{lstat, Dir, DirEntry, InnerReadDir, ReadDir};
     use crate::ffi::CStr;
     use crate::io;
     use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd};
     use crate::os::unix::prelude::{OwnedFd, RawFd};
     use crate::path::{Path, PathBuf};
     use crate::sync::Arc;
+    use crate::sys::common::small_c_string::run_path_with_cstr;
     use crate::sys::{cvt, cvt_r};
 
     #[cfg(not(all(target_os = "macos", not(target_arch = "aarch64")),))]
@@ -1862,7 +1861,7 @@ mod remove_dir_impl {
         if attr.file_type().is_symlink() {
             crate::fs::remove_file(p)
         } else {
-            remove_dir_all_recursive(None, &cstr(p)?)
+            run_path_with_cstr(p, |p| remove_dir_all_recursive(None, &p))
         }
     }
 
diff --git a/library/std/src/sys/unix/io.rs b/library/std/src/sys/unix/io.rs
index deb5ee76bd0..29c340dd349 100644
--- a/library/std/src/sys/unix/io.rs
+++ b/library/std/src/sys/unix/io.rs
@@ -1,4 +1,5 @@
 use crate::marker::PhantomData;
+use crate::os::fd::{AsFd, AsRawFd};
 use crate::slice;
 
 use libc::{c_void, iovec};
@@ -74,3 +75,8 @@ impl<'a> IoSliceMut<'a> {
         unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
     }
 }
+
+pub fn is_terminal(fd: &impl AsFd) -> bool {
+    let fd = fd.as_fd();
+    unsafe { libc::isatty(fd.as_raw_fd()) != 0 }
+}
diff --git a/library/std/src/sys/unix/kernel_copy.rs b/library/std/src/sys/unix/kernel_copy.rs
index 8f7abb55e23..94546ca09d0 100644
--- a/library/std/src/sys/unix/kernel_copy.rs
+++ b/library/std/src/sys/unix/kernel_copy.rs
@@ -20,7 +20,7 @@
 //! Since those syscalls have requirements that cannot be fully checked in advance and
 //! gathering additional information about file descriptors would require additional syscalls
 //! anyway it simply attempts to use them one after another (guided by inaccurate hints) to
-//! figure out which one works and and falls back to the generic read-write copy loop if none of them
+//! figure out which one works and falls back to the generic read-write copy loop if none of them
 //! does.
 //! Once a working syscall is found for a pair of file descriptors it will be called in a loop
 //! until the copy operation is completed.
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index 3c3770708b1..2f2663db607 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -7,6 +7,7 @@ mod tests;
 
 use crate::os::unix::prelude::*;
 
+use crate::convert::TryFrom;
 use crate::error::Error as StdError;
 use crate::ffi::{CStr, CString, OsStr, OsString};
 use crate::fmt;
@@ -18,6 +19,7 @@ use crate::ptr;
 use crate::slice;
 use crate::str;
 use crate::sync::{PoisonError, RwLock};
+use crate::sys::common::small_c_string::{run_path_with_cstr, run_with_cstr};
 use crate::sys::cvt;
 use crate::sys::fd;
 use crate::sys::memchr;
@@ -125,7 +127,9 @@ pub fn error_string(errno: i32) -> String {
         }
 
         let p = p as *const _;
-        str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
+        // We can't always expect a UTF-8 environment. When we don't get that luxury,
+        // it's better to give a low-quality error message than none at all.
+        String::from_utf8_lossy(CStr::from_ptr(p).to_bytes()).into()
     }
 }
 
@@ -168,12 +172,8 @@ pub fn chdir(p: &path::Path) -> io::Result<()> {
 
 #[cfg(not(target_os = "espidf"))]
 pub fn chdir(p: &path::Path) -> io::Result<()> {
-    let p: &OsStr = p.as_ref();
-    let p = CString::new(p.as_bytes())?;
-    if unsafe { libc::chdir(p.as_ptr()) } != 0 {
-        return Err(io::Error::last_os_error());
-    }
-    Ok(())
+    let result = run_path_with_cstr(p, |p| unsafe { Ok(libc::chdir(p.as_ptr())) })?;
+    if result == 0 { Ok(()) } else { Err(io::Error::last_os_error()) }
 }
 
 pub struct SplitPaths<'a> {
@@ -546,35 +546,32 @@ pub fn env() -> Env {
 pub fn getenv(k: &OsStr) -> Option<OsString> {
     // environment variables with a nul byte can't be set, so their value is
     // always None as well
-    let k = CString::new(k.as_bytes()).ok()?;
-    unsafe {
+    let s = run_with_cstr(k.as_bytes(), |k| {
         let _guard = env_read_lock();
-        let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
-        if s.is_null() {
-            None
-        } else {
-            Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
-        }
+        Ok(unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char)
+    })
+    .ok()?;
+    if s.is_null() {
+        None
+    } else {
+        Some(OsStringExt::from_vec(unsafe { CStr::from_ptr(s) }.to_bytes().to_vec()))
     }
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
-    let k = CString::new(k.as_bytes())?;
-    let v = CString::new(v.as_bytes())?;
-
-    unsafe {
-        let _guard = ENV_LOCK.write();
-        cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop)
-    }
+    run_with_cstr(k.as_bytes(), |k| {
+        run_with_cstr(v.as_bytes(), |v| {
+            let _guard = ENV_LOCK.write();
+            cvt(unsafe { libc::setenv(k.as_ptr(), v.as_ptr(), 1) }).map(drop)
+        })
+    })
 }
 
 pub fn unsetenv(n: &OsStr) -> io::Result<()> {
-    let nbuf = CString::new(n.as_bytes())?;
-
-    unsafe {
+    run_with_cstr(n.as_bytes(), |nbuf| {
         let _guard = ENV_LOCK.write();
-        cvt(libc::unsetenv(nbuf.as_ptr())).map(drop)
-    }
+        cvt(unsafe { libc::unsetenv(nbuf.as_ptr()) }).map(drop)
+    })
 }
 
 #[cfg(not(target_os = "espidf"))]
diff --git a/library/std/src/sys/unix/process/process_fuchsia.rs b/library/std/src/sys/unix/process/process_fuchsia.rs
index 73f5d3a618b..66ea3db2015 100644
--- a/library/std/src/sys/unix/process/process_fuchsia.rs
+++ b/library/std/src/sys/unix/process/process_fuchsia.rs
@@ -287,7 +287,7 @@ impl ExitStatus {
         // SuS and POSIX) say a wait status is, but Fuchsia apparently uses a u64, so it won't
         // necessarily fit.
         //
-        // It seems to me that that the right answer would be to provide std::os::fuchsia with its
+        // It seems to me that the right answer would be to provide std::os::fuchsia with its
         // own ExitStatusExt, rather that trying to provide a not very convincing imitation of
         // Unix.  Ie, std::os::unix::process:ExitStatusExt ought not to exist on Fuchsia.  But
         // fixing this up that is beyond the scope of my efforts now.
diff --git a/library/std/src/sys/unix/rand.rs b/library/std/src/sys/unix/rand.rs
index 40885417308..a6fe07873d7 100644
--- a/library/std/src/sys/unix/rand.rs
+++ b/library/std/src/sys/unix/rand.rs
@@ -137,9 +137,11 @@ mod imp {
     }
 }
 
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
+#[cfg(target_os = "macos")]
 mod imp {
-    use crate::io;
+    use crate::fs::File;
+    use crate::io::Read;
+    use crate::sys::os::errno;
     use crate::sys::weak::weak;
     use libc::{c_int, c_void, size_t};
 
@@ -153,7 +155,7 @@ mod imp {
                 for s in v.chunks_mut(256) {
                     let ret = unsafe { f(s.as_mut_ptr() as *mut c_void, s.len()) };
                     if ret == -1 {
-                        panic!("unexpected getentropy error: {}", io::Error::last_os_error());
+                        panic!("unexpected getentropy error: {}", errno());
                     }
                 }
                 true
@@ -161,64 +163,14 @@ mod imp {
             .unwrap_or(false)
     }
 
-    #[cfg(target_os = "macos")]
-    fn fallback_fill_bytes(v: &mut [u8]) {
-        use crate::fs::File;
-        use crate::io::Read;
-
-        let mut file = File::open("/dev/urandom").expect("failed to open /dev/urandom");
-        file.read_exact(v).expect("failed to read /dev/urandom")
-    }
-
-    // On iOS and MacOS `SecRandomCopyBytes` calls `CCRandomCopyBytes` with
-    // `kCCRandomDefault`. `CCRandomCopyBytes` manages a CSPRNG which is seeded
-    // from `/dev/random` and which runs on its own thread accessed via GCD.
-    //
-    // This is very heavyweight compared to the alternatives, but they may not be usable:
-    // - `getentropy` was added in iOS 10, but we support a minimum of iOS 7
-    // - `/dev/urandom` is not accessible inside the iOS app sandbox.
-    //
-    // Therefore `SecRandomCopyBytes` is only used on older iOS versions where no
-    // better options are present.
-    #[cfg(target_os = "ios")]
-    fn fallback_fill_bytes(v: &mut [u8]) {
-        use crate::ptr;
-
-        enum SecRandom {}
-
-        #[allow(non_upper_case_globals)]
-        const kSecRandomDefault: *const SecRandom = ptr::null();
-
-        extern "C" {
-            fn SecRandomCopyBytes(rnd: *const SecRandom, count: size_t, bytes: *mut u8) -> c_int;
-        }
-
-        let ret = unsafe { SecRandomCopyBytes(kSecRandomDefault, v.len(), v.as_mut_ptr()) };
-        if ret == -1 {
-            panic!("couldn't generate random bytes: {}", io::Error::last_os_error());
-        }
-    }
-
-    // All supported versions of watchOS (>= 5) have support for `getentropy`.
-    #[cfg(target_os = "watchos")]
-    #[cold]
-    fn fallback_fill_bytes(_: &mut [u8]) {
-        unreachable!()
-    }
-
     pub fn fill_bytes(v: &mut [u8]) {
         if getentropy_fill_bytes(v) {
             return;
         }
 
-        // Older macOS versions (< 10.12) don't support `getentropy`. Fallback to
-        // reading from `/dev/urandom` on these systems.
-        //
-        // Older iOS versions (< 10) don't support it either. Fallback to
-        // `SecRandomCopyBytes` on these systems. On watchOS, this is unreachable
-        // because the minimum supported version is 5 while `getentropy` became accessible
-        // in 3.
-        fallback_fill_bytes(v)
+        // for older macos which doesn't support getentropy
+        let mut file = File::open("/dev/urandom").expect("failed to open /dev/urandom");
+        file.read_exact(v).expect("failed to read /dev/urandom")
     }
 }
 
@@ -237,6 +189,36 @@ mod imp {
     }
 }
 
+// On iOS and MacOS `SecRandomCopyBytes` calls `CCRandomCopyBytes` with
+// `kCCRandomDefault`. `CCRandomCopyBytes` manages a CSPRNG which is seeded
+// from `/dev/random` and which runs on its own thread accessed via GCD.
+// This seems needlessly heavyweight for the purposes of generating two u64s
+// once per thread in `hashmap_random_keys`. Therefore `SecRandomCopyBytes` is
+// only used on iOS where direct access to `/dev/urandom` is blocked by the
+// sandbox.
+#[cfg(any(target_os = "ios", target_os = "watchos"))]
+mod imp {
+    use crate::io;
+    use crate::ptr;
+    use libc::{c_int, size_t};
+
+    enum SecRandom {}
+
+    #[allow(non_upper_case_globals)]
+    const kSecRandomDefault: *const SecRandom = ptr::null();
+
+    extern "C" {
+        fn SecRandomCopyBytes(rnd: *const SecRandom, count: size_t, bytes: *mut u8) -> c_int;
+    }
+
+    pub fn fill_bytes(v: &mut [u8]) {
+        let ret = unsafe { SecRandomCopyBytes(kSecRandomDefault, v.len(), v.as_mut_ptr()) };
+        if ret == -1 {
+            panic!("couldn't generate random bytes: {}", io::Error::last_os_error());
+        }
+    }
+}
+
 #[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
 mod imp {
     use crate::ptr;
diff --git a/library/std/src/sys/unix/stdio.rs b/library/std/src/sys/unix/stdio.rs
index 329f9433dba..b3626c564e8 100644
--- a/library/std/src/sys/unix/stdio.rs
+++ b/library/std/src/sys/unix/stdio.rs
@@ -1,6 +1,6 @@
 use crate::io::{self, IoSlice, IoSliceMut};
 use crate::mem::ManuallyDrop;
-use crate::os::unix::io::{AsFd, BorrowedFd, FromRawFd};
+use crate::os::unix::io::FromRawFd;
 use crate::sys::fd::FileDesc;
 
 pub struct Stdin(());
@@ -91,51 +91,3 @@ pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
 pub fn panic_output() -> Option<impl io::Write> {
     Some(Stderr::new())
 }
-
-#[stable(feature = "io_safety", since = "1.63.0")]
-impl AsFd for io::Stdin {
-    #[inline]
-    fn as_fd(&self) -> BorrowedFd<'_> {
-        unsafe { BorrowedFd::borrow_raw(libc::STDIN_FILENO) }
-    }
-}
-
-#[stable(feature = "io_safety", since = "1.63.0")]
-impl<'a> AsFd for io::StdinLock<'a> {
-    #[inline]
-    fn as_fd(&self) -> BorrowedFd<'_> {
-        unsafe { BorrowedFd::borrow_raw(libc::STDIN_FILENO) }
-    }
-}
-
-#[stable(feature = "io_safety", since = "1.63.0")]
-impl AsFd for io::Stdout {
-    #[inline]
-    fn as_fd(&self) -> BorrowedFd<'_> {
-        unsafe { BorrowedFd::borrow_raw(libc::STDOUT_FILENO) }
-    }
-}
-
-#[stable(feature = "io_safety", since = "1.63.0")]
-impl<'a> AsFd for io::StdoutLock<'a> {
-    #[inline]
-    fn as_fd(&self) -> BorrowedFd<'_> {
-        unsafe { BorrowedFd::borrow_raw(libc::STDOUT_FILENO) }
-    }
-}
-
-#[stable(feature = "io_safety", since = "1.63.0")]
-impl AsFd for io::Stderr {
-    #[inline]
-    fn as_fd(&self) -> BorrowedFd<'_> {
-        unsafe { BorrowedFd::borrow_raw(libc::STDERR_FILENO) }
-    }
-}
-
-#[stable(feature = "io_safety", since = "1.63.0")]
-impl<'a> AsFd for io::StderrLock<'a> {
-    #[inline]
-    fn as_fd(&self) -> BorrowedFd<'_> {
-        unsafe { BorrowedFd::borrow_raw(libc::STDERR_FILENO) }
-    }
-}
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 56bb71b5dcb..42ac6fcd8bf 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -154,9 +154,8 @@ impl Thread {
 
     #[cfg(target_os = "netbsd")]
     pub fn set_name(name: &CStr) {
-        use crate::ffi::CString;
-        let cname = CString::new(&b"%s"[..]).unwrap();
         unsafe {
+            let cname = CStr::from_bytes_with_nul_unchecked(b"%s\0".as_slice());
             libc::pthread_setname_np(
                 libc::pthread_self(),
                 cname.as_ptr(),
@@ -767,6 +766,16 @@ pub mod guard {
             const GUARD_PAGES: usize = 1;
             let guard = guardaddr..guardaddr + GUARD_PAGES * page_size;
             Some(guard)
+        } else if cfg!(target_os = "openbsd") {
+            // OpenBSD stack already includes a guard page, and stack is
+            // immutable.
+            //
+            // We'll just note where we expect rlimit to start
+            // faulting, so our handler can report "stack overflow", and
+            // trust that the kernel's own stack guard will work.
+            let stackptr = get_stack_start_aligned()?;
+            let stackaddr = stackptr.addr();
+            Some(stackaddr - page_size..stackaddr)
         } else {
             // Reallocate the last page of the stack.
             // This ensures SIGBUS will be raised on
diff --git a/library/std/src/sys/unix/thread_local_dtor.rs b/library/std/src/sys/unix/thread_local_dtor.rs
index 6e8be2a91de..d7fd2130f7c 100644
--- a/library/std/src/sys/unix/thread_local_dtor.rs
+++ b/library/std/src/sys/unix/thread_local_dtor.rs
@@ -17,6 +17,7 @@
     target_os = "redox",
     target_os = "emscripten"
 ))]
+#[cfg_attr(target_family = "wasm", allow(unused))] // might remain unused depending on target details (e.g. wasm32-unknown-emscripten)
 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
     use crate::mem;
     use crate::sys_common::thread_local_dtor::register_dtor_fallback;
diff --git a/library/std/src/sys/unix/thread_local_key.rs b/library/std/src/sys/unix/thread_local_key.rs
index 2c5b94b1e61..2b2d079ee4d 100644
--- a/library/std/src/sys/unix/thread_local_key.rs
+++ b/library/std/src/sys/unix/thread_local_key.rs
@@ -27,8 +27,3 @@ pub unsafe fn destroy(key: Key) {
     let r = libc::pthread_key_delete(key);
     debug_assert_eq!(r, 0);
 }
-
-#[inline]
-pub fn requires_synchronized_create() -> bool {
-    false
-}
diff --git a/library/std/src/sys/unix/thread_parker/darwin.rs b/library/std/src/sys/unix/thread_parker/darwin.rs
new file mode 100644
index 00000000000..2f5356fe227
--- /dev/null
+++ b/library/std/src/sys/unix/thread_parker/darwin.rs
@@ -0,0 +1,131 @@
+//! Thread parking for Darwin-based systems.
+//!
+//! Darwin actually has futex syscalls (`__ulock_wait`/`__ulock_wake`), but they
+//! cannot be used in `std` because they are non-public (their use will lead to
+//! rejection from the App Store) and because they are only available starting
+//! with macOS version 10.12, even though the minimum target version is 10.7.
+//!
+//! Therefore, we need to look for other synchronization primitives. Luckily, Darwin
+//! supports semaphores, which allow us to implement the behaviour we need with
+//! only one primitive (as opposed to a mutex-condvar pair). We use the semaphore
+//! provided by libdispatch, as the underlying Mach semaphore is only dubiously
+//! public.
+
+use crate::pin::Pin;
+use crate::sync::atomic::{
+    AtomicI8,
+    Ordering::{Acquire, Release},
+};
+use crate::time::Duration;
+
+type dispatch_semaphore_t = *mut crate::ffi::c_void;
+type dispatch_time_t = u64;
+
+const DISPATCH_TIME_NOW: dispatch_time_t = 0;
+const DISPATCH_TIME_FOREVER: dispatch_time_t = !0;
+
+// Contained in libSystem.dylib, which is linked by default.
+extern "C" {
+    fn dispatch_time(when: dispatch_time_t, delta: i64) -> dispatch_time_t;
+    fn dispatch_semaphore_create(val: isize) -> dispatch_semaphore_t;
+    fn dispatch_semaphore_wait(dsema: dispatch_semaphore_t, timeout: dispatch_time_t) -> isize;
+    fn dispatch_semaphore_signal(dsema: dispatch_semaphore_t) -> isize;
+    fn dispatch_release(object: *mut crate::ffi::c_void);
+}
+
+const EMPTY: i8 = 0;
+const NOTIFIED: i8 = 1;
+const PARKED: i8 = -1;
+
+pub struct Parker {
+    semaphore: dispatch_semaphore_t,
+    state: AtomicI8,
+}
+
+unsafe impl Sync for Parker {}
+unsafe impl Send for Parker {}
+
+impl Parker {
+    pub unsafe fn new(parker: *mut Parker) {
+        let semaphore = dispatch_semaphore_create(0);
+        assert!(
+            !semaphore.is_null(),
+            "failed to create dispatch semaphore for thread synchronization"
+        );
+        parker.write(Parker { semaphore, state: AtomicI8::new(EMPTY) })
+    }
+
+    // Does not need `Pin`, but other implementation do.
+    pub unsafe fn park(self: Pin<&Self>) {
+        // The semaphore counter must be zero at this point, because unparking
+        // threads will not actually increase it until we signalled that we
+        // are waiting.
+
+        // Change NOTIFIED to EMPTY and EMPTY to PARKED.
+        if self.state.fetch_sub(1, Acquire) == NOTIFIED {
+            return;
+        }
+
+        // Another thread may increase the semaphore counter from this point on.
+        // If it is faster than us, we will decrement it again immediately below.
+        // If we are faster, we wait.
+
+        // Ensure that the semaphore counter has actually been decremented, even
+        // if the call timed out for some reason.
+        while dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER) != 0 {}
+
+        // At this point, the semaphore counter is zero again.
+
+        // We were definitely woken up, so we don't need to check the state.
+        // Still, we need to reset the state using a swap to observe the state
+        // change with acquire ordering.
+        self.state.swap(EMPTY, Acquire);
+    }
+
+    // Does not need `Pin`, but other implementation do.
+    pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) {
+        if self.state.fetch_sub(1, Acquire) == NOTIFIED {
+            return;
+        }
+
+        let nanos = dur.as_nanos().try_into().unwrap_or(i64::MAX);
+        let timeout = dispatch_time(DISPATCH_TIME_NOW, nanos);
+
+        let timeout = dispatch_semaphore_wait(self.semaphore, timeout) != 0;
+
+        let state = self.state.swap(EMPTY, Acquire);
+        if state == NOTIFIED && timeout {
+            // If the state was NOTIFIED but semaphore_wait returned without
+            // decrementing the count because of a timeout, it means another
+            // thread is about to call semaphore_signal. We must wait for that
+            // to happen to ensure the semaphore count is reset.
+            while dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER) != 0 {}
+        } else {
+            // Either a timeout occurred and we reset the state before any thread
+            // tried to wake us up, or we were woken up and reset the state,
+            // making sure to observe the state change with acquire ordering.
+            // Either way, the semaphore counter is now zero again.
+        }
+    }
+
+    // Does not need `Pin`, but other implementation do.
+    pub fn unpark(self: Pin<&Self>) {
+        let state = self.state.swap(NOTIFIED, Release);
+        if state == PARKED {
+            unsafe {
+                dispatch_semaphore_signal(self.semaphore);
+            }
+        }
+    }
+}
+
+impl Drop for Parker {
+    fn drop(&mut self) {
+        // SAFETY:
+        // We always ensure that the semaphore count is reset, so this will
+        // never cause an exception.
+        unsafe {
+            dispatch_release(self.semaphore);
+        }
+    }
+}
diff --git a/library/std/src/sys/unix/thread_parker/mod.rs b/library/std/src/sys/unix/thread_parker/mod.rs
index e2453580dc7..35f1e68a87e 100644
--- a/library/std/src/sys/unix/thread_parker/mod.rs
+++ b/library/std/src/sys/unix/thread_parker/mod.rs
@@ -11,7 +11,18 @@
 )))]
 
 cfg_if::cfg_if! {
-    if #[cfg(target_os = "netbsd")] {
+    if #[cfg(all(
+        any(
+            target_os = "macos",
+            target_os = "ios",
+            target_os = "watchos",
+            target_os = "tvos",
+        ),
+        not(miri),
+    ))] {
+        mod darwin;
+        pub use darwin::Parker;
+    } else if #[cfg(target_os = "netbsd")] {
         mod netbsd;
         pub use netbsd::Parker;
     } else {
diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs
index dff973f59d1..cca9c676701 100644
--- a/library/std/src/sys/unix/time.rs
+++ b/library/std/src/sys/unix/time.rs
@@ -7,6 +7,12 @@ const NSEC_PER_SEC: u64 = 1_000_000_000;
 pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(transparent)]
+#[rustc_layout_scalar_valid_range_start(0)]
+#[rustc_layout_scalar_valid_range_end(999_999_999)]
+struct Nanoseconds(u32);
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct SystemTime {
     pub(in crate::sys::unix) t: Timespec,
 }
@@ -14,7 +20,7 @@ pub struct SystemTime {
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub(in crate::sys::unix) struct Timespec {
     tv_sec: i64,
-    tv_nsec: i64,
+    tv_nsec: Nanoseconds,
 }
 
 impl SystemTime {
@@ -46,18 +52,20 @@ impl fmt::Debug for SystemTime {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("SystemTime")
             .field("tv_sec", &self.t.tv_sec)
-            .field("tv_nsec", &self.t.tv_nsec)
+            .field("tv_nsec", &self.t.tv_nsec.0)
             .finish()
     }
 }
 
 impl Timespec {
     pub const fn zero() -> Timespec {
-        Timespec { tv_sec: 0, tv_nsec: 0 }
+        Timespec::new(0, 0)
     }
 
-    fn new(tv_sec: i64, tv_nsec: i64) -> Timespec {
-        Timespec { tv_sec, tv_nsec }
+    const fn new(tv_sec: i64, tv_nsec: i64) -> Timespec {
+        assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64);
+        // SAFETY: The assert above checks tv_nsec is within the valid range
+        Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds(tv_nsec as u32) } }
     }
 
     pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
@@ -75,12 +83,12 @@ impl Timespec {
             //
             // Ideally this code could be rearranged such that it more
             // directly expresses the lower-cost behavior we want from it.
-            let (secs, nsec) = if self.tv_nsec >= other.tv_nsec {
-                ((self.tv_sec - other.tv_sec) as u64, (self.tv_nsec - other.tv_nsec) as u32)
+            let (secs, nsec) = if self.tv_nsec.0 >= other.tv_nsec.0 {
+                ((self.tv_sec - other.tv_sec) as u64, self.tv_nsec.0 - other.tv_nsec.0)
             } else {
                 (
                     (self.tv_sec - other.tv_sec - 1) as u64,
-                    self.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.tv_nsec as u32,
+                    self.tv_nsec.0 + (NSEC_PER_SEC as u32) - other.tv_nsec.0,
                 )
             };
 
@@ -102,7 +110,7 @@ impl Timespec {
 
         // Nano calculations can't overflow because nanos are <1B which fit
         // in a u32.
-        let mut nsec = other.subsec_nanos() + self.tv_nsec as u32;
+        let mut nsec = other.subsec_nanos() + self.tv_nsec.0;
         if nsec >= NSEC_PER_SEC as u32 {
             nsec -= NSEC_PER_SEC as u32;
             secs = secs.checked_add(1)?;
@@ -118,7 +126,7 @@ impl Timespec {
             .and_then(|secs| self.tv_sec.checked_sub(secs))?;
 
         // Similar to above, nanos can't overflow.
-        let mut nsec = self.tv_nsec as i32 - other.subsec_nanos() as i32;
+        let mut nsec = self.tv_nsec.0 as i32 - other.subsec_nanos() as i32;
         if nsec < 0 {
             nsec += NSEC_PER_SEC as i32;
             secs = secs.checked_sub(1)?;
@@ -130,7 +138,7 @@ impl Timespec {
     pub fn to_timespec(&self) -> Option<libc::timespec> {
         Some(libc::timespec {
             tv_sec: self.tv_sec.try_into().ok()?,
-            tv_nsec: self.tv_nsec.try_into().ok()?,
+            tv_nsec: self.tv_nsec.0.try_into().ok()?,
         })
     }
 }
@@ -293,7 +301,7 @@ mod inner {
         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             f.debug_struct("Instant")
                 .field("tv_sec", &self.t.tv_sec)
-                .field("tv_nsec", &self.t.tv_nsec)
+                .field("tv_nsec", &self.t.tv_nsec.0)
                 .finish()
         }
     }
@@ -334,7 +342,7 @@ mod inner {
                     let mut t = MaybeUninit::uninit();
                     cvt(unsafe { clock_gettime64(clock, t.as_mut_ptr()) }).unwrap();
                     let t = unsafe { t.assume_init() };
-                    return Timespec { tv_sec: t.tv_sec, tv_nsec: t.tv_nsec as i64 };
+                    return Timespec::new(t.tv_sec, t.tv_nsec as i64);
                 }
             }
 
diff --git a/library/std/src/sys/unsupported/io.rs b/library/std/src/sys/unsupported/io.rs
index d5f475b4310..82610ffab7e 100644
--- a/library/std/src/sys/unsupported/io.rs
+++ b/library/std/src/sys/unsupported/io.rs
@@ -45,3 +45,7 @@ impl<'a> IoSliceMut<'a> {
         self.0
     }
 }
+
+pub fn is_terminal<T>(_: &T) -> bool {
+    false
+}
diff --git a/library/std/src/sys/unsupported/locks/condvar.rs b/library/std/src/sys/unsupported/locks/condvar.rs
index e703fd0d269..527a26a12bc 100644
--- a/library/std/src/sys/unsupported/locks/condvar.rs
+++ b/library/std/src/sys/unsupported/locks/condvar.rs
@@ -7,6 +7,7 @@ pub type MovableCondvar = Condvar;
 
 impl Condvar {
     #[inline]
+    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
     pub const fn new() -> Condvar {
         Condvar {}
     }
diff --git a/library/std/src/sys/unsupported/locks/mutex.rs b/library/std/src/sys/unsupported/locks/mutex.rs
index 2be0b34b985..87ea475c6e3 100644
--- a/library/std/src/sys/unsupported/locks/mutex.rs
+++ b/library/std/src/sys/unsupported/locks/mutex.rs
@@ -12,6 +12,7 @@ unsafe impl Sync for Mutex {} // no threads on this platform
 
 impl Mutex {
     #[inline]
+    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
     pub const fn new() -> Mutex {
         Mutex { locked: Cell::new(false) }
     }
diff --git a/library/std/src/sys/unsupported/locks/rwlock.rs b/library/std/src/sys/unsupported/locks/rwlock.rs
index aca5fb7152c..5292691b955 100644
--- a/library/std/src/sys/unsupported/locks/rwlock.rs
+++ b/library/std/src/sys/unsupported/locks/rwlock.rs
@@ -12,6 +12,7 @@ unsafe impl Sync for RwLock {} // no threads on this platform
 
 impl RwLock {
     #[inline]
+    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
     pub const fn new() -> RwLock {
         RwLock { mode: Cell::new(0) }
     }
diff --git a/library/std/src/sys/unsupported/thread_local_dtor.rs b/library/std/src/sys/unsupported/thread_local_dtor.rs
index 85d66098302..84660ea5881 100644
--- a/library/std/src/sys/unsupported/thread_local_dtor.rs
+++ b/library/std/src/sys/unsupported/thread_local_dtor.rs
@@ -1,5 +1,6 @@
 #![unstable(feature = "thread_local_internals", issue = "none")]
 
+#[cfg_attr(target_family = "wasm", allow(unused))] // unused on wasm32-unknown-unknown
 pub unsafe fn register_dtor(_t: *mut u8, _dtor: unsafe extern "C" fn(*mut u8)) {
     // FIXME: right now there is no concept of "thread exit", but this is likely
     // going to show up at some point in the form of an exported symbol that the
diff --git a/library/std/src/sys/unsupported/thread_local_key.rs b/library/std/src/sys/unsupported/thread_local_key.rs
index c31b61cbf56..b6e5e4cd2e1 100644
--- a/library/std/src/sys/unsupported/thread_local_key.rs
+++ b/library/std/src/sys/unsupported/thread_local_key.rs
@@ -19,8 +19,3 @@ pub unsafe fn get(_key: Key) -> *mut u8 {
 pub unsafe fn destroy(_key: Key) {
     panic!("should not be used on this target");
 }
-
-#[inline]
-pub fn requires_synchronized_create() -> bool {
-    panic!("should not be used on this target");
-}
diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs
index 510cf36b1bf..d4866bbc32b 100644
--- a/library/std/src/sys/wasi/fs.rs
+++ b/library/std/src/sys/wasi/fs.rs
@@ -1,7 +1,7 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 
 use super::fd::WasiFd;
-use crate::ffi::{CStr, CString, OsStr, OsString};
+use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
 use crate::iter;
@@ -12,6 +12,7 @@ use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd
 use crate::path::{Path, PathBuf};
 use crate::ptr;
 use crate::sync::Arc;
+use crate::sys::common::small_c_string::run_path_with_cstr;
 use crate::sys::time::SystemTime;
 use crate::sys::unsupported;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
@@ -65,8 +66,8 @@ pub struct FilePermissions {
 
 #[derive(Copy, Clone, Debug, Default)]
 pub struct FileTimes {
-    accessed: Option<wasi::Timestamp>,
-    modified: Option<wasi::Timestamp>,
+    accessed: Option<SystemTime>,
+    modified: Option<SystemTime>,
 }
 
 #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
@@ -120,11 +121,11 @@ impl FilePermissions {
 
 impl FileTimes {
     pub fn set_accessed(&mut self, t: SystemTime) {
-        self.accessed = Some(t.to_wasi_timestamp_or_panic());
+        self.accessed = Some(t);
     }
 
     pub fn set_modified(&mut self, t: SystemTime) {
-        self.modified = Some(t.to_wasi_timestamp_or_panic());
+        self.modified = Some(t);
     }
 }
 
@@ -476,9 +477,16 @@ impl File {
     }
 
     pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
+        let to_timestamp = |time: Option<SystemTime>| {
+            match time {
+                Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts),
+                Some(_) => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time")),
+                None => Ok(0),
+            }
+        };
         self.fd.filestat_set_times(
-            times.accessed.unwrap_or(0),
-            times.modified.unwrap_or(0),
+            to_timestamp(times.accessed)?,
+            to_timestamp(times.modified)?,
             times.accessed.map_or(0, |_| wasi::FSTFLAGS_ATIM)
                 | times.modified.map_or(0, |_| wasi::FSTFLAGS_MTIM),
         )
@@ -687,51 +695,52 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> {
 /// Note that this can fail if `p` doesn't look like it can be opened relative
 /// to any pre-opened file descriptor.
 fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
-    let p = CString::new(p.as_os_str().as_bytes())?;
-    let mut buf = Vec::<u8>::with_capacity(512);
-    loop {
-        unsafe {
-            let mut relative_path = buf.as_ptr().cast();
-            let mut abs_prefix = ptr::null();
-            let fd = __wasilibc_find_relpath(
-                p.as_ptr(),
-                &mut abs_prefix,
-                &mut relative_path,
-                buf.capacity(),
-            );
-            if fd == -1 {
-                if io::Error::last_os_error().raw_os_error() == Some(libc::ENOMEM) {
-                    // Trigger the internal buffer resizing logic of `Vec` by requiring
-                    // more space than the current capacity.
-                    let cap = buf.capacity();
-                    buf.set_len(cap);
-                    buf.reserve(1);
-                    continue;
-                }
-                let msg = format!(
-                    "failed to find a pre-opened file descriptor \
-                     through which {:?} could be opened",
-                    p
+    run_path_with_cstr(p, |p| {
+        let mut buf = Vec::<u8>::with_capacity(512);
+        loop {
+            unsafe {
+                let mut relative_path = buf.as_ptr().cast();
+                let mut abs_prefix = ptr::null();
+                let fd = __wasilibc_find_relpath(
+                    p.as_ptr(),
+                    &mut abs_prefix,
+                    &mut relative_path,
+                    buf.capacity(),
                 );
-                return Err(io::Error::new(io::ErrorKind::Uncategorized, msg));
-            }
-            let relative = CStr::from_ptr(relative_path).to_bytes().to_vec();
+                if fd == -1 {
+                    if io::Error::last_os_error().raw_os_error() == Some(libc::ENOMEM) {
+                        // Trigger the internal buffer resizing logic of `Vec` by requiring
+                        // more space than the current capacity.
+                        let cap = buf.capacity();
+                        buf.set_len(cap);
+                        buf.reserve(1);
+                        continue;
+                    }
+                    let msg = format!(
+                        "failed to find a pre-opened file descriptor \
+                     through which {:?} could be opened",
+                        p
+                    );
+                    return Err(io::Error::new(io::ErrorKind::Uncategorized, msg));
+                }
+                let relative = CStr::from_ptr(relative_path).to_bytes().to_vec();
 
-            return Ok((
-                ManuallyDrop::new(WasiFd::from_raw_fd(fd as c_int)),
-                PathBuf::from(OsString::from_vec(relative)),
-            ));
+                return Ok((
+                    ManuallyDrop::new(WasiFd::from_raw_fd(fd as c_int)),
+                    PathBuf::from(OsString::from_vec(relative)),
+                ));
+            }
         }
-    }
 
-    extern "C" {
-        pub fn __wasilibc_find_relpath(
-            path: *const libc::c_char,
-            abs_prefix: *mut *const libc::c_char,
-            relative_path: *mut *const libc::c_char,
-            relative_path_len: libc::size_t,
-        ) -> libc::c_int;
-    }
+        extern "C" {
+            pub fn __wasilibc_find_relpath(
+                path: *const libc::c_char,
+                abs_prefix: *mut *const libc::c_char,
+                relative_path: *mut *const libc::c_char,
+                relative_path_len: libc::size_t,
+            ) -> libc::c_int;
+        }
+    })
 }
 
 pub fn osstr2str(f: &OsStr) -> io::Result<&str> {
diff --git a/library/std/src/sys/wasi/io.rs b/library/std/src/sys/wasi/io.rs
index ee017d13a4c..2cd45df88fa 100644
--- a/library/std/src/sys/wasi/io.rs
+++ b/library/std/src/sys/wasi/io.rs
@@ -1,6 +1,7 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::marker::PhantomData;
+use crate::os::fd::{AsFd, AsRawFd};
 use crate::slice;
 
 #[derive(Copy, Clone)]
@@ -71,3 +72,8 @@ impl<'a> IoSliceMut<'a> {
         unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.buf_len) }
     }
 }
+
+pub fn is_terminal(fd: &impl AsFd) -> bool {
+    let fd = fd.as_fd();
+    unsafe { libc::isatty(fd.as_raw_fd()) != 0 }
+}
diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs
index 683a07a34dc..c8c47763a34 100644
--- a/library/std/src/sys/wasi/mod.rs
+++ b/library/std/src/sys/wasi/mod.rs
@@ -25,6 +25,9 @@ pub mod cmath;
 pub mod env;
 pub mod fd;
 pub mod fs;
+#[allow(unused)]
+#[path = "../wasm/atomics/futex.rs"]
+pub mod futex;
 pub mod io;
 #[path = "../unsupported/locks/mod.rs"]
 pub mod locks;
diff --git a/library/std/src/sys/wasi/os.rs b/library/std/src/sys/wasi/os.rs
index c5229a18834..f5513e9996d 100644
--- a/library/std/src/sys/wasi/os.rs
+++ b/library/std/src/sys/wasi/os.rs
@@ -1,14 +1,15 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 
-use crate::any::Any;
 use crate::error::Error as StdError;
-use crate::ffi::{CStr, CString, OsStr, OsString};
+use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt;
 use crate::io;
 use crate::marker::PhantomData;
+use crate::ops::Drop;
 use crate::os::wasi::prelude::*;
 use crate::path::{self, PathBuf};
 use crate::str;
+use crate::sys::common::small_c_string::{run_path_with_cstr, run_with_cstr};
 use crate::sys::memchr;
 use crate::sys::unsupported;
 use crate::vec;
@@ -23,10 +24,26 @@ mod libc {
     }
 }
 
-#[cfg(not(target_feature = "atomics"))]
-pub unsafe fn env_lock() -> impl Any {
-    // No need for a lock if we're single-threaded, but this function will need
-    // to get implemented for multi-threaded scenarios
+cfg_if::cfg_if! {
+    if #[cfg(target_feature = "atomics")] {
+        // Access to the environment must be protected by a lock in multi-threaded scenarios.
+        use crate::sync::{PoisonError, RwLock};
+        static ENV_LOCK: RwLock<()> = RwLock::new(());
+        pub fn env_read_lock() -> impl Drop {
+            ENV_LOCK.read().unwrap_or_else(PoisonError::into_inner)
+        }
+        pub fn env_write_lock() -> impl Drop {
+            ENV_LOCK.write().unwrap_or_else(PoisonError::into_inner)
+        }
+    } else {
+        // No need for a lock if we are single-threaded.
+        pub fn env_read_lock() -> impl Drop {
+            Box::new(())
+        }
+        pub fn env_write_lock() -> impl Drop {
+            Box::new(())
+        }
+    }
 }
 
 pub fn errno() -> i32 {
@@ -77,13 +94,10 @@ pub fn getcwd() -> io::Result<PathBuf> {
 }
 
 pub fn chdir(p: &path::Path) -> io::Result<()> {
-    let p: &OsStr = p.as_ref();
-    let p = CString::new(p.as_bytes())?;
-    unsafe {
-        match libc::chdir(p.as_ptr()) == (0 as libc::c_int) {
-            true => Ok(()),
-            false => Err(io::Error::last_os_error()),
-        }
+    let result = run_path_with_cstr(p, |p| unsafe { Ok(libc::chdir(p.as_ptr())) })?;
+    match result == (0 as libc::c_int) {
+        true => Ok(()),
+        false => Err(io::Error::last_os_error()),
     }
 }
 
@@ -146,7 +160,7 @@ impl Iterator for Env {
 
 pub fn env() -> Env {
     unsafe {
-        let _guard = env_lock();
+        let _guard = env_read_lock();
         let mut environ = libc::environ;
         let mut result = Vec::new();
         if !environ.is_null() {
@@ -176,35 +190,32 @@ pub fn env() -> Env {
 }
 
 pub fn getenv(k: &OsStr) -> Option<OsString> {
-    let k = CString::new(k.as_bytes()).ok()?;
-    unsafe {
-        let _guard = env_lock();
-        let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
-        if s.is_null() {
-            None
-        } else {
-            Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
-        }
+    let s = run_with_cstr(k.as_bytes(), |k| unsafe {
+        let _guard = env_read_lock();
+        Ok(libc::getenv(k.as_ptr()) as *const libc::c_char)
+    })
+    .ok()?;
+    if s.is_null() {
+        None
+    } else {
+        Some(OsStringExt::from_vec(unsafe { CStr::from_ptr(s) }.to_bytes().to_vec()))
     }
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
-    let k = CString::new(k.as_bytes())?;
-    let v = CString::new(v.as_bytes())?;
-
-    unsafe {
-        let _guard = env_lock();
-        cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop)
-    }
+    run_with_cstr(k.as_bytes(), |k| {
+        run_with_cstr(v.as_bytes(), |v| unsafe {
+            let _guard = env_write_lock();
+            cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop)
+        })
+    })
 }
 
 pub fn unsetenv(n: &OsStr) -> io::Result<()> {
-    let nbuf = CString::new(n.as_bytes())?;
-
-    unsafe {
-        let _guard = env_lock();
+    run_with_cstr(n.as_bytes(), |nbuf| unsafe {
+        let _guard = env_write_lock();
         cvt(libc::unsetenv(nbuf.as_ptr())).map(drop)
-    }
+    })
 }
 
 pub fn temp_dir() -> PathBuf {
diff --git a/library/std/src/sys/wasi/stdio.rs b/library/std/src/sys/wasi/stdio.rs
index d2081771b6e..4cc0e4ed5a4 100644
--- a/library/std/src/sys/wasi/stdio.rs
+++ b/library/std/src/sys/wasi/stdio.rs
@@ -4,7 +4,7 @@ use super::fd::WasiFd;
 use crate::io::{self, IoSlice, IoSliceMut};
 use crate::mem::ManuallyDrop;
 use crate::os::raw;
-use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd};
+use crate::os::wasi::io::{AsRawFd, FromRawFd};
 
 pub struct Stdin;
 pub struct Stdout;
@@ -23,13 +23,6 @@ impl AsRawFd for Stdin {
     }
 }
 
-impl AsFd for Stdin {
-    #[inline]
-    fn as_fd(&self) -> BorrowedFd<'_> {
-        unsafe { BorrowedFd::borrow_raw(0) }
-    }
-}
-
 impl io::Read for Stdin {
     fn read(&mut self, data: &mut [u8]) -> io::Result<usize> {
         self.read_vectored(&mut [IoSliceMut::new(data)])
@@ -58,13 +51,6 @@ impl AsRawFd for Stdout {
     }
 }
 
-impl AsFd for Stdout {
-    #[inline]
-    fn as_fd(&self) -> BorrowedFd<'_> {
-        unsafe { BorrowedFd::borrow_raw(1) }
-    }
-}
-
 impl io::Write for Stdout {
     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         self.write_vectored(&[IoSlice::new(data)])
@@ -96,13 +82,6 @@ impl AsRawFd for Stderr {
     }
 }
 
-impl AsFd for Stderr {
-    #[inline]
-    fn as_fd(&self) -> BorrowedFd<'_> {
-        unsafe { BorrowedFd::borrow_raw(2) }
-    }
-}
-
 impl io::Write for Stderr {
     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         self.write_vectored(&[IoSlice::new(data)])
diff --git a/library/std/src/sys/wasi/time.rs b/library/std/src/sys/wasi/time.rs
index 3d326e49106..016b06efbdc 100644
--- a/library/std/src/sys/wasi/time.rs
+++ b/library/std/src/sys/wasi/time.rs
@@ -47,8 +47,8 @@ impl SystemTime {
         SystemTime(Duration::from_nanos(ts))
     }
 
-    pub fn to_wasi_timestamp_or_panic(&self) -> wasi::Timestamp {
-        self.0.as_nanos().try_into().expect("time does not fit in WASI timestamp")
+    pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
+        self.0.as_nanos().try_into().ok()
     }
 
     pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index 89d0ab59be8..917fc8e4995 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -71,6 +71,7 @@ pub type BCRYPT_ALG_HANDLE = LPVOID;
 pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE;
 pub type PLARGE_INTEGER = *mut c_longlong;
 pub type PSRWLOCK = *mut SRWLOCK;
+pub type LPINIT_ONCE = *mut INIT_ONCE;
 
 pub type SOCKET = crate::os::windows::raw::SOCKET;
 pub type socklen_t = c_int;
@@ -126,6 +127,8 @@ pub const SECURITY_SQOS_PRESENT: DWORD = 0x00100000;
 
 pub const FIONBIO: c_ulong = 0x8004667e;
 
+pub const MAX_PATH: usize = 260;
+
 #[repr(C)]
 #[derive(Copy)]
 pub struct WIN32_FIND_DATAW {
@@ -194,6 +197,9 @@ pub const DUPLICATE_SAME_ACCESS: DWORD = 0x00000002;
 
 pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { ptr: ptr::null_mut() };
 pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: ptr::null_mut() };
+pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { ptr: ptr::null_mut() };
+
+pub const INIT_ONCE_INIT_FAILED: DWORD = 0x00000004;
 
 pub const DETACHED_PROCESS: DWORD = 0x00000008;
 pub const CREATE_NEW_PROCESS_GROUP: DWORD = 0x00000200;
@@ -279,7 +285,6 @@ pub const STATUS_INVALID_PARAMETER: NTSTATUS = 0xc000000d_u32 as _;
 pub const STATUS_PENDING: NTSTATUS = 0x103 as _;
 pub const STATUS_END_OF_FILE: NTSTATUS = 0xC0000011_u32 as _;
 pub const STATUS_NOT_IMPLEMENTED: NTSTATUS = 0xC0000002_u32 as _;
-pub const STATUS_NOT_SUPPORTED: NTSTATUS = 0xC00000BB_u32 as _;
 
 // Equivalent to the `NT_SUCCESS` C preprocessor macro.
 // See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
@@ -289,6 +294,7 @@ pub fn nt_success(status: NTSTATUS) -> bool {
 
 // "RNG\0"
 pub const BCRYPT_RNG_ALGORITHM: &[u16] = &[b'R' as u16, b'N' as u16, b'G' as u16, 0];
+pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;
 
 #[repr(C)]
 pub struct UNICODE_STRING {
@@ -535,6 +541,12 @@ pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
 /// NB: Use carefully! In general using this as a reference is likely to get the
 /// provenance wrong for the `PathBuffer` field!
 #[repr(C)]
+pub struct FILE_NAME_INFO {
+    pub FileNameLength: DWORD,
+    pub FileName: [WCHAR; 1],
+}
+
+#[repr(C)]
 pub struct MOUNT_POINT_REPARSE_BUFFER {
     pub SubstituteNameOffset: c_ushort,
     pub SubstituteNameLength: c_ushort,
@@ -565,6 +577,10 @@ pub struct CONDITION_VARIABLE {
 pub struct SRWLOCK {
     pub ptr: LPVOID,
 }
+#[repr(C)]
+pub struct INIT_ONCE {
+    pub ptr: LPVOID,
+}
 
 #[repr(C)]
 pub struct REPARSE_MOUNTPOINT_DATA_BUFFER {
@@ -817,10 +833,6 @@ if #[cfg(not(target_vendor = "uwp"))] {
 
     #[link(name = "advapi32")]
     extern "system" {
-        // Forbidden when targeting UWP
-        #[link_name = "SystemFunction036"]
-        pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN;
-
         // Allowed but unused by UWP
         pub fn OpenProcessToken(
             ProcessHandle: HANDLE,
@@ -959,6 +971,7 @@ extern "system" {
     pub fn TlsAlloc() -> DWORD;
     pub fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
     pub fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
+    pub fn TlsFree(dwTlsIndex: DWORD) -> BOOL;
     pub fn GetLastError() -> DWORD;
     pub fn QueryPerformanceFrequency(lpFrequency: *mut LARGE_INTEGER) -> BOOL;
     pub fn QueryPerformanceCounter(lpPerformanceCount: *mut LARGE_INTEGER) -> BOOL;
@@ -1118,6 +1131,14 @@ extern "system" {
     pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN;
     pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN;
 
+    pub fn InitOnceBeginInitialize(
+        lpInitOnce: LPINIT_ONCE,
+        dwFlags: DWORD,
+        fPending: LPBOOL,
+        lpContext: *mut LPVOID,
+    ) -> BOOL;
+    pub fn InitOnceComplete(lpInitOnce: LPINIT_ONCE, dwFlags: DWORD, lpContext: LPVOID) -> BOOL;
+
     pub fn CompareStringOrdinal(
         lpString1: LPCWSTR,
         cchCount1: c_int,
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs
index 155d0297e49..ade00750c95 100644
--- a/library/std/src/sys/windows/fs.rs
+++ b/library/std/src/sys/windows/fs.rs
@@ -572,6 +572,14 @@ impl File {
                 "Cannot set file timestamp to 0",
             ));
         }
+        let is_max =
+            |t: c::FILETIME| t.dwLowDateTime == c::DWORD::MAX && t.dwHighDateTime == c::DWORD::MAX;
+        if times.accessed.map_or(false, is_max) || times.modified.map_or(false, is_max) {
+            return Err(io::const_io_error!(
+                io::ErrorKind::InvalidInput,
+                "Cannot set file timestamp to 0xFFFF_FFFF_FFFF_FFFF",
+            ));
+        }
         cvt(unsafe {
             c::SetFileTime(self.as_handle(), None, times.accessed.as_ref(), times.modified.as_ref())
         })?;
diff --git a/library/std/src/sys/windows/io.rs b/library/std/src/sys/windows/io.rs
index fb06df1f80c..0879ef19933 100644
--- a/library/std/src/sys/windows/io.rs
+++ b/library/std/src/sys/windows/io.rs
@@ -1,6 +1,10 @@
 use crate::marker::PhantomData;
+use crate::mem::size_of;
+use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle};
 use crate::slice;
-use crate::sys::c;
+use crate::sys::{c, Align8};
+use core;
+use libc;
 
 #[derive(Copy, Clone)]
 #[repr(transparent)]
@@ -78,3 +82,66 @@ impl<'a> IoSliceMut<'a> {
         unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.len as usize) }
     }
 }
+
+pub fn is_terminal(h: &impl AsHandle) -> bool {
+    unsafe { handle_is_console(h.as_handle()) }
+}
+
+unsafe fn handle_is_console(handle: BorrowedHandle<'_>) -> bool {
+    let handle = handle.as_raw_handle();
+
+    // A null handle means the process has no console.
+    if handle.is_null() {
+        return false;
+    }
+
+    let mut out = 0;
+    if c::GetConsoleMode(handle, &mut out) != 0 {
+        // False positives aren't possible. If we got a console then we definitely have a console.
+        return true;
+    }
+
+    // At this point, we *could* have a false negative. We can determine that this is a true
+    // negative if we can detect the presence of a console on any of the standard I/O streams. If
+    // another stream has a console, then we know we're in a Windows console and can therefore
+    // trust the negative.
+    for std_handle in [c::STD_INPUT_HANDLE, c::STD_OUTPUT_HANDLE, c::STD_ERROR_HANDLE] {
+        let std_handle = c::GetStdHandle(std_handle);
+        if !std_handle.is_null()
+            && std_handle != handle
+            && c::GetConsoleMode(std_handle, &mut out) != 0
+        {
+            return false;
+        }
+    }
+
+    // Otherwise, we fall back to an msys hack to see if we can detect the presence of a pty.
+    msys_tty_on(handle)
+}
+
+unsafe fn msys_tty_on(handle: c::HANDLE) -> bool {
+    const SIZE: usize = size_of::<c::FILE_NAME_INFO>() + c::MAX_PATH * size_of::<c::WCHAR>();
+    let mut name_info_bytes = Align8([0u8; SIZE]);
+    let res = c::GetFileInformationByHandleEx(
+        handle,
+        c::FileNameInfo,
+        name_info_bytes.0.as_mut_ptr() as *mut libc::c_void,
+        SIZE as u32,
+    );
+    if res == 0 {
+        return false;
+    }
+    let name_info: &c::FILE_NAME_INFO = &*(name_info_bytes.0.as_ptr() as *const c::FILE_NAME_INFO);
+    let name_len = name_info.FileNameLength as usize / 2;
+    // Offset to get the `FileName` field.
+    let name_ptr = name_info_bytes.0.as_ptr().offset(size_of::<c::DWORD>() as isize).cast::<u16>();
+    let s = core::slice::from_raw_parts(name_ptr, name_len);
+    let name = String::from_utf16_lossy(s);
+    // This checks whether 'pty' exists in the file name, which indicates that
+    // a pseudo-terminal is attached. To mitigate against false positives
+    // (e.g., an actual file name that contains 'pty'), we also require that
+    // either the strings 'msys-' or 'cygwin-' are in the file name as well.)
+    let is_msys = name.contains("msys-") || name.contains("cygwin-");
+    let is_pty = name.contains("-pty");
+    is_msys && is_pty
+}
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index 02d5af4719a..9cbb4ef19e9 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -16,6 +16,7 @@ use crate::os::windows::ffi::{OsStrExt, OsStringExt};
 use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle};
 use crate::path::{Path, PathBuf};
 use crate::ptr;
+use crate::sync::Mutex;
 use crate::sys::args::{self, Arg};
 use crate::sys::c;
 use crate::sys::c::NonZeroDWORD;
@@ -25,7 +26,6 @@ use crate::sys::handle::Handle;
 use crate::sys::path;
 use crate::sys::pipe::{self, AnonPipe};
 use crate::sys::stdio;
-use crate::sys_common::mutex::StaticMutex;
 use crate::sys_common::process::{CommandEnv, CommandEnvs};
 use crate::sys_common::IntoInner;
 
@@ -301,9 +301,9 @@ impl Command {
         //
         // For more information, msdn also has an article about this race:
         // https://support.microsoft.com/kb/315939
-        static CREATE_PROCESS_LOCK: StaticMutex = StaticMutex::new();
+        static CREATE_PROCESS_LOCK: Mutex<()> = Mutex::new(());
 
-        let _guard = unsafe { CREATE_PROCESS_LOCK.lock() };
+        let _guard = CREATE_PROCESS_LOCK.lock();
 
         let mut pipes = StdioPipes { stdin: None, stdout: None, stderr: None };
         let null = Stdio::Null;
diff --git a/library/std/src/sys/windows/rand.rs b/library/std/src/sys/windows/rand.rs
index d6cd8f80271..b5a49489d3f 100644
--- a/library/std/src/sys/windows/rand.rs
+++ b/library/std/src/sys/windows/rand.rs
@@ -13,15 +13,12 @@
 //! but significant number of users to experience panics caused by a failure of
 //! this function. See [#94098].
 //!
-//! The current version changes this to use the `BCRYPT_RNG_ALG_HANDLE`
-//! [Pseudo-handle], which gets the default RNG algorithm without querying the
-//! system preference thus hopefully avoiding the previous issue.
-//! This is only supported on Windows 10+ so a fallback is used for older versions.
+//! The current version falls back to using `BCryptOpenAlgorithmProvider` if
+//! `BCRYPT_USE_SYSTEM_PREFERRED_RNG` fails for any reason.
 //!
 //! [#94098]: https://github.com/rust-lang/rust/issues/94098
 //! [`RtlGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom
 //! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
-//! [Pseudo-handle]: https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-pseudo-handles
 use crate::mem;
 use crate::ptr;
 use crate::sys::c;
@@ -33,37 +30,35 @@ use crate::sys::c;
 /// [`HashMap`]: crate::collections::HashMap
 /// [`RandomState`]: crate::collections::hash_map::RandomState
 pub fn hashmap_random_keys() -> (u64, u64) {
-    Rng::open().and_then(|rng| rng.gen_random_keys()).unwrap_or_else(fallback_rng)
+    Rng::SYSTEM.gen_random_keys().unwrap_or_else(fallback_rng)
 }
 
-struct Rng(c::BCRYPT_ALG_HANDLE);
+struct Rng {
+    algorithm: c::BCRYPT_ALG_HANDLE,
+    flags: u32,
+}
 impl Rng {
-    #[cfg(miri)]
-    fn open() -> Result<Self, c::NTSTATUS> {
-        const BCRYPT_RNG_ALG_HANDLE: c::BCRYPT_ALG_HANDLE = ptr::invalid_mut(0x81);
-        let _ = (
-            c::BCryptOpenAlgorithmProvider,
-            c::BCryptCloseAlgorithmProvider,
-            c::BCRYPT_RNG_ALGORITHM,
-            c::STATUS_NOT_SUPPORTED,
-        );
-        Ok(Self(BCRYPT_RNG_ALG_HANDLE))
+    const SYSTEM: Self = unsafe { Self::new(ptr::null_mut(), c::BCRYPT_USE_SYSTEM_PREFERRED_RNG) };
+
+    /// Create the RNG from an existing algorithm handle.
+    ///
+    /// # Safety
+    ///
+    /// The handle must either be null or a valid algorithm handle.
+    const unsafe fn new(algorithm: c::BCRYPT_ALG_HANDLE, flags: u32) -> Self {
+        Self { algorithm, flags }
     }
-    #[cfg(not(miri))]
-    // Open a handle to the RNG algorithm.
+
+    /// Open a handle to the RNG algorithm.
     fn open() -> Result<Self, c::NTSTATUS> {
         use crate::sync::atomic::AtomicPtr;
         use crate::sync::atomic::Ordering::{Acquire, Release};
-        const ERROR_VALUE: c::LPVOID = ptr::invalid_mut(usize::MAX);
 
         // An atomic is used so we don't need to reopen the handle every time.
         static HANDLE: AtomicPtr<crate::ffi::c_void> = AtomicPtr::new(ptr::null_mut());
 
         let mut handle = HANDLE.load(Acquire);
-        // We use a sentinel value to designate an error occurred last time.
-        if handle == ERROR_VALUE {
-            Err(c::STATUS_NOT_SUPPORTED)
-        } else if handle.is_null() {
+        if handle.is_null() {
             let status = unsafe {
                 c::BCryptOpenAlgorithmProvider(
                     &mut handle,
@@ -80,13 +75,12 @@ impl Rng {
                     unsafe { c::BCryptCloseAlgorithmProvider(handle, 0) };
                     handle = previous_handle;
                 }
-                Ok(Self(handle))
+                Ok(unsafe { Self::new(handle, 0) })
             } else {
-                HANDLE.store(ERROR_VALUE, Release);
                 Err(status)
             }
         } else {
-            Ok(Self(handle))
+            Ok(unsafe { Self::new(handle, 0) })
         }
     }
 
@@ -94,33 +88,19 @@ impl Rng {
         let mut v = (0, 0);
         let status = unsafe {
             let size = mem::size_of_val(&v).try_into().unwrap();
-            c::BCryptGenRandom(self.0, ptr::addr_of_mut!(v).cast(), size, 0)
+            c::BCryptGenRandom(self.algorithm, ptr::addr_of_mut!(v).cast(), size, self.flags)
         };
         if c::nt_success(status) { Ok(v) } else { Err(status) }
     }
 }
 
-/// Generate random numbers using the fallback RNG function (RtlGenRandom)
-#[cfg(not(target_vendor = "uwp"))]
+/// Generate random numbers using the fallback RNG function
 #[inline(never)]
 fn fallback_rng(rng_status: c::NTSTATUS) -> (u64, u64) {
-    let mut v = (0, 0);
-    let ret =
-        unsafe { c::RtlGenRandom(&mut v as *mut _ as *mut u8, mem::size_of_val(&v) as c::ULONG) };
-
-    if ret != 0 {
-        v
-    } else {
-        panic!(
-            "RNG broken: {rng_status:#x}, fallback RNG broken: {}",
-            crate::io::Error::last_os_error()
-        )
+    match Rng::open().and_then(|rng| rng.gen_random_keys()) {
+        Ok(keys) => keys,
+        Err(status) => {
+            panic!("RNG broken: {rng_status:#x}, fallback RNG broken: {status:#x}")
+        }
     }
 }
-
-/// We can't use RtlGenRandom with UWP, so there is no fallback
-#[cfg(target_vendor = "uwp")]
-#[inline(never)]
-fn fallback_rng(rng_status: c::NTSTATUS) -> (u64, u64) {
-    panic!("RNG broken: {rng_status:#x} fallback RNG broken: RtlGenRandom() not supported on UWP");
-}
diff --git a/library/std/src/sys/windows/thread_local_key.rs b/library/std/src/sys/windows/thread_local_key.rs
index ec670238e6f..17628b7579b 100644
--- a/library/std/src/sys/windows/thread_local_key.rs
+++ b/library/std/src/sys/windows/thread_local_key.rs
@@ -1,11 +1,16 @@
-use crate::mem::ManuallyDrop;
+use crate::cell::UnsafeCell;
 use crate::ptr;
-use crate::sync::atomic::AtomicPtr;
-use crate::sync::atomic::Ordering::SeqCst;
+use crate::sync::atomic::{
+    AtomicPtr, AtomicU32,
+    Ordering::{AcqRel, Acquire, Relaxed, Release},
+};
 use crate::sys::c;
 
-pub type Key = c::DWORD;
-pub type Dtor = unsafe extern "C" fn(*mut u8);
+#[cfg(test)]
+mod tests;
+
+type Key = c::DWORD;
+type Dtor = unsafe extern "C" fn(*mut u8);
 
 // Turns out, like pretty much everything, Windows is pretty close the
 // functionality that Unix provides, but slightly different! In the case of
@@ -22,60 +27,109 @@ pub type Dtor = unsafe extern "C" fn(*mut u8);
 // To accomplish this feat, we perform a number of threads, all contained
 // within this module:
 //
-// * All TLS destructors are tracked by *us*, not the windows runtime. This
+// * All TLS destructors are tracked by *us*, not the Windows runtime. This
 //   means that we have a global list of destructors for each TLS key that
 //   we know about.
 // * When a thread exits, we run over the entire list and run dtors for all
 //   non-null keys. This attempts to match Unix semantics in this regard.
 //
-// This ends up having the overhead of using a global list, having some
-// locks here and there, and in general just adding some more code bloat. We
-// attempt to optimize runtime by forgetting keys that don't have
-// destructors, but this only gets us so far.
-//
 // For more details and nitty-gritty, see the code sections below!
 //
 // [1]: https://www.codeproject.com/Articles/8113/Thread-Local-Storage-The-C-Way
-// [2]: https://github.com/ChromiumWebApps/chromium/blob/master/base
-//                        /threading/thread_local_storage_win.cc#L42
+// [2]: https://github.com/ChromiumWebApps/chromium/blob/master/base/threading/thread_local_storage_win.cc#L42
 
-// -------------------------------------------------------------------------
-// Native bindings
-//
-// This section is just raw bindings to the native functions that Windows
-// provides, There's a few extra calls to deal with destructors.
+pub struct StaticKey {
+    /// The key value shifted up by one. Since TLS_OUT_OF_INDEXES == DWORD::MAX
+    /// is not a valid key value, this allows us to use zero as sentinel value
+    /// without risking overflow.
+    key: AtomicU32,
+    dtor: Option<Dtor>,
+    next: AtomicPtr<StaticKey>,
+    /// Currently, destructors cannot be unregistered, so we cannot use racy
+    /// initialization for keys. Instead, we need synchronize initialization.
+    /// Use the Windows-provided `Once` since it does not require TLS.
+    once: UnsafeCell<c::INIT_ONCE>,
+}
 
-#[inline]
-pub unsafe fn create(dtor: Option<Dtor>) -> Key {
-    let key = c::TlsAlloc();
-    assert!(key != c::TLS_OUT_OF_INDEXES);
-    if let Some(f) = dtor {
-        register_dtor(key, f);
+impl StaticKey {
+    #[inline]
+    pub const fn new(dtor: Option<Dtor>) -> StaticKey {
+        StaticKey {
+            key: AtomicU32::new(0),
+            dtor,
+            next: AtomicPtr::new(ptr::null_mut()),
+            once: UnsafeCell::new(c::INIT_ONCE_STATIC_INIT),
+        }
     }
-    key
-}
 
-#[inline]
-pub unsafe fn set(key: Key, value: *mut u8) {
-    let r = c::TlsSetValue(key, value as c::LPVOID);
-    debug_assert!(r != 0);
-}
+    #[inline]
+    pub unsafe fn set(&'static self, val: *mut u8) {
+        let r = c::TlsSetValue(self.key(), val.cast());
+        debug_assert_eq!(r, c::TRUE);
+    }
 
-#[inline]
-pub unsafe fn get(key: Key) -> *mut u8 {
-    c::TlsGetValue(key) as *mut u8
-}
+    #[inline]
+    pub unsafe fn get(&'static self) -> *mut u8 {
+        c::TlsGetValue(self.key()).cast()
+    }
 
-#[inline]
-pub unsafe fn destroy(_key: Key) {
-    rtabort!("can't destroy tls keys on windows")
-}
+    #[inline]
+    unsafe fn key(&'static self) -> Key {
+        match self.key.load(Acquire) {
+            0 => self.init(),
+            key => key - 1,
+        }
+    }
+
+    #[cold]
+    unsafe fn init(&'static self) -> Key {
+        if self.dtor.is_some() {
+            let mut pending = c::FALSE;
+            let r = c::InitOnceBeginInitialize(self.once.get(), 0, &mut pending, ptr::null_mut());
+            assert_eq!(r, c::TRUE);
 
-#[inline]
-pub fn requires_synchronized_create() -> bool {
-    true
+            if pending == c::FALSE {
+                // Some other thread initialized the key, load it.
+                self.key.load(Relaxed) - 1
+            } else {
+                let key = c::TlsAlloc();
+                if key == c::TLS_OUT_OF_INDEXES {
+                    // Wakeup the waiting threads before panicking to avoid deadlock.
+                    c::InitOnceComplete(self.once.get(), c::INIT_ONCE_INIT_FAILED, ptr::null_mut());
+                    panic!("out of TLS indexes");
+                }
+
+                self.key.store(key + 1, Release);
+                register_dtor(self);
+
+                let r = c::InitOnceComplete(self.once.get(), 0, ptr::null_mut());
+                debug_assert_eq!(r, c::TRUE);
+
+                key
+            }
+        } else {
+            // If there is no destructor to clean up, we can use racy initialization.
+
+            let key = c::TlsAlloc();
+            assert_ne!(key, c::TLS_OUT_OF_INDEXES, "out of TLS indexes");
+
+            match self.key.compare_exchange(0, key + 1, AcqRel, Acquire) {
+                Ok(_) => key,
+                Err(new) => {
+                    // Some other thread completed initialization first, so destroy
+                    // our key and use theirs.
+                    let r = c::TlsFree(key);
+                    debug_assert_eq!(r, c::TRUE);
+                    new - 1
+                }
+            }
+        }
+    }
 }
 
+unsafe impl Send for StaticKey {}
+unsafe impl Sync for StaticKey {}
+
 // -------------------------------------------------------------------------
 // Dtor registration
 //
@@ -96,29 +150,21 @@ pub fn requires_synchronized_create() -> bool {
 // Typically processes have a statically known set of TLS keys which is pretty
 // small, and we'd want to keep this memory alive for the whole process anyway
 // really.
-//
-// Perhaps one day we can fold the `Box` here into a static allocation,
-// expanding the `StaticKey` structure to contain not only a slot for the TLS
-// key but also a slot for the destructor queue on windows. An optimization for
-// another day!
-
-static DTORS: AtomicPtr<Node> = AtomicPtr::new(ptr::null_mut());
-
-struct Node {
-    dtor: Dtor,
-    key: Key,
-    next: *mut Node,
-}
 
-unsafe fn register_dtor(key: Key, dtor: Dtor) {
-    let mut node = ManuallyDrop::new(Box::new(Node { key, dtor, next: ptr::null_mut() }));
+static DTORS: AtomicPtr<StaticKey> = AtomicPtr::new(ptr::null_mut());
 
-    let mut head = DTORS.load(SeqCst);
+/// Should only be called once per key, otherwise loops or breaks may occur in
+/// the linked list.
+unsafe fn register_dtor(key: &'static StaticKey) {
+    let this = <*const StaticKey>::cast_mut(key);
+    // Use acquire ordering to pass along the changes done by the previously
+    // registered keys when we store the new head with release ordering.
+    let mut head = DTORS.load(Acquire);
     loop {
-        node.next = head;
-        match DTORS.compare_exchange(head, &mut **node, SeqCst, SeqCst) {
-            Ok(_) => return, // nothing to drop, we successfully added the node to the list
-            Err(cur) => head = cur,
+        key.next.store(head, Relaxed);
+        match DTORS.compare_exchange_weak(head, this, Release, Acquire) {
+            Ok(_) => break,
+            Err(new) => head = new,
         }
     }
 }
@@ -214,25 +260,29 @@ unsafe extern "system" fn on_tls_callback(h: c::LPVOID, dwReason: c::DWORD, pv:
     unsafe fn reference_tls_used() {}
 }
 
-#[allow(dead_code)] // actually called above
+#[allow(dead_code)] // actually called below
 unsafe fn run_dtors() {
-    let mut any_run = true;
     for _ in 0..5 {
-        if !any_run {
-            break;
-        }
-        any_run = false;
-        let mut cur = DTORS.load(SeqCst);
+        let mut any_run = false;
+
+        // Use acquire ordering to observe key initialization.
+        let mut cur = DTORS.load(Acquire);
         while !cur.is_null() {
-            let ptr = c::TlsGetValue((*cur).key);
+            let key = (*cur).key.load(Relaxed) - 1;
+            let dtor = (*cur).dtor.unwrap();
 
+            let ptr = c::TlsGetValue(key);
             if !ptr.is_null() {
-                c::TlsSetValue((*cur).key, ptr::null_mut());
-                ((*cur).dtor)(ptr as *mut _);
+                c::TlsSetValue(key, ptr::null_mut());
+                dtor(ptr as *mut _);
                 any_run = true;
             }
 
-            cur = (*cur).next;
+            cur = (*cur).next.load(Relaxed);
+        }
+
+        if !any_run {
+            break;
         }
     }
 }
diff --git a/library/std/src/sys/windows/thread_local_key/tests.rs b/library/std/src/sys/windows/thread_local_key/tests.rs
new file mode 100644
index 00000000000..c95f383fb90
--- /dev/null
+++ b/library/std/src/sys/windows/thread_local_key/tests.rs
@@ -0,0 +1,53 @@
+use super::StaticKey;
+use crate::ptr;
+
+#[test]
+fn smoke() {
+    static K1: StaticKey = StaticKey::new(None);
+    static K2: StaticKey = StaticKey::new(None);
+
+    unsafe {
+        assert!(K1.get().is_null());
+        assert!(K2.get().is_null());
+        K1.set(ptr::invalid_mut(1));
+        K2.set(ptr::invalid_mut(2));
+        assert_eq!(K1.get() as usize, 1);
+        assert_eq!(K2.get() as usize, 2);
+    }
+}
+
+#[test]
+fn destructors() {
+    use crate::mem::ManuallyDrop;
+    use crate::sync::Arc;
+    use crate::thread;
+
+    unsafe extern "C" fn destruct(ptr: *mut u8) {
+        drop(Arc::from_raw(ptr as *const ()));
+    }
+
+    static KEY: StaticKey = StaticKey::new(Some(destruct));
+
+    let shared1 = Arc::new(());
+    let shared2 = Arc::clone(&shared1);
+
+    unsafe {
+        assert!(KEY.get().is_null());
+        KEY.set(Arc::into_raw(shared1) as *mut u8);
+    }
+
+    thread::spawn(move || unsafe {
+        assert!(KEY.get().is_null());
+        KEY.set(Arc::into_raw(shared2) as *mut u8);
+    })
+    .join()
+    .unwrap();
+
+    // Leak the Arc, let the TLS destructor clean it up.
+    let shared1 = unsafe { ManuallyDrop::new(Arc::from_raw(KEY.get() as *const ())) };
+    assert_eq!(
+        Arc::strong_count(&shared1),
+        1,
+        "destructor should have dropped the other reference on thread exit"
+    );
+}
diff --git a/library/std/src/sys_common/backtrace.rs b/library/std/src/sys_common/backtrace.rs
index 31164afdc7b..8807077cb49 100644
--- a/library/std/src/sys_common/backtrace.rs
+++ b/library/std/src/sys_common/backtrace.rs
@@ -7,15 +7,14 @@ use crate::fmt;
 use crate::io;
 use crate::io::prelude::*;
 use crate::path::{self, Path, PathBuf};
-use crate::sys_common::mutex::StaticMutex;
+use crate::sync::{Mutex, PoisonError};
 
 /// Max number of frames to print.
 const MAX_NB_FRAMES: usize = 100;
 
-// SAFETY: Don't attempt to lock this reentrantly.
-pub unsafe fn lock() -> impl Drop {
-    static LOCK: StaticMutex = StaticMutex::new();
-    LOCK.lock()
+pub fn lock() -> impl Drop {
+    static LOCK: Mutex<()> = Mutex::new(());
+    LOCK.lock().unwrap_or_else(PoisonError::into_inner)
 }
 
 /// Prints the current backtrace.
diff --git a/library/std/src/sys_common/condvar.rs b/library/std/src/sys_common/condvar.rs
index f3ac1061b89..8bc5b24115d 100644
--- a/library/std/src/sys_common/condvar.rs
+++ b/library/std/src/sys_common/condvar.rs
@@ -15,6 +15,7 @@ pub struct Condvar {
 impl Condvar {
     /// Creates a new condition variable for use.
     #[inline]
+    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
     pub const fn new() -> Self {
         Self { inner: imp::MovableCondvar::new(), check: CondvarCheck::new() }
     }
diff --git a/library/std/src/sys_common/condvar/check.rs b/library/std/src/sys_common/condvar/check.rs
index ce8f3670487..4ac9e62bf86 100644
--- a/library/std/src/sys_common/condvar/check.rs
+++ b/library/std/src/sys_common/condvar/check.rs
@@ -50,6 +50,7 @@ pub struct NoCheck;
 
 #[allow(dead_code)]
 impl NoCheck {
+    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
     pub const fn new() -> Self {
         Self
     }
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 80f56bf7522..8c19f9332dc 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -27,17 +27,25 @@ pub mod io;
 pub mod lazy_box;
 pub mod memchr;
 pub mod mutex;
+pub mod once;
 pub mod process;
 pub mod remutex;
 pub mod rwlock;
 pub mod thread;
 pub mod thread_info;
 pub mod thread_local_dtor;
-pub mod thread_local_key;
 pub mod thread_parker;
 pub mod wtf8;
 
 cfg_if::cfg_if! {
+    if #[cfg(target_os = "windows")] {
+        pub use crate::sys::thread_local_key;
+    } else {
+        pub mod thread_local_key;
+    }
+}
+
+cfg_if::cfg_if! {
     if #[cfg(any(target_os = "l4re",
                  target_os = "hermit",
                  feature = "restricted-std",
diff --git a/library/std/src/sys_common/mutex.rs b/library/std/src/sys_common/mutex.rs
index 48479f5bdb3..98046f20f89 100644
--- a/library/std/src/sys_common/mutex.rs
+++ b/library/std/src/sys_common/mutex.rs
@@ -1,49 +1,5 @@
 use crate::sys::locks as imp;
 
-/// An OS-based mutual exclusion lock, meant for use in static variables.
-///
-/// This mutex has a const constructor ([`StaticMutex::new`]), does not
-/// implement `Drop` to cleanup resources, and causes UB when used reentrantly.
-///
-/// This mutex does not implement poisoning.
-///
-/// This is a wrapper around `imp::Mutex` that does *not* call `init()` and
-/// `destroy()`.
-pub struct StaticMutex(imp::Mutex);
-
-unsafe impl Sync for StaticMutex {}
-
-impl StaticMutex {
-    /// Creates a new mutex for use.
-    #[inline]
-    pub const fn new() -> Self {
-        Self(imp::Mutex::new())
-    }
-
-    /// Calls raw_lock() and then returns an RAII guard to guarantee the mutex
-    /// will be unlocked.
-    ///
-    /// It is undefined behaviour to call this function while locked by the
-    /// same thread.
-    #[inline]
-    pub unsafe fn lock(&'static self) -> StaticMutexGuard {
-        self.0.lock();
-        StaticMutexGuard(&self.0)
-    }
-}
-
-#[must_use]
-pub struct StaticMutexGuard(&'static imp::Mutex);
-
-impl Drop for StaticMutexGuard {
-    #[inline]
-    fn drop(&mut self) {
-        unsafe {
-            self.0.unlock();
-        }
-    }
-}
-
 /// An OS-based mutual exclusion lock.
 ///
 /// This mutex cleans up its resources in its `Drop` implementation, may safely
@@ -61,6 +17,7 @@ unsafe impl Sync for MovableMutex {}
 impl MovableMutex {
     /// Creates a new mutex.
     #[inline]
+    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
     pub const fn new() -> Self {
         Self(imp::MovableMutex::new())
     }
diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs
index 3ad802afa8f..fad4a63331b 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -2,12 +2,13 @@
 mod tests;
 
 use crate::cmp;
-use crate::ffi::CString;
+use crate::convert::{TryFrom, TryInto};
 use crate::fmt;
 use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
 use crate::mem;
 use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
 use crate::ptr;
+use crate::sys::common::small_c_string::run_with_cstr;
 use crate::sys::net::netc as c;
 use crate::sys::net::{cvt, cvt_gai, cvt_r, init, wrlen_t, Socket};
 use crate::sys_common::{AsInner, FromInner, IntoInner};
@@ -197,14 +198,15 @@ impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
     fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
         init();
 
-        let c_host = CString::new(host)?;
-        let mut hints: c::addrinfo = unsafe { mem::zeroed() };
-        hints.ai_socktype = c::SOCK_STREAM;
-        let mut res = ptr::null_mut();
-        unsafe {
-            cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res))
-                .map(|_| LookupHost { original: res, cur: res, port })
-        }
+        run_with_cstr(host.as_bytes(), |c_host| {
+            let mut hints: c::addrinfo = unsafe { mem::zeroed() };
+            hints.ai_socktype = c::SOCK_STREAM;
+            let mut res = ptr::null_mut();
+            unsafe {
+                cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res))
+                    .map(|_| LookupHost { original: res, cur: res, port })
+            }
+        })
     }
 }
 
diff --git a/library/std/src/sys_common/once/futex.rs b/library/std/src/sys_common/once/futex.rs
new file mode 100644
index 00000000000..5c7e6c01371
--- /dev/null
+++ b/library/std/src/sys_common/once/futex.rs
@@ -0,0 +1,134 @@
+use crate::cell::Cell;
+use crate::sync as public;
+use crate::sync::atomic::{
+    AtomicU32,
+    Ordering::{Acquire, Relaxed, Release},
+};
+use crate::sys::futex::{futex_wait, futex_wake_all};
+
+// On some platforms, the OS is very nice and handles the waiter queue for us.
+// This means we only need one atomic value with 5 states:
+
+/// No initialization has run yet, and no thread is currently using the Once.
+const INCOMPLETE: u32 = 0;
+/// Some thread has previously attempted to initialize the Once, but it panicked,
+/// so the Once is now poisoned. There are no other threads currently accessing
+/// this Once.
+const POISONED: u32 = 1;
+/// Some thread is currently attempting to run initialization. It may succeed,
+/// so all future threads need to wait for it to finish.
+const RUNNING: u32 = 2;
+/// Some thread is currently attempting to run initialization and there are threads
+/// waiting for it to finish.
+const QUEUED: u32 = 3;
+/// Initialization has completed and all future calls should finish immediately.
+const COMPLETE: u32 = 4;
+
+// Threads wait by setting the state to QUEUED and calling `futex_wait` on the state
+// variable. When the running thread finishes, it will wake all waiting threads using
+// `futex_wake_all`.
+
+pub struct OnceState {
+    poisoned: bool,
+    set_state_to: Cell<u32>,
+}
+
+impl OnceState {
+    #[inline]
+    pub fn is_poisoned(&self) -> bool {
+        self.poisoned
+    }
+
+    #[inline]
+    pub fn poison(&self) {
+        self.set_state_to.set(POISONED);
+    }
+}
+
+struct CompletionGuard<'a> {
+    state: &'a AtomicU32,
+    set_state_on_drop_to: u32,
+}
+
+impl<'a> Drop for CompletionGuard<'a> {
+    fn drop(&mut self) {
+        // Use release ordering to propagate changes to all threads checking
+        // up on the Once. `futex_wake_all` does its own synchronization, hence
+        // we do not need `AcqRel`.
+        if self.state.swap(self.set_state_on_drop_to, Release) == QUEUED {
+            futex_wake_all(&self.state);
+        }
+    }
+}
+
+pub struct Once {
+    state: AtomicU32,
+}
+
+impl Once {
+    #[inline]
+    pub const fn new() -> Once {
+        Once { state: AtomicU32::new(INCOMPLETE) }
+    }
+
+    #[inline]
+    pub fn is_completed(&self) -> bool {
+        // Use acquire ordering to make all initialization changes visible to the
+        // current thread.
+        self.state.load(Acquire) == COMPLETE
+    }
+
+    // This uses FnMut to match the API of the generic implementation. As this
+    // implementation is quite light-weight, it is generic over the closure and
+    // so avoids the cost of dynamic dispatch.
+    #[cold]
+    #[track_caller]
+    pub fn call(&self, ignore_poisoning: bool, f: &mut impl FnMut(&public::OnceState)) {
+        let mut state = self.state.load(Acquire);
+        loop {
+            match state {
+                POISONED if !ignore_poisoning => {
+                    // Panic to propagate the poison.
+                    panic!("Once instance has previously been poisoned");
+                }
+                INCOMPLETE | POISONED => {
+                    // Try to register the current thread as the one running.
+                    if let Err(new) =
+                        self.state.compare_exchange_weak(state, RUNNING, Acquire, Acquire)
+                    {
+                        state = new;
+                        continue;
+                    }
+                    // `waiter_queue` will manage other waiting threads, and
+                    // wake them up on drop.
+                    let mut waiter_queue =
+                        CompletionGuard { state: &self.state, set_state_on_drop_to: POISONED };
+                    // Run the function, letting it know if we're poisoned or not.
+                    let f_state = public::OnceState {
+                        inner: OnceState {
+                            poisoned: state == POISONED,
+                            set_state_to: Cell::new(COMPLETE),
+                        },
+                    };
+                    f(&f_state);
+                    waiter_queue.set_state_on_drop_to = f_state.inner.set_state_to.get();
+                    return;
+                }
+                RUNNING | QUEUED => {
+                    // Set the state to QUEUED if it is not already.
+                    if state == RUNNING
+                        && let Err(new) = self.state.compare_exchange_weak(RUNNING, QUEUED, Relaxed, Acquire)
+                    {
+                        state = new;
+                        continue;
+                    }
+
+                    futex_wait(&self.state, QUEUED, None);
+                    state = self.state.load(Acquire);
+                }
+                COMPLETE => return,
+                _ => unreachable!("state is never set to invalid values"),
+            }
+        }
+    }
+}
diff --git a/library/std/src/sys_common/once/generic.rs b/library/std/src/sys_common/once/generic.rs
new file mode 100644
index 00000000000..acf5f247164
--- /dev/null
+++ b/library/std/src/sys_common/once/generic.rs
@@ -0,0 +1,282 @@
+// Each `Once` has one word of atomic state, and this state is CAS'd on to
+// determine what to do. There are four possible state of a `Once`:
+//
+// * Incomplete - no initialization has run yet, and no thread is currently
+//                using the Once.
+// * Poisoned - some thread has previously attempted to initialize the Once, but
+//              it panicked, so the Once is now poisoned. There are no other
+//              threads currently accessing this Once.
+// * Running - some thread is currently attempting to run initialization. It may
+//             succeed, so all future threads need to wait for it to finish.
+//             Note that this state is accompanied with a payload, described
+//             below.
+// * Complete - initialization has completed and all future calls should finish
+//              immediately.
+//
+// With 4 states we need 2 bits to encode this, and we use the remaining bits
+// in the word we have allocated as a queue of threads waiting for the thread
+// responsible for entering the RUNNING state. This queue is just a linked list
+// of Waiter nodes which is monotonically increasing in size. Each node is
+// allocated on the stack, and whenever the running closure finishes it will
+// consume the entire queue and notify all waiters they should try again.
+//
+// You'll find a few more details in the implementation, but that's the gist of
+// it!
+//
+// Atomic orderings:
+// When running `Once` we deal with multiple atomics:
+// `Once.state_and_queue` and an unknown number of `Waiter.signaled`.
+// * `state_and_queue` is used (1) as a state flag, (2) for synchronizing the
+//   result of the `Once`, and (3) for synchronizing `Waiter` nodes.
+//     - At the end of the `call` function we have to make sure the result
+//       of the `Once` is acquired. So every load which can be the only one to
+//       load COMPLETED must have at least acquire ordering, which means all
+//       three of them.
+//     - `WaiterQueue::drop` is the only place that may store COMPLETED, and
+//       must do so with release ordering to make the result available.
+//     - `wait` inserts `Waiter` nodes as a pointer in `state_and_queue`, and
+//       needs to make the nodes available with release ordering. The load in
+//       its `compare_exchange` can be relaxed because it only has to compare
+//       the atomic, not to read other data.
+//     - `WaiterQueue::drop` must see the `Waiter` nodes, so it must load
+//       `state_and_queue` with acquire ordering.
+//     - There is just one store where `state_and_queue` is used only as a
+//       state flag, without having to synchronize data: switching the state
+//       from INCOMPLETE to RUNNING in `call`. This store can be Relaxed,
+//       but the read has to be Acquire because of the requirements mentioned
+//       above.
+// * `Waiter.signaled` is both used as a flag, and to protect a field with
+//   interior mutability in `Waiter`. `Waiter.thread` is changed in
+//   `WaiterQueue::drop` which then sets `signaled` with release ordering.
+//   After `wait` loads `signaled` with acquire ordering and sees it is true,
+//   it needs to see the changes to drop the `Waiter` struct correctly.
+// * There is one place where the two atomics `Once.state_and_queue` and
+//   `Waiter.signaled` come together, and might be reordered by the compiler or
+//   processor. Because both use acquire ordering such a reordering is not
+//   allowed, so no need for `SeqCst`.
+
+use crate::cell::Cell;
+use crate::fmt;
+use crate::ptr;
+use crate::sync as public;
+use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
+use crate::thread::{self, Thread};
+
+type Masked = ();
+
+pub struct Once {
+    state_and_queue: AtomicPtr<Masked>,
+}
+
+pub struct OnceState {
+    poisoned: bool,
+    set_state_on_drop_to: Cell<*mut Masked>,
+}
+
+// Four states that a Once can be in, encoded into the lower bits of
+// `state_and_queue` in the Once structure.
+const INCOMPLETE: usize = 0x0;
+const POISONED: usize = 0x1;
+const RUNNING: usize = 0x2;
+const COMPLETE: usize = 0x3;
+
+// Mask to learn about the state. All other bits are the queue of waiters if
+// this is in the RUNNING state.
+const STATE_MASK: usize = 0x3;
+
+// Representation of a node in the linked list of waiters, used while in the
+// RUNNING state.
+// Note: `Waiter` can't hold a mutable pointer to the next thread, because then
+// `wait` would both hand out a mutable reference to its `Waiter` node, and keep
+// a shared reference to check `signaled`. Instead we hold shared references and
+// use interior mutability.
+#[repr(align(4))] // Ensure the two lower bits are free to use as state bits.
+struct Waiter {
+    thread: Cell<Option<Thread>>,
+    signaled: AtomicBool,
+    next: *const Waiter,
+}
+
+// Head of a linked list of waiters.
+// Every node is a struct on the stack of a waiting thread.
+// Will wake up the waiters when it gets dropped, i.e. also on panic.
+struct WaiterQueue<'a> {
+    state_and_queue: &'a AtomicPtr<Masked>,
+    set_state_on_drop_to: *mut Masked,
+}
+
+impl Once {
+    #[inline]
+    pub const fn new() -> Once {
+        Once { state_and_queue: AtomicPtr::new(ptr::invalid_mut(INCOMPLETE)) }
+    }
+
+    #[inline]
+    pub fn is_completed(&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
+        // `Release` operations on the slow path.
+        self.state_and_queue.load(Ordering::Acquire).addr() == COMPLETE
+    }
+
+    // This is a non-generic function to reduce the monomorphization cost of
+    // using `call_once` (this isn't exactly a trivial or small implementation).
+    //
+    // Additionally, this is tagged with `#[cold]` as it should indeed be cold
+    // and it helps let LLVM know that calls to this function should be off the
+    // fast path. Essentially, this should help generate more straight line code
+    // in LLVM.
+    //
+    // Finally, this takes an `FnMut` instead of a `FnOnce` because there's
+    // currently no way to take an `FnOnce` and call it via virtual dispatch
+    // without some allocation overhead.
+    #[cold]
+    #[track_caller]
+    pub fn call(&self, ignore_poisoning: bool, init: &mut dyn FnMut(&public::OnceState)) {
+        let mut state_and_queue = self.state_and_queue.load(Ordering::Acquire);
+        loop {
+            match state_and_queue.addr() {
+                COMPLETE => break,
+                POISONED if !ignore_poisoning => {
+                    // Panic to propagate the poison.
+                    panic!("Once instance has previously been poisoned");
+                }
+                POISONED | INCOMPLETE => {
+                    // Try to register this thread as the one RUNNING.
+                    let exchange_result = self.state_and_queue.compare_exchange(
+                        state_and_queue,
+                        ptr::invalid_mut(RUNNING),
+                        Ordering::Acquire,
+                        Ordering::Acquire,
+                    );
+                    if let Err(old) = exchange_result {
+                        state_and_queue = old;
+                        continue;
+                    }
+                    // `waiter_queue` will manage other waiting threads, and
+                    // wake them up on drop.
+                    let mut waiter_queue = WaiterQueue {
+                        state_and_queue: &self.state_and_queue,
+                        set_state_on_drop_to: ptr::invalid_mut(POISONED),
+                    };
+                    // Run the initialization function, letting it know if we're
+                    // poisoned or not.
+                    let init_state = public::OnceState {
+                        inner: OnceState {
+                            poisoned: state_and_queue.addr() == POISONED,
+                            set_state_on_drop_to: Cell::new(ptr::invalid_mut(COMPLETE)),
+                        },
+                    };
+                    init(&init_state);
+                    waiter_queue.set_state_on_drop_to = init_state.inner.set_state_on_drop_to.get();
+                    break;
+                }
+                _ => {
+                    // All other values must be RUNNING with possibly a
+                    // pointer to the waiter queue in the more significant bits.
+                    assert!(state_and_queue.addr() & STATE_MASK == RUNNING);
+                    wait(&self.state_and_queue, state_and_queue);
+                    state_and_queue = self.state_and_queue.load(Ordering::Acquire);
+                }
+            }
+        }
+    }
+}
+
+fn wait(state_and_queue: &AtomicPtr<Masked>, mut current_state: *mut Masked) {
+    // Note: the following code was carefully written to avoid creating a
+    // mutable reference to `node` that gets aliased.
+    loop {
+        // Don't queue this thread if the status is no longer running,
+        // otherwise we will not be woken up.
+        if current_state.addr() & STATE_MASK != RUNNING {
+            return;
+        }
+
+        // Create the node for our current thread.
+        let node = Waiter {
+            thread: Cell::new(Some(thread::current())),
+            signaled: AtomicBool::new(false),
+            next: current_state.with_addr(current_state.addr() & !STATE_MASK) as *const Waiter,
+        };
+        let me = &node as *const Waiter as *const Masked as *mut Masked;
+
+        // Try to slide in the node at the head of the linked list, making sure
+        // that another thread didn't just replace the head of the linked list.
+        let exchange_result = state_and_queue.compare_exchange(
+            current_state,
+            me.with_addr(me.addr() | RUNNING),
+            Ordering::Release,
+            Ordering::Relaxed,
+        );
+        if let Err(old) = exchange_result {
+            current_state = old;
+            continue;
+        }
+
+        // We have enqueued ourselves, now lets wait.
+        // It is important not to return before being signaled, otherwise we
+        // would drop our `Waiter` node and leave a hole in the linked list
+        // (and a dangling reference). Guard against spurious wakeups by
+        // reparking ourselves until we are signaled.
+        while !node.signaled.load(Ordering::Acquire) {
+            // If the managing thread happens to signal and unpark us before we
+            // can park ourselves, the result could be this thread never gets
+            // unparked. Luckily `park` comes with the guarantee that if it got
+            // an `unpark` just before on an unparked thread it does not park.
+            thread::park();
+        }
+        break;
+    }
+}
+
+#[stable(feature = "std_debug", since = "1.16.0")]
+impl fmt::Debug for Once {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Once").finish_non_exhaustive()
+    }
+}
+
+impl Drop for WaiterQueue<'_> {
+    fn drop(&mut self) {
+        // Swap out our state with however we finished.
+        let state_and_queue =
+            self.state_and_queue.swap(self.set_state_on_drop_to, Ordering::AcqRel);
+
+        // We should only ever see an old state which was RUNNING.
+        assert_eq!(state_and_queue.addr() & STATE_MASK, RUNNING);
+
+        // Walk the entire linked list of waiters and wake them up (in lifo
+        // order, last to register is first to wake up).
+        unsafe {
+            // Right after setting `node.signaled = true` the other thread may
+            // free `node` if there happens to be has a spurious wakeup.
+            // So we have to take out the `thread` field and copy the pointer to
+            // `next` first.
+            let mut queue =
+                state_and_queue.with_addr(state_and_queue.addr() & !STATE_MASK) as *const Waiter;
+            while !queue.is_null() {
+                let next = (*queue).next;
+                let thread = (*queue).thread.take().unwrap();
+                (*queue).signaled.store(true, Ordering::Release);
+                // ^- FIXME (maybe): This is another case of issue #55005
+                // `store()` has a potentially dangling ref to `signaled`.
+                queue = next;
+                thread.unpark();
+            }
+        }
+    }
+}
+
+impl OnceState {
+    #[inline]
+    pub fn is_poisoned(&self) -> bool {
+        self.poisoned
+    }
+
+    #[inline]
+    pub fn poison(&self) {
+        self.set_state_on_drop_to.set(ptr::invalid_mut(POISONED));
+    }
+}
diff --git a/library/std/src/sys_common/once/mod.rs b/library/std/src/sys_common/once/mod.rs
new file mode 100644
index 00000000000..8742e68cc7a
--- /dev/null
+++ b/library/std/src/sys_common/once/mod.rs
@@ -0,0 +1,43 @@
+// A "once" is a relatively simple primitive, and it's also typically provided
+// by the OS as well (see `pthread_once` or `InitOnceExecuteOnce`). The OS
+// primitives, however, tend to have surprising restrictions, such as the Unix
+// one doesn't allow an argument to be passed to the function.
+//
+// As a result, we end up implementing it ourselves in the standard library.
+// This also gives us the opportunity to optimize the implementation a bit which
+// should help the fast path on call sites.
+//
+// So to recap, the guarantees of a Once are that it will call the
+// initialization closure at most once, and it will never return until the one
+// that's running has finished running. This means that we need some form of
+// blocking here while the custom callback is running at the very least.
+// Additionally, we add on the restriction of **poisoning**. Whenever an
+// initialization closure panics, the Once enters a "poisoned" state which means
+// that all future calls will immediately panic as well.
+//
+// So to implement this, one might first reach for a `Mutex`, but those cannot
+// be put into a `static`. It also gets a lot harder with poisoning to figure
+// out when the mutex needs to be deallocated because it's not after the closure
+// finishes, but after the first successful closure finishes.
+//
+// All in all, this is instead implemented with atomics and lock-free
+// operations! Whee!
+
+cfg_if::cfg_if! {
+    if #[cfg(any(
+        target_os = "linux",
+        target_os = "android",
+        all(target_arch = "wasm32", target_feature = "atomics"),
+        target_os = "freebsd",
+        target_os = "openbsd",
+        target_os = "dragonfly",
+        target_os = "fuchsia",
+        target_os = "hermit",
+    ))] {
+        mod futex;
+        pub use futex::{Once, OnceState};
+    } else {
+        mod generic;
+        pub use generic::{Once, OnceState};
+    }
+}
diff --git a/library/std/src/sys_common/rwlock.rs b/library/std/src/sys_common/rwlock.rs
index 36d721fcbcb..042981dac60 100644
--- a/library/std/src/sys_common/rwlock.rs
+++ b/library/std/src/sys_common/rwlock.rs
@@ -15,6 +15,7 @@ pub struct MovableRwLock(imp::MovableRwLock);
 impl MovableRwLock {
     /// Creates a new reader-writer lock for use.
     #[inline]
+    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
     pub const fn new() -> Self {
         Self(imp::MovableRwLock::new())
     }
diff --git a/library/std/src/sys_common/thread_local_key.rs b/library/std/src/sys_common/thread_local_key.rs
index 032bf604d73..747579f1781 100644
--- a/library/std/src/sys_common/thread_local_key.rs
+++ b/library/std/src/sys_common/thread_local_key.rs
@@ -53,7 +53,6 @@ mod tests;
 
 use crate::sync::atomic::{self, AtomicUsize, Ordering};
 use crate::sys::thread_local_key as imp;
-use crate::sys_common::mutex::StaticMutex;
 
 /// A type for TLS keys that are statically allocated.
 ///
@@ -151,25 +150,6 @@ impl StaticKey {
     }
 
     unsafe fn lazy_init(&self) -> usize {
-        // Currently the Windows implementation of TLS is pretty hairy, and
-        // it greatly simplifies creation if we just synchronize everything.
-        //
-        // Additionally a 0-index of a tls key hasn't been seen on windows, so
-        // we just simplify the whole branch.
-        if imp::requires_synchronized_create() {
-            // We never call `INIT_LOCK.init()`, so it is UB to attempt to
-            // acquire this mutex reentrantly!
-            static INIT_LOCK: StaticMutex = StaticMutex::new();
-            let _guard = INIT_LOCK.lock();
-            let mut key = self.key.load(Ordering::SeqCst);
-            if key == 0 {
-                key = imp::create(self.dtor) as usize;
-                self.key.store(key, Ordering::SeqCst);
-            }
-            rtassert!(key != 0);
-            return key;
-        }
-
         // POSIX allows the key created here to be 0, but the compare_exchange
         // below relies on using 0 as a sentinel value to check who won the
         // race to set the shared TLS key. As far as I know, there is no
@@ -232,8 +212,6 @@ impl Key {
 
 impl Drop for Key {
     fn drop(&mut self) {
-        // Right now Windows doesn't support TLS key destruction, but this also
-        // isn't used anywhere other than tests, so just leak the TLS key.
-        // unsafe { imp::destroy(self.key) }
+        unsafe { imp::destroy(self.key) }
     }
 }
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index 8aedfc4a6b8..5d267891bb0 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -95,6 +95,7 @@ use crate::fmt;
 /// [loader lock]: https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
 /// [`JoinHandle::join`]: crate::thread::JoinHandle::join
 /// [`with`]: LocalKey::with
+#[cfg_attr(not(test), rustc_diagnostic_item = "LocalKey")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct LocalKey<T: 'static> {
     // This outer `LocalKey<T>` type is what's going to be stored in statics,
@@ -900,7 +901,7 @@ pub mod statik {
 }
 
 #[doc(hidden)]
-#[cfg(target_thread_local)]
+#[cfg(all(target_thread_local, not(all(target_family = "wasm", not(target_feature = "atomics"))),))]
 pub mod fast {
     use super::lazy::LazyKeyInner;
     use crate::cell::Cell;
@@ -1036,7 +1037,10 @@ pub mod fast {
 }
 
 #[doc(hidden)]
-#[cfg(not(target_thread_local))]
+#[cfg(all(
+    not(target_thread_local),
+    not(all(target_family = "wasm", not(target_feature = "atomics"))),
+))]
 pub mod os {
     use super::lazy::LazyKeyInner;
     use crate::cell::Cell;
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index ceea6986e33..05023df1bb2 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -150,6 +150,8 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
+// Under `test`, `__FastLocalKeyInner` seems unused.
+#![cfg_attr(test, allow(dead_code))]
 
 #[cfg(all(test, not(target_os = "emscripten")))]
 mod tests;
@@ -160,7 +162,7 @@ use crate::ffi::{CStr, CString};
 use crate::fmt;
 use crate::io;
 use crate::marker::PhantomData;
-use crate::mem;
+use crate::mem::{self, forget};
 use crate::num::NonZeroU64;
 use crate::num::NonZeroUsize;
 use crate::panic;
@@ -192,32 +194,40 @@ pub use scoped::{scope, Scope, ScopedJoinHandle};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::local::{AccessError, LocalKey};
 
-// Select the type used by the thread_local! macro to access TLS keys. There
-// are three types: "static", "fast", "OS". The "OS" thread local key
+// Provide the type used by the thread_local! macro to access TLS keys. This
+// needs to be kept in sync with the macro itself (in `local.rs`).
+// There are three types: "static", "fast", "OS". The "OS" thread local key
 // type is accessed via platform-specific API calls and is slow, while the "fast"
 // key type is accessed via code generated via LLVM, where TLS keys are set up
 // by the elf linker. "static" is for single-threaded platforms where a global
 // static is sufficient.
 
 #[unstable(feature = "libstd_thread_internals", issue = "none")]
-#[cfg(target_thread_local)]
 #[cfg(not(test))]
+#[cfg(all(
+    target_thread_local,
+    not(all(target_family = "wasm", not(target_feature = "atomics"))),
+))]
 #[doc(hidden)]
 pub use self::local::fast::Key as __FastLocalKeyInner;
-#[unstable(feature = "libstd_thread_internals", issue = "none")]
-#[cfg(target_thread_local)]
-#[cfg(test)] // when building for tests, use real std's key
-pub use realstd::thread::__FastLocalKeyInner;
 
+// when building for tests, use real std's type
 #[unstable(feature = "libstd_thread_internals", issue = "none")]
-#[cfg(target_thread_local)]
 #[cfg(test)]
-pub use self::local::fast::Key as __FastLocalKeyInnerUnused; // we import this anyway to silence 'unused' warnings
+#[cfg(all(
+    target_thread_local,
+    not(all(target_family = "wasm", not(target_feature = "atomics"))),
+))]
+pub use realstd::thread::__FastLocalKeyInner;
 
 #[unstable(feature = "libstd_thread_internals", issue = "none")]
+#[cfg(all(
+    not(target_thread_local),
+    not(all(target_family = "wasm", not(target_feature = "atomics"))),
+))]
 #[doc(hidden)]
-#[cfg(not(target_thread_local))]
 pub use self::local::os::Key as __OsLocalKeyInner;
+
 #[unstable(feature = "libstd_thread_internals", issue = "none")]
 #[cfg(all(target_family = "wasm", not(target_feature = "atomics")))]
 #[doc(hidden)]
@@ -499,6 +509,31 @@ impl Builder {
         let output_capture = crate::io::set_output_capture(None);
         crate::io::set_output_capture(output_capture.clone());
 
+        // Pass `f` in `MaybeUninit` because actually that closure might *run longer than the lifetime of `F`*.
+        // See <https://github.com/rust-lang/rust/issues/101983> for more details.
+        // To prevent leaks we use a wrapper that drops its contents.
+        #[repr(transparent)]
+        struct MaybeDangling<T>(mem::MaybeUninit<T>);
+        impl<T> MaybeDangling<T> {
+            fn new(x: T) -> Self {
+                MaybeDangling(mem::MaybeUninit::new(x))
+            }
+            fn into_inner(self) -> T {
+                // SAFETY: we are always initiailized.
+                let ret = unsafe { self.0.assume_init_read() };
+                // Make sure we don't drop.
+                mem::forget(self);
+                ret
+            }
+        }
+        impl<T> Drop for MaybeDangling<T> {
+            fn drop(&mut self) {
+                // SAFETY: we are always initiailized.
+                unsafe { self.0.assume_init_drop() };
+            }
+        }
+
+        let f = MaybeDangling::new(f);
         let main = move || {
             if let Some(name) = their_thread.cname() {
                 imp::Thread::set_name(name);
@@ -506,6 +541,8 @@ impl Builder {
 
             crate::io::set_output_capture(output_capture);
 
+            // SAFETY: we constructed `f` initialized.
+            let f = f.into_inner();
             // SAFETY: the stack guard passed is the one for the current thread.
             // This means the current thread's stack and the new thread's stack
             // are properly set and protected from each other.
@@ -518,6 +555,12 @@ impl Builder {
             // same `JoinInner` as this closure meaning the mutation will be
             // safe (not modify it and affect a value far away).
             unsafe { *their_packet.result.get() = Some(try_result) };
+            // Here `their_packet` gets dropped, and if this is the last `Arc` for that packet that
+            // will call `decrement_num_running_threads` and therefore signal that this thread is
+            // done.
+            drop(their_packet);
+            // Here, the lifetime `'a` and even `'scope` can end. `main` keeps running for a bit
+            // after that before returning itself.
         };
 
         if let Some(scope_data) = &my_packet.scope {
@@ -779,6 +822,8 @@ pub fn panicking() -> bool {
     panicking::panicking()
 }
 
+/// Use [`sleep`].
+///
 /// Puts the current thread to sleep for at least the specified amount of time.
 ///
 /// The thread may sleep longer than the duration specified due to scheduling
@@ -849,10 +894,22 @@ pub fn sleep(dur: Duration) {
     imp::Thread::sleep(dur)
 }
 
+/// Used to ensure that `park` and `park_timeout` do not unwind, as that can
+/// cause undefined behaviour if not handled correctly (see #102398 for context).
+struct PanicGuard;
+
+impl Drop for PanicGuard {
+    fn drop(&mut self) {
+        rtabort!("an irrecoverable error occurred while synchronizing threads")
+    }
+}
+
 /// Blocks unless or until the current thread's token is made available.
 ///
 /// A call to `park` does not guarantee that the thread will remain parked
-/// forever, and callers should be prepared for this possibility.
+/// forever, and callers should be prepared for this possibility. However,
+/// it is guaranteed that this function will not panic (it may abort the
+/// process if the implementation encounters some rare errors).
 ///
 /// # park and unpark
 ///
@@ -937,10 +994,13 @@ pub fn sleep(dur: Duration) {
 /// [`thread::park_timeout`]: park_timeout
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn park() {
+    let guard = PanicGuard;
     // SAFETY: park_timeout is called on the parker owned by this thread.
     unsafe {
         current().inner.as_ref().parker().park();
     }
+    // No panic occurred, do not abort.
+    forget(guard);
 }
 
 /// Use [`park_timeout`].
@@ -1001,10 +1061,13 @@ pub fn park_timeout_ms(ms: u32) {
 /// ```
 #[stable(feature = "park_timeout", since = "1.4.0")]
 pub fn park_timeout(dur: Duration) {
+    let guard = PanicGuard;
     // SAFETY: park_timeout is called on the parker owned by this thread.
     unsafe {
         current().inner.as_ref().parker().park_timeout(dur);
     }
+    // No panic occurred, do not abort.
+    forget(guard);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1065,24 +1128,21 @@ impl ThreadId {
                     }
                 }
             } else {
-                use crate::sys_common::mutex::StaticMutex;
+                use crate::sync::{Mutex, PoisonError};
 
-                // It is UB to attempt to acquire this mutex reentrantly!
-                static GUARD: StaticMutex = StaticMutex::new();
-                static mut COUNTER: u64 = 0;
+                static COUNTER: Mutex<u64> = Mutex::new(0);
 
-                unsafe {
-                    let guard = GUARD.lock();
+                let mut counter = COUNTER.lock().unwrap_or_else(PoisonError::into_inner);
+                let Some(id) = counter.checked_add(1) else {
+                    // in case the panic handler ends up calling `ThreadId::new()`,
+                    // avoid reentrant lock acquire.
+                    drop(counter);
+                    exhausted();
+                };
 
-                    let Some(id) = COUNTER.checked_add(1) else {
-                        drop(guard); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
-                        exhausted();
-                    };
-
-                    COUNTER = id;
-                    drop(guard);
-                    ThreadId(NonZeroU64::new(id).unwrap())
-                }
+                *counter = id;
+                drop(counter);
+                ThreadId(NonZeroU64::new(id).unwrap())
             }
         }
     }
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index 130e47c8d44..dfb8765ab4e 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -245,6 +245,28 @@ fn test_try_panic_any_message_unit_struct() {
 }
 
 #[test]
+fn test_park_unpark_before() {
+    for _ in 0..10 {
+        thread::current().unpark();
+        thread::park();
+    }
+}
+
+#[test]
+fn test_park_unpark_called_other_thread() {
+    for _ in 0..10 {
+        let th = thread::current();
+
+        let _guard = thread::spawn(move || {
+            super::sleep(Duration::from_millis(50));
+            th.unpark();
+        });
+
+        thread::park();
+    }
+}
+
+#[test]
 fn test_park_timeout_unpark_before() {
     for _ in 0..10 {
         thread::current().unpark();
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index 759a59e1f98..d4a1b9d9b50 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -356,7 +356,7 @@ impl Instant {
     ///
     /// # Panics
     ///
-    /// Previous rust versions panicked when self was earlier than the current time. Currently this
+    /// Previous rust versions panicked when the current time was earlier than self. Currently this
     /// method returns a Duration of zero in that case. Future versions may reintroduce the panic.
     /// See [Monotonicity].
     ///