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/collections/hash/map.rs20
-rw-r--r--library/std/src/collections/hash/set.rs19
-rw-r--r--library/std/src/env.rs73
-rw-r--r--library/std/src/ffi/os_str.rs22
-rw-r--r--library/std/src/fs.rs75
-rw-r--r--library/std/src/fs/tests.rs36
-rw-r--r--library/std/src/io/pipe.rs6
-rw-r--r--library/std/src/keyword_docs.rs89
-rw-r--r--library/std/src/lib.rs3
-rw-r--r--library/std/src/path.rs19
-rw-r--r--library/std/src/process.rs48
-rw-r--r--library/std/src/sync/poison/mutex.rs22
-rw-r--r--library/std/src/sync/poison/rwlock.rs54
-rw-r--r--library/std/src/sys/args/common.rs66
-rw-r--r--library/std/src/sys/args/sgx.rs68
-rw-r--r--library/std/src/sys/args/unsupported.rs18
-rw-r--r--library/std/src/sys/exit_guard.rs43
-rw-r--r--library/std/src/sys/fs/hermit.rs11
-rw-r--r--library/std/src/sys/fs/solid.rs11
-rw-r--r--library/std/src/sys/fs/uefi.rs5
-rw-r--r--library/std/src/sys/fs/unix.rs39
-rw-r--r--library/std/src/sys/fs/unsupported.rs5
-rw-r--r--library/std/src/sys/fs/wasi.rs11
-rw-r--r--library/std/src/sys/fs/windows.rs17
-rw-r--r--library/std/src/sys/os_str/bytes.rs25
-rw-r--r--library/std/src/sys/os_str/wtf8.rs30
-rw-r--r--library/std/src/sys/pal/unix/fuchsia.rs321
-rw-r--r--library/std/src/sys/pal/unix/futex.rs54
-rw-r--r--library/std/src/sys/pal/unix/os.rs2
-rw-r--r--library/std/src/sys/pal/unix/thread.rs19
-rw-r--r--library/std/src/sys/process/env.rs (renamed from library/std/src/sys_common/process.rs)48
-rw-r--r--library/std/src/sys/process/mod.rs59
-rw-r--r--library/std/src/sys/process/uefi.rs116
-rw-r--r--library/std/src/sys/process/unix/common.rs2
-rw-r--r--library/std/src/sys/process/unix/fuchsia.rs9
-rw-r--r--library/std/src/sys/process/unix/mod.rs1
-rw-r--r--library/std/src/sys/process/unix/unix.rs5
-rw-r--r--library/std/src/sys/process/unix/unsupported.rs8
-rw-r--r--library/std/src/sys/process/unix/vxworks.rs5
-rw-r--r--library/std/src/sys/process/unsupported.rs8
-rw-r--r--library/std/src/sys/process/windows.rs7
-rw-r--r--library/std/src/sys/sync/mutex/fuchsia.rs6
-rw-r--r--library/std/src/sys_common/mod.rs1
43 files changed, 882 insertions, 624 deletions
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 9ad26e5d28e..961d6ee0665 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -683,7 +683,7 @@ impl<K, V, S> HashMap<K, V, S> {
     /// ```
     #[inline]
     #[rustc_lint_query_instability]
-    #[stable(feature = "hash_extract_if", since = "1.87.0")]
+    #[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
     pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, K, V, F>
     where
         F: FnMut(&K, &mut V) -> bool,
@@ -1680,12 +1680,9 @@ impl<'a, K, V> Drain<'a, K, V> {
 /// ]);
 /// let iter = map.extract_if(|_k, v| *v % 2 == 0);
 /// ```
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
-pub struct ExtractIf<'a, K, V, F>
-where
-    F: FnMut(&K, &mut V) -> bool,
-{
+pub struct ExtractIf<'a, K, V, F> {
     base: base::ExtractIf<'a, K, V, F>,
 }
 
@@ -2297,7 +2294,7 @@ where
     }
 }
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<K, V, F> Iterator for ExtractIf<'_, K, V, F>
 where
     F: FnMut(&K, &mut V) -> bool,
@@ -2314,13 +2311,14 @@ where
     }
 }
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<K, V, F> FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {}
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
-impl<'a, K, V, F> fmt::Debug for ExtractIf<'a, K, V, F>
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+impl<K, V, F> fmt::Debug for ExtractIf<'_, K, V, F>
 where
-    F: FnMut(&K, &mut V) -> bool,
+    K: fmt::Debug,
+    V: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("ExtractIf").finish_non_exhaustive()
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 7be000594bc..fa2f4f0a58f 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -308,7 +308,7 @@ impl<T, S> HashSet<T, S> {
     /// ```
     #[inline]
     #[rustc_lint_query_instability]
-    #[stable(feature = "hash_extract_if", since = "1.87.0")]
+    #[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
     pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, T, F>
     where
         F: FnMut(&T) -> bool,
@@ -1390,11 +1390,8 @@ pub struct Drain<'a, K: 'a> {
 ///
 /// let mut extract_ifed = a.extract_if(|v| v % 2 == 0);
 /// ```
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
-pub struct ExtractIf<'a, K, F>
-where
-    F: FnMut(&K) -> bool,
-{
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+pub struct ExtractIf<'a, K, F> {
     base: base::ExtractIf<'a, K, F>,
 }
 
@@ -1673,7 +1670,7 @@ impl<K: fmt::Debug> fmt::Debug for Drain<'_, K> {
     }
 }
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<K, F> Iterator for ExtractIf<'_, K, F>
 where
     F: FnMut(&K) -> bool,
@@ -1690,13 +1687,13 @@ where
     }
 }
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<K, F> FusedIterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool {}
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
-impl<'a, K, F> fmt::Debug for ExtractIf<'a, K, F>
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+impl<K, F> fmt::Debug for ExtractIf<'_, K, F>
 where
-    F: FnMut(&K) -> bool,
+    K: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("ExtractIf").finish_non_exhaustive()
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 1593969e114..ce2dc795220 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -12,9 +12,11 @@
 
 use crate::error::Error;
 use crate::ffi::{OsStr, OsString};
+use crate::num::NonZero;
+use crate::ops::Try;
 use crate::path::{Path, PathBuf};
 use crate::sys::{env as env_imp, os as os_imp};
-use crate::{fmt, io, sys};
+use crate::{array, fmt, io, sys};
 
 /// Returns the current working directory as a [`PathBuf`].
 ///
@@ -872,19 +874,36 @@ impl !Sync for Args {}
 #[stable(feature = "env", since = "1.0.0")]
 impl Iterator for Args {
     type Item = String;
+
     fn next(&mut self) -> Option<String> {
         self.inner.next().map(|s| s.into_string().unwrap())
     }
+
+    #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    // Methods which skip args cannot simply delegate to the inner iterator,
+    // because `env::args` states that we will "panic during iteration if any
+    // argument to the process is not valid Unicode".
+    //
+    // This offers two possible interpretations:
+    // - a skipped argument is never encountered "during iteration"
+    // - even a skipped argument is encountered "during iteration"
+    //
+    // As a panic can be observed, we err towards validating even skipped
+    // arguments for now, though this is not explicitly promised by the API.
 }
 
 #[stable(feature = "env", since = "1.0.0")]
 impl ExactSizeIterator for Args {
+    #[inline]
     fn len(&self) -> usize {
         self.inner.len()
     }
+
+    #[inline]
     fn is_empty(&self) -> bool {
         self.inner.is_empty()
     }
@@ -914,19 +933,65 @@ impl !Sync for ArgsOs {}
 #[stable(feature = "env", since = "1.0.0")]
 impl Iterator for ArgsOs {
     type Item = OsString;
+
+    #[inline]
     fn next(&mut self) -> Option<OsString> {
         self.inner.next()
     }
+
+    #[inline]
+    fn next_chunk<const N: usize>(
+        &mut self,
+    ) -> Result<[OsString; N], array::IntoIter<OsString, N>> {
+        self.inner.next_chunk()
+    }
+
+    #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.inner.len()
+    }
+
+    #[inline]
+    fn last(self) -> Option<OsString> {
+        self.inner.last()
+    }
+
+    #[inline]
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.inner.advance_by(n)
+    }
+
+    #[inline]
+    fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>,
+    {
+        self.inner.try_fold(init, f)
+    }
+
+    #[inline]
+    fn fold<B, F>(self, init: B, f: F) -> B
+    where
+        F: FnMut(B, Self::Item) -> B,
+    {
+        self.inner.fold(init, f)
+    }
 }
 
 #[stable(feature = "env", since = "1.0.0")]
 impl ExactSizeIterator for ArgsOs {
+    #[inline]
     fn len(&self) -> usize {
         self.inner.len()
     }
+
+    #[inline]
     fn is_empty(&self) -> bool {
         self.inner.is_empty()
     }
@@ -934,9 +999,15 @@ impl ExactSizeIterator for ArgsOs {
 
 #[stable(feature = "env_iterators", since = "1.12.0")]
 impl DoubleEndedIterator for ArgsOs {
+    #[inline]
     fn next_back(&mut self) -> Option<OsString> {
         self.inner.next_back()
     }
+
+    #[inline]
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.inner.advance_back_by(n)
+    }
 }
 
 #[stable(feature = "std_debug", since = "1.16.0")]
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index ce01175309a..72bdf03ee61 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -582,15 +582,25 @@ impl OsString {
     #[unstable(feature = "os_string_truncate", issue = "133262")]
     pub fn truncate(&mut self, len: usize) {
         self.as_os_str().inner.check_public_boundary(len);
-        self.inner.truncate(len);
+        // SAFETY: The length was just checked to be at a valid boundary.
+        unsafe { self.inner.truncate_unchecked(len) };
     }
 
-    /// Provides plumbing to core `Vec::extend_from_slice`.
-    /// More well behaving alternative to allowing outer types
-    /// full mutable access to the core `Vec`.
+    /// Provides plumbing to `Vec::extend_from_slice` without giving full
+    /// mutable access to the `Vec`.
+    ///
+    /// # Safety
+    ///
+    /// The slice must be valid for the platform encoding (as described in
+    /// [`OsStr::from_encoded_bytes_unchecked`]).
+    ///
+    /// This bypasses the encoding-dependent surrogate joining, so `self` must
+    /// not end with a leading surrogate half and `other` must not start with
+    /// with a trailing surrogate half.
     #[inline]
-    pub(crate) fn extend_from_slice(&mut self, other: &[u8]) {
-        self.inner.extend_from_slice(other);
+    pub(crate) unsafe fn extend_from_slice_unchecked(&mut self, other: &[u8]) {
+        // SAFETY: Guaranteed by caller.
+        unsafe { self.inner.extend_from_slice_unchecked(other) };
     }
 }
 
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 3340a5dc23d..11f439b9996 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -21,7 +21,6 @@
 mod tests;
 
 use crate::ffi::OsString;
-use crate::fmt;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
 use crate::path::{Path, PathBuf};
 use crate::sealed::Sealed;
@@ -29,6 +28,7 @@ use crate::sync::Arc;
 use crate::sys::fs as fs_imp;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 use crate::time::SystemTime;
+use crate::{error, fmt};
 
 /// An object providing access to an open file on the filesystem.
 ///
@@ -116,6 +116,22 @@ pub struct File {
     inner: fs_imp::File,
 }
 
+/// An enumeration of possible errors which can occur while trying to acquire a lock
+/// from the [`try_lock`] method and [`try_lock_shared`] method on a [`File`].
+///
+/// [`try_lock`]: File::try_lock
+/// [`try_lock_shared`]: File::try_lock_shared
+#[unstable(feature = "file_lock", issue = "130994")]
+pub enum TryLockError {
+    /// The lock could not be acquired due to an I/O error on the file. The standard library will
+    /// not return an [`ErrorKind::WouldBlock`] error inside [`TryLockError::Error`]
+    ///
+    /// [`ErrorKind::WouldBlock`]: io::ErrorKind::WouldBlock
+    Error(io::Error),
+    /// The lock could not be acquired at this time because it is held by another handle/process.
+    WouldBlock,
+}
+
 /// Metadata information about a file.
 ///
 /// This structure is returned from the [`metadata`] or
@@ -352,6 +368,30 @@ pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result
     inner(path.as_ref(), contents.as_ref())
 }
 
+#[unstable(feature = "file_lock", issue = "130994")]
+impl error::Error for TryLockError {}
+
+#[unstable(feature = "file_lock", issue = "130994")]
+impl fmt::Debug for TryLockError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            TryLockError::Error(err) => err.fmt(f),
+            TryLockError::WouldBlock => "WouldBlock".fmt(f),
+        }
+    }
+}
+
+#[unstable(feature = "file_lock", issue = "130994")]
+impl fmt::Display for TryLockError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            TryLockError::Error(_) => "lock acquisition failed due to I/O error",
+            TryLockError::WouldBlock => "lock acquisition failed because the operation would block",
+        }
+        .fmt(f)
+    }
+}
+
 impl File {
     /// Attempts to open a file in read-only mode.
     ///
@@ -734,8 +774,8 @@ impl File {
 
     /// Try to acquire an exclusive lock on the file.
     ///
-    /// Returns `Ok(false)` if a different lock is already held on this file (via another
-    /// handle/descriptor).
+    /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file
+    /// (via another handle/descriptor).
     ///
     /// This acquires an exclusive lock; no other file handle to this file may acquire another lock.
     ///
@@ -777,23 +817,27 @@ impl File {
     ///
     /// ```no_run
     /// #![feature(file_lock)]
-    /// use std::fs::File;
+    /// use std::fs::{File, TryLockError};
     ///
     /// fn main() -> std::io::Result<()> {
     ///     let f = File::create("foo.txt")?;
-    ///     f.try_lock()?;
+    ///     match f.try_lock() {
+    ///         Ok(_) => (),
+    ///         Err(TryLockError::WouldBlock) => (), // Lock not acquired
+    ///         Err(TryLockError::Error(err)) => return Err(err),
+    ///     }
     ///     Ok(())
     /// }
     /// ```
     #[unstable(feature = "file_lock", issue = "130994")]
-    pub fn try_lock(&self) -> io::Result<bool> {
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
         self.inner.try_lock()
     }
 
     /// Try to acquire a shared (non-exclusive) lock on the file.
     ///
-    /// Returns `Ok(false)` if an exclusive lock is already held on this file (via another
-    /// handle/descriptor).
+    /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file
+    /// (via another handle/descriptor).
     ///
     /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may
     /// hold an exclusive lock at the same time.
@@ -834,16 +878,21 @@ impl File {
     ///
     /// ```no_run
     /// #![feature(file_lock)]
-    /// use std::fs::File;
+    /// use std::fs::{File, TryLockError};
     ///
     /// fn main() -> std::io::Result<()> {
     ///     let f = File::open("foo.txt")?;
-    ///     f.try_lock_shared()?;
+    ///     match f.try_lock_shared() {
+    ///         Ok(_) => (),
+    ///         Err(TryLockError::WouldBlock) => (), // Lock not acquired
+    ///         Err(TryLockError::Error(err)) => return Err(err),
+    ///     }
+    ///
     ///     Ok(())
     /// }
     /// ```
     #[unstable(feature = "file_lock", issue = "130994")]
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
         self.inner.try_lock_shared()
     }
 
@@ -2874,6 +2923,8 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///
 /// Consider ignoring the error if validating the removal is not required for your use case.
 ///
+/// This function may return [`io::ErrorKind::DirectoryNotEmpty`] if the directory is concurrently
+/// written into, which typically indicates some contents were removed but not all.
 /// [`io::ErrorKind::NotFound`] is only returned if no removal occurs.
 ///
 /// [`fs::remove_file`]: remove_file
@@ -2992,7 +3043,7 @@ pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
 /// When possible, permissions should be set at creation time instead.
 ///
 /// # Rationale
-/// POSIX does not specify an `lchown` function,
+/// POSIX does not specify an `lchmod` function,
 /// and symlinks can be followed regardless of what permission bits are set.
 ///
 /// # Errors
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 4712e58980c..46b0d832fec 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1,6 +1,22 @@
 use rand::RngCore;
 
+#[cfg(any(
+    windows,
+    target_os = "freebsd",
+    target_os = "linux",
+    target_os = "netbsd",
+    target_vendor = "apple",
+))]
+use crate::assert_matches::assert_matches;
 use crate::char::MAX_LEN_UTF8;
+#[cfg(any(
+    windows,
+    target_os = "freebsd",
+    target_os = "linux",
+    target_os = "netbsd",
+    target_vendor = "apple",
+))]
+use crate::fs::TryLockError;
 use crate::fs::{self, File, FileTimes, OpenOptions};
 use crate::io::prelude::*;
 use crate::io::{BorrowedBuf, ErrorKind, SeekFrom};
@@ -223,8 +239,8 @@ fn file_lock_multiple_shared() {
     check!(f2.lock_shared());
     check!(f1.unlock());
     check!(f2.unlock());
-    assert!(check!(f1.try_lock_shared()));
-    assert!(check!(f2.try_lock_shared()));
+    check!(f1.try_lock_shared());
+    check!(f2.try_lock_shared());
 }
 
 #[test]
@@ -243,12 +259,12 @@ fn file_lock_blocking() {
 
     // Check that shared locks block exclusive locks
     check!(f1.lock_shared());
-    assert!(!check!(f2.try_lock()));
+    assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
     check!(f1.unlock());
 
     // Check that exclusive locks block shared locks
     check!(f1.lock());
-    assert!(!check!(f2.try_lock_shared()));
+    assert_matches!(f2.try_lock_shared(), Err(TryLockError::WouldBlock));
 }
 
 #[test]
@@ -267,9 +283,9 @@ fn file_lock_drop() {
 
     // Check that locks are released when the File is dropped
     check!(f1.lock_shared());
-    assert!(!check!(f2.try_lock()));
+    assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
     drop(f1);
-    assert!(check!(f2.try_lock()));
+    check!(f2.try_lock());
 }
 
 #[test]
@@ -288,10 +304,10 @@ fn file_lock_dup() {
 
     // Check that locks are not dropped if the File has been cloned
     check!(f1.lock_shared());
-    assert!(!check!(f2.try_lock()));
+    assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
     let cloned = check!(f1.try_clone());
     drop(f1);
-    assert!(!check!(f2.try_lock()));
+    assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
     drop(cloned)
 }
 
@@ -307,9 +323,9 @@ fn file_lock_double_unlock() {
     // Check that both are released by unlock()
     check!(f1.lock());
     check!(f1.lock_shared());
-    assert!(!check!(f2.try_lock()));
+    assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
     check!(f1.unlock());
-    assert!(check!(f2.try_lock()));
+    check!(f2.try_lock());
 }
 
 #[test]
diff --git a/library/std/src/io/pipe.rs b/library/std/src/io/pipe.rs
index c6b7b49a351..47243806cd2 100644
--- a/library/std/src/io/pipe.rs
+++ b/library/std/src/io/pipe.rs
@@ -2,7 +2,7 @@ use crate::io;
 use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner};
 use crate::sys_common::{FromInner, IntoInner};
 
-/// Create an anonymous pipe.
+/// Creates an anonymous pipe.
 ///
 /// # Behavior
 ///
@@ -108,7 +108,7 @@ impl IntoInner<AnonPipe> for PipeWriter {
 }
 
 impl PipeReader {
-    /// Create a new [`PipeReader`] instance that shares the same underlying file description.
+    /// Creates a new [`PipeReader`] instance that shares the same underlying file description.
     ///
     /// # Examples
     ///
@@ -167,7 +167,7 @@ impl PipeReader {
 }
 
 impl PipeWriter {
-    /// Create a new [`PipeWriter`] instance that shares the same underlying file description.
+    /// Creates a new [`PipeWriter`] instance that shares the same underlying file description.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index c9595b051e2..79b25040ef6 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -91,7 +91,7 @@ mod as_keyword {}
 ///
 /// When associated with `loop`, a break expression may be used to return a value from that loop.
 /// This is only valid with `loop` and not with any other type of loop.
-/// If no value is specified, `break;` returns `()`.
+/// If no value is specified for `break;` it returns `()`.
 /// Every `break` within a loop must return the same type.
 ///
 /// ```rust
@@ -109,6 +109,33 @@ mod as_keyword {}
 /// println!("{result}");
 /// ```
 ///
+/// It is also possible to exit from any *labelled* block returning the value early.
+/// If no value is specified for `break;` it returns `()`.
+///
+/// ```rust
+/// let inputs = vec!["Cow", "Cat", "Dog", "Snake", "Cod"];
+///
+/// let mut results = vec![];
+/// for input in inputs {
+///     let result = 'filter: {
+///         if input.len() > 3 {
+///             break 'filter Err("Too long");
+///         };
+///
+///         if !input.contains("C") {
+///             break 'filter Err("No Cs");
+///         };
+///
+///         Ok(input.to_uppercase())
+///     };
+///
+///     results.push(result);
+/// }
+///
+/// // [Ok("COW"), Ok("CAT"), Err("No Cs"), Err("Too long"), Ok("COD")]
+/// println!("{:?}", results)
+/// ```
+///
 /// For more details consult the [Reference on "break expression"] and the [Reference on "break and
 /// loop values"].
 ///
@@ -1206,6 +1233,28 @@ mod ref_keyword {}
 ///     Ok(())
 /// }
 /// ```
+///
+/// Within [closures] and [`async`] blocks, `return` returns a value from within the closure or
+/// `async` block, not from the parent function:
+///
+/// ```rust
+/// fn foo() -> i32 {
+///     let closure = || {
+///         return 5;
+///     };
+///
+///     let future = async {
+///         return 10;
+///     };
+///
+///     return 15;
+/// }
+///
+/// assert_eq!(foo(), 15);
+/// ```
+///
+/// [closures]: ../book/ch13-01-closures.html
+/// [`async`]: ../std/keyword.async.html
 mod return_keyword {}
 
 #[doc(keyword = "self")]
@@ -2399,6 +2448,39 @@ mod while_keyword {}
 ///
 /// We have written an [async book] detailing `async`/`await` and trade-offs compared to using threads.
 ///
+/// ## Control Flow
+/// [`return`] statements and [`?`][try operator] operators within `async` blocks do not cause
+/// a return from the parent function; rather, they cause the `Future` returned by the block to
+/// return with that value.
+///
+/// For example, the following Rust function will return `5`, causing `x` to take the [`!` type][never type]:
+/// ```rust
+/// #[expect(unused_variables)]
+/// fn example() -> i32 {
+///     let x = {
+///         return 5;
+///     };
+/// }
+/// ```
+/// In contrast, the following asynchronous function assigns a `Future<Output = i32>` to `x`, and
+/// only returns `5` when `x` is `.await`ed:
+/// ```rust
+/// async fn example() -> i32 {
+///     let x = async {
+///         return 5;
+///     };
+///
+///     x.await
+/// }
+/// ```
+/// Code using `?` behaves similarly - it causes the `async` block to return a [`Result`] without
+/// affecting the parent function.
+///
+/// Note that you cannot use `break` or `continue` from within an `async` block to affect the
+/// control flow of a loop in the parent function.
+///
+/// Control flow in `async` blocks is documented further in the [async book][async book blocks].
+///
 /// ## Editions
 ///
 /// `async` is a keyword from the 2018 edition onwards.
@@ -2408,6 +2490,11 @@ mod while_keyword {}
 /// [`Future`]: future::Future
 /// [`.await`]: ../std/keyword.await.html
 /// [async book]: https://rust-lang.github.io/async-book/
+/// [`return`]: ../std/keyword.return.html
+/// [try operator]: ../reference/expressions/operator-expr.html#r-expr.try
+/// [never type]: ../reference/types/never.html
+/// [`Result`]: result::Result
+/// [async book blocks]: https://rust-lang.github.io/async-book/part-guide/more-async-await.html#async-blocks
 mod async_keyword {}
 
 #[doc(keyword = "await")]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index ba57ad9bae3..c011f9661ae 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -301,6 +301,8 @@
 #![feature(formatting_options)]
 #![feature(if_let_guard)]
 #![feature(intra_doc_pointers)]
+#![feature(iter_advance_by)]
+#![feature(iter_next_chunk)]
 #![feature(lang_items)]
 #![feature(let_chains)]
 #![feature(link_cfg)]
@@ -321,6 +323,7 @@
 #![feature(strict_provenance_lints)]
 #![feature(thread_local)]
 #![feature(try_blocks)]
+#![feature(try_trait_v2)]
 #![feature(type_alias_impl_trait)]
 // tidy-alphabetical-end
 //
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 7cd20c48d89..1a4a7aa7448 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1529,11 +1529,13 @@ impl PathBuf {
         self.inner.truncate(end_file_stem.wrapping_sub(start));
 
         // add the new extension, if any
-        let new = extension;
+        let new = extension.as_encoded_bytes();
         if !new.is_empty() {
             self.inner.reserve_exact(new.len() + 1);
-            self.inner.push(OsStr::new("."));
-            self.inner.push(new);
+            self.inner.push(".");
+            // SAFETY: Since a UTF-8 string was just pushed, it is not possible
+            // for the buffer to end with a surrogate half.
+            unsafe { self.inner.extend_from_slice_unchecked(new) };
         }
 
         true
@@ -1597,7 +1599,7 @@ impl PathBuf {
             Some(f) => f.as_encoded_bytes(),
         };
 
-        let new = extension;
+        let new = extension.as_encoded_bytes();
         if !new.is_empty() {
             // truncate until right after the file name
             // this is necessary for trimming the trailing slash
@@ -1607,8 +1609,10 @@ impl PathBuf {
 
             // append the new extension
             self.inner.reserve_exact(new.len() + 1);
-            self.inner.push(OsStr::new("."));
-            self.inner.push(new);
+            self.inner.push(".");
+            // SAFETY: Since a UTF-8 string was just pushed, it is not possible
+            // for the buffer to end with a surrogate half.
+            unsafe { self.inner.extend_from_slice_unchecked(new) };
         }
 
         true
@@ -2769,7 +2773,8 @@ impl Path {
         };
 
         let mut new_path = PathBuf::with_capacity(new_capacity);
-        new_path.inner.extend_from_slice(slice_to_copy);
+        // SAFETY: The path is empty, so cannot have surrogate halves.
+        unsafe { new_path.inner.extend_from_slice_unchecked(slice_to_copy) };
         new_path.set_extension(extension);
         new_path
     }
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 76ce7bce81b..df6b9a6e563 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -168,8 +168,6 @@ use crate::num::NonZero;
 use crate::path::Path;
 use crate::sys::pipe::{AnonPipe, read2};
 use crate::sys::process as imp;
-#[stable(feature = "command_access", since = "1.57.0")]
-pub use crate::sys_common::process::CommandEnvs;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 use crate::{fmt, fs, str};
 
@@ -1073,7 +1071,7 @@ impl Command {
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn output(&mut self) -> io::Result<Output> {
-        let (status, stdout, stderr) = self.inner.output()?;
+        let (status, stdout, stderr) = imp::output(&mut self.inner)?;
         Ok(Output { status: ExitStatus(status), stdout, stderr })
     }
 
@@ -1174,7 +1172,7 @@ impl Command {
     /// ```
     #[stable(feature = "command_access", since = "1.57.0")]
     pub fn get_envs(&self) -> CommandEnvs<'_> {
-        self.inner.get_envs()
+        CommandEnvs { iter: self.inner.get_envs() }
     }
 
     /// Returns the working directory for the child process.
@@ -1264,6 +1262,48 @@ impl<'a> ExactSizeIterator for CommandArgs<'a> {
     }
 }
 
+/// An iterator over the command environment variables.
+///
+/// This struct is created by
+/// [`Command::get_envs`][crate::process::Command::get_envs]. See its
+/// documentation for more.
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "command_access", since = "1.57.0")]
+pub struct CommandEnvs<'a> {
+    iter: imp::CommandEnvs<'a>,
+}
+
+#[stable(feature = "command_access", since = "1.57.0")]
+impl<'a> Iterator for CommandEnvs<'a> {
+    type Item = (&'a OsStr, Option<&'a OsStr>);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next()
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+#[stable(feature = "command_access", since = "1.57.0")]
+impl<'a> ExactSizeIterator for CommandEnvs<'a> {
+    fn len(&self) -> usize {
+        self.iter.len()
+    }
+
+    fn is_empty(&self) -> bool {
+        self.iter.is_empty()
+    }
+}
+
+#[stable(feature = "command_access", since = "1.57.0")]
+impl<'a> fmt::Debug for CommandEnvs<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.iter.fmt(f)
+    }
+}
+
 /// The output of a finished process.
 ///
 /// This is returned in a Result by either the [`output`] method of a
diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs
index adb74bb6f3d..1c29c619edc 100644
--- a/library/std/src/sync/poison/mutex.rs
+++ b/library/std/src/sync/poison/mutex.rs
@@ -253,11 +253,11 @@ unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
 /// The data protected by the mutex can be accessed through this guard via its
 /// [`Deref`] and [`DerefMut`] implementations.
 ///
-/// This structure is created by the [`map`] and [`try_map`] methods on
+/// This structure is created by the [`map`] and [`filter_map`] methods on
 /// [`MutexGuard`].
 ///
 /// [`map`]: MutexGuard::map
-/// [`try_map`]: MutexGuard::try_map
+/// [`filter_map`]: MutexGuard::filter_map
 /// [`Condvar`]: crate::sync::Condvar
 #[must_use = "if unused the Mutex will immediately unlock"]
 #[must_not_suspend = "holding a MappedMutexGuard across suspend \
@@ -718,7 +718,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
         U: ?Sized,
     {
         // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
@@ -739,17 +739,16 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
     /// The `Mutex` is already locked, so this cannot fail.
     ///
     /// This is an associated function that needs to be used as
-    /// `MutexGuard::try_map(...)`. A method would interfere with methods of the
+    /// `MutexGuard::filter_map(...)`. A method would interfere with methods of the
     /// same name on the contents of the `MutexGuard` used through `Deref`.
-    #[doc(alias = "filter_map")]
     #[unstable(feature = "mapped_lock_guards", issue = "117108")]
-    pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
+    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
     where
         F: FnOnce(&mut T) -> Option<&mut U>,
         U: ?Sized,
     {
         // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         match f(unsafe { &mut *orig.lock.data.get() }) {
@@ -826,7 +825,7 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
         U: ?Sized,
     {
         // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
@@ -847,17 +846,16 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
     /// The `Mutex` is already locked, so this cannot fail.
     ///
     /// This is an associated function that needs to be used as
-    /// `MappedMutexGuard::try_map(...)`. A method would interfere with methods of the
+    /// `MappedMutexGuard::filter_map(...)`. A method would interfere with methods of the
     /// same name on the contents of the `MutexGuard` used through `Deref`.
-    #[doc(alias = "filter_map")]
     #[unstable(feature = "mapped_lock_guards", issue = "117108")]
-    pub fn try_map<U, F>(mut orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
+    pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
     where
         F: FnOnce(&mut T) -> Option<&mut U>,
         U: ?Sized,
     {
         // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         match f(unsafe { orig.data.as_mut() }) {
diff --git a/library/std/src/sync/poison/rwlock.rs b/library/std/src/sync/poison/rwlock.rs
index a2abd4f692e..6976c0a64e2 100644
--- a/library/std/src/sync/poison/rwlock.rs
+++ b/library/std/src/sync/poison/rwlock.rs
@@ -147,11 +147,11 @@ unsafe impl<T: ?Sized + Sync> Sync for RwLockWriteGuard<'_, T> {}
 /// RAII structure used to release the shared read access of a lock when
 /// dropped, which can point to a subfield of the protected data.
 ///
-/// This structure is created by the [`map`] and [`try_map`] methods
+/// This structure is created by the [`map`] and [`filter_map`] methods
 /// on [`RwLockReadGuard`].
 ///
 /// [`map`]: RwLockReadGuard::map
-/// [`try_map`]: RwLockReadGuard::try_map
+/// [`filter_map`]: RwLockReadGuard::filter_map
 #[must_use = "if unused the RwLock will immediately unlock"]
 #[must_not_suspend = "holding a MappedRwLockReadGuard across suspend \
                       points can cause deadlocks, delays, \
@@ -176,11 +176,11 @@ unsafe impl<T: ?Sized + Sync> Sync for MappedRwLockReadGuard<'_, T> {}
 /// RAII structure used to release the exclusive write access of a lock when
 /// dropped, which can point to a subfield of the protected data.
 ///
-/// This structure is created by the [`map`] and [`try_map`] methods
+/// This structure is created by the [`map`] and [`filter_map`] methods
 /// on [`RwLockWriteGuard`].
 ///
 /// [`map`]: RwLockWriteGuard::map
-/// [`try_map`]: RwLockWriteGuard::try_map
+/// [`filter_map`]: RwLockWriteGuard::filter_map
 #[must_use = "if unused the RwLock will immediately unlock"]
 #[must_not_suspend = "holding a MappedRwLockWriteGuard across suspend \
                       points can cause deadlocks, delays, \
@@ -788,7 +788,7 @@ impl<T: ?Sized> Deref for MappedRwLockReadGuard<'_, T> {
 
     fn deref(&self) -> &T {
         // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         unsafe { self.data.as_ref() }
     }
 }
@@ -799,7 +799,7 @@ impl<T: ?Sized> Deref for MappedRwLockWriteGuard<'_, T> {
 
     fn deref(&self) -> &T {
         // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         unsafe { self.data.as_ref() }
     }
 }
@@ -808,7 +808,7 @@ impl<T: ?Sized> Deref for MappedRwLockWriteGuard<'_, T> {
 impl<T: ?Sized> DerefMut for MappedRwLockWriteGuard<'_, T> {
     fn deref_mut(&mut self) -> &mut T {
         // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         unsafe { self.data.as_mut() }
     }
 }
@@ -838,7 +838,7 @@ impl<T: ?Sized> Drop for RwLockWriteGuard<'_, T> {
 impl<T: ?Sized> Drop for MappedRwLockReadGuard<'_, T> {
     fn drop(&mut self) {
         // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         unsafe {
             self.inner_lock.read_unlock();
         }
@@ -850,7 +850,7 @@ impl<T: ?Sized> Drop for MappedRwLockWriteGuard<'_, T> {
     fn drop(&mut self) {
         self.poison_flag.done(&self.poison);
         // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         unsafe {
             self.inner_lock.write_unlock();
         }
@@ -878,7 +878,7 @@ impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
         U: ?Sized,
     {
         // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
@@ -893,22 +893,21 @@ impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
     /// The `RwLock` is already locked for reading, so this cannot fail.
     ///
     /// This is an associated function that needs to be used as
-    /// `RwLockReadGuard::try_map(...)`. A method would interfere with methods
+    /// `RwLockReadGuard::filter_map(...)`. A method would interfere with methods
     /// of the same name on the contents of the `RwLockReadGuard` used through
     /// `Deref`.
     ///
     /// # Panics
     ///
     /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
-    #[doc(alias = "filter_map")]
     #[unstable(feature = "mapped_lock_guards", issue = "117108")]
-    pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
+    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
     where
         F: FnOnce(&T) -> Option<&U>,
         U: ?Sized,
     {
         // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         match f(unsafe { orig.data.as_ref() }) {
@@ -943,7 +942,7 @@ impl<'a, T: ?Sized> MappedRwLockReadGuard<'a, T> {
         U: ?Sized,
     {
         // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
@@ -958,22 +957,21 @@ impl<'a, T: ?Sized> MappedRwLockReadGuard<'a, T> {
     /// The `RwLock` is already locked for reading, so this cannot fail.
     ///
     /// This is an associated function that needs to be used as
-    /// `MappedRwLockReadGuard::try_map(...)`. A method would interfere with
+    /// `MappedRwLockReadGuard::filter_map(...)`. A method would interfere with
     /// methods of the same name on the contents of the `MappedRwLockReadGuard`
     /// used through `Deref`.
     ///
     /// # Panics
     ///
     /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
-    #[doc(alias = "filter_map")]
     #[unstable(feature = "mapped_lock_guards", issue = "117108")]
-    pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
+    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
     where
         F: FnOnce(&T) -> Option<&U>,
         U: ?Sized,
     {
         // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         match f(unsafe { orig.data.as_ref() }) {
@@ -1008,7 +1006,7 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
         U: ?Sized,
     {
         // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
@@ -1029,22 +1027,21 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
     /// The `RwLock` is already locked for writing, so this cannot fail.
     ///
     /// This is an associated function that needs to be used as
-    /// `RwLockWriteGuard::try_map(...)`. A method would interfere with methods
+    /// `RwLockWriteGuard::filter_map(...)`. A method would interfere with methods
     /// of the same name on the contents of the `RwLockWriteGuard` used through
     /// `Deref`.
     ///
     /// # Panics
     ///
     /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
-    #[doc(alias = "filter_map")]
     #[unstable(feature = "mapped_lock_guards", issue = "117108")]
-    pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
+    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
     where
         F: FnOnce(&mut T) -> Option<&mut U>,
         U: ?Sized,
     {
         // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         match f(unsafe { &mut *orig.lock.data.get() }) {
@@ -1147,7 +1144,7 @@ impl<'a, T: ?Sized> MappedRwLockWriteGuard<'a, T> {
         U: ?Sized,
     {
         // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
@@ -1168,22 +1165,21 @@ impl<'a, T: ?Sized> MappedRwLockWriteGuard<'a, T> {
     /// The `RwLock` is already locked for writing, so this cannot fail.
     ///
     /// This is an associated function that needs to be used as
-    /// `MappedRwLockWriteGuard::try_map(...)`. A method would interfere with
+    /// `MappedRwLockWriteGuard::filter_map(...)`. A method would interfere with
     /// methods of the same name on the contents of the `MappedRwLockWriteGuard`
     /// used through `Deref`.
     ///
     /// # Panics
     ///
     /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
-    #[doc(alias = "filter_map")]
     #[unstable(feature = "mapped_lock_guards", issue = "117108")]
-    pub fn try_map<U, F>(mut orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
+    pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
     where
         F: FnOnce(&mut T) -> Option<&mut U>,
         U: ?Sized,
     {
         // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
-        // was created, and have been upheld throughout `map` and/or `try_map`.
+        // was created, and have been upheld throughout `map` and/or `filter_map`.
         // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
         // passed to it. If the closure panics, the guard will be dropped.
         match f(unsafe { orig.data.as_mut() }) {
diff --git a/library/std/src/sys/args/common.rs b/library/std/src/sys/args/common.rs
index 43ac5e95923..e787105a05a 100644
--- a/library/std/src/sys/args/common.rs
+++ b/library/std/src/sys/args/common.rs
@@ -1,5 +1,7 @@
 use crate::ffi::OsString;
-use crate::{fmt, vec};
+use crate::num::NonZero;
+use crate::ops::Try;
+use crate::{array, fmt, vec};
 
 pub struct Args {
     iter: vec::IntoIter<OsString>,
@@ -9,6 +11,7 @@ impl !Send for Args {}
 impl !Sync for Args {}
 
 impl Args {
+    #[inline]
     pub(super) fn new(args: Vec<OsString>) -> Self {
         Args { iter: args.into_iter() }
     }
@@ -22,22 +25,77 @@ impl fmt::Debug for Args {
 
 impl Iterator for Args {
     type Item = OsString;
+
+    #[inline]
     fn next(&mut self) -> Option<OsString> {
         self.iter.next()
     }
+
+    #[inline]
+    fn next_chunk<const N: usize>(
+        &mut self,
+    ) -> Result<[OsString; N], array::IntoIter<OsString, N>> {
+        self.iter.next_chunk()
+    }
+
+    #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
-}
 
-impl ExactSizeIterator for Args {
-    fn len(&self) -> usize {
+    #[inline]
+    fn count(self) -> usize {
         self.iter.len()
     }
+
+    #[inline]
+    fn last(self) -> Option<OsString> {
+        self.iter.last()
+    }
+
+    #[inline]
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.iter.advance_by(n)
+    }
+
+    #[inline]
+    fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>,
+    {
+        self.iter.try_fold(init, f)
+    }
+
+    #[inline]
+    fn fold<B, F>(self, init: B, f: F) -> B
+    where
+        F: FnMut(B, Self::Item) -> B,
+    {
+        self.iter.fold(init, f)
+    }
 }
 
 impl DoubleEndedIterator for Args {
+    #[inline]
     fn next_back(&mut self) -> Option<OsString> {
         self.iter.next_back()
     }
+
+    #[inline]
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.iter.advance_back_by(n)
+    }
+}
+
+impl ExactSizeIterator for Args {
+    #[inline]
+    fn len(&self) -> usize {
+        self.iter.len()
+    }
+
+    #[inline]
+    fn is_empty(&self) -> bool {
+        self.iter.is_empty()
+    }
 }
diff --git a/library/std/src/sys/args/sgx.rs b/library/std/src/sys/args/sgx.rs
index 2a4bc76aefb..f800500c22a 100644
--- a/library/std/src/sys/args/sgx.rs
+++ b/library/std/src/sys/args/sgx.rs
@@ -1,6 +1,8 @@
 #![allow(fuzzy_provenance_casts)] // FIXME: this module systematically confuses pointers and integers
 
 use crate::ffi::OsString;
+use crate::num::NonZero;
+use crate::ops::Try;
 use crate::sync::atomic::{Atomic, AtomicUsize, Ordering};
 use crate::sys::os_str::Buf;
 use crate::sys::pal::abi::usercalls::alloc;
@@ -28,35 +30,81 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
 
 pub fn args() -> Args {
     let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() };
-    if let Some(args) = args { Args(args.iter()) } else { Args([].iter()) }
+    let slice = args.map(|args| args.as_slice()).unwrap_or(&[]);
+    Args { iter: slice.iter() }
 }
 
-pub struct Args(slice::Iter<'static, OsString>);
+pub struct Args {
+    iter: slice::Iter<'static, OsString>,
+}
 
 impl fmt::Debug for Args {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0.as_slice().fmt(f)
+        self.iter.as_slice().fmt(f)
     }
 }
 
 impl Iterator for Args {
     type Item = OsString;
+
     fn next(&mut self) -> Option<OsString> {
-        self.0.next().cloned()
+        self.iter.next().cloned()
     }
+
+    #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        self.0.size_hint()
+        self.iter.size_hint()
     }
-}
 
-impl ExactSizeIterator for Args {
-    fn len(&self) -> usize {
-        self.0.len()
+    #[inline]
+    fn count(self) -> usize {
+        self.iter.len()
+    }
+
+    fn last(self) -> Option<OsString> {
+        self.iter.last().cloned()
+    }
+
+    #[inline]
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.iter.advance_by(n)
+    }
+
+    fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>,
+    {
+        self.iter.by_ref().cloned().try_fold(init, f)
+    }
+
+    fn fold<B, F>(self, init: B, f: F) -> B
+    where
+        F: FnMut(B, Self::Item) -> B,
+    {
+        self.iter.cloned().fold(init, f)
     }
 }
 
 impl DoubleEndedIterator for Args {
     fn next_back(&mut self) -> Option<OsString> {
-        self.0.next_back().cloned()
+        self.iter.next_back().cloned()
+    }
+
+    #[inline]
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.iter.advance_back_by(n)
+    }
+}
+
+impl ExactSizeIterator for Args {
+    #[inline]
+    fn len(&self) -> usize {
+        self.iter.len()
+    }
+
+    #[inline]
+    fn is_empty(&self) -> bool {
+        self.iter.is_empty()
     }
 }
diff --git a/library/std/src/sys/args/unsupported.rs b/library/std/src/sys/args/unsupported.rs
index a2d75a61976..ecffc6d2641 100644
--- a/library/std/src/sys/args/unsupported.rs
+++ b/library/std/src/sys/args/unsupported.rs
@@ -15,22 +15,28 @@ impl fmt::Debug for Args {
 
 impl Iterator for Args {
     type Item = OsString;
+
+    #[inline]
     fn next(&mut self) -> Option<OsString> {
         None
     }
+
+    #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         (0, Some(0))
     }
 }
 
-impl ExactSizeIterator for Args {
-    fn len(&self) -> usize {
-        0
-    }
-}
-
 impl DoubleEndedIterator for Args {
+    #[inline]
     fn next_back(&mut self) -> Option<OsString> {
         None
     }
 }
+
+impl ExactSizeIterator for Args {
+    #[inline]
+    fn len(&self) -> usize {
+        0
+    }
+}
diff --git a/library/std/src/sys/exit_guard.rs b/library/std/src/sys/exit_guard.rs
index 5a090f50666..bd70d178244 100644
--- a/library/std/src/sys/exit_guard.rs
+++ b/library/std/src/sys/exit_guard.rs
@@ -1,14 +1,5 @@
 cfg_if::cfg_if! {
     if #[cfg(target_os = "linux")] {
-        /// pthread_t is a pointer on some platforms,
-        /// so we wrap it in this to impl Send + Sync.
-        #[derive(Clone, Copy)]
-        #[repr(transparent)]
-        struct PThread(libc::pthread_t);
-        // Safety: pthread_t is safe to send between threads
-        unsafe impl Send for PThread {}
-        // Safety: pthread_t is safe to share between threads
-        unsafe impl Sync for PThread {}
         /// Mitigation for <https://github.com/rust-lang/rust/issues/126600>
         ///
         /// On glibc, `libc::exit` has been observed to not always be thread-safe.
@@ -30,28 +21,34 @@ cfg_if::cfg_if! {
         ///   (waiting for the process to exit).
         #[cfg_attr(any(test, doctest), allow(dead_code))]
         pub(crate) fn unique_thread_exit() {
-            let this_thread_id = unsafe { libc::pthread_self() };
-            use crate::sync::{Mutex, PoisonError};
-            static EXITING_THREAD_ID: Mutex<Option<PThread>> = Mutex::new(None);
-            let mut exiting_thread_id =
-                EXITING_THREAD_ID.lock().unwrap_or_else(PoisonError::into_inner);
-            match *exiting_thread_id {
-                None => {
+            use crate::ffi::c_int;
+            use crate::ptr;
+            use crate::sync::atomic::AtomicPtr;
+            use crate::sync::atomic::Ordering::{Acquire, Relaxed};
+
+            static EXITING_THREAD_ID: AtomicPtr<c_int> = AtomicPtr::new(ptr::null_mut());
+
+            // We use the address of `errno` as a cheap and safe way to identify
+            // threads. As the C standard mandates that `errno` must have thread
+            // storage duration, we can rely on its address not changing over the
+            // lifetime of the thread. Additionally, accesses to `errno` are
+            // async-signal-safe, so this function is available in all imaginable
+            // circumstances.
+            let this_thread_id = crate::sys::os::errno_location();
+            match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) {
+                Ok(_) => {
                     // This is the first thread to call `unique_thread_exit`,
-                    // and this is the first time it is called.
-                    // Set EXITING_THREAD_ID to this thread's ID and return.
-                    *exiting_thread_id = Some(PThread(this_thread_id));
-                },
-                Some(exiting_thread_id) if exiting_thread_id.0 == this_thread_id => {
+                    // and this is the first time it is called. Continue exiting.
+                }
+                Err(exiting_thread_id) if exiting_thread_id == this_thread_id => {
                     // This is the first thread to call `unique_thread_exit`,
                     // but this is the second time it is called.
                     // Abort the process.
                     core::panicking::panic_nounwind("std::process::exit called re-entrantly")
                 }
-                Some(_) => {
+                Err(_) => {
                     // This is not the first thread to call `unique_thread_exit`.
                     // Pause until the process exits.
-                    drop(exiting_thread_id);
                     loop {
                         // Safety: libc::pause is safe to call.
                         unsafe { libc::pause(); }
diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs
index 99690abe8ed..a9774bef9e3 100644
--- a/library/std/src/sys/fs/hermit.rs
+++ b/library/std/src/sys/fs/hermit.rs
@@ -1,4 +1,5 @@
 use crate::ffi::{CStr, OsStr, OsString, c_char};
+use crate::fs::TryLockError;
 use crate::io::{self, BorrowedCursor, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom};
 use crate::os::hermit::ffi::OsStringExt;
 use crate::os::hermit::hermit_abi::{
@@ -12,7 +13,7 @@ use crate::sys::common::small_c_string::run_path_with_cstr;
 use crate::sys::fd::FileDesc;
 pub use crate::sys::fs::common::{copy, exists};
 use crate::sys::time::SystemTime;
-use crate::sys::{cvt, unsupported};
+use crate::sys::{cvt, unsupported, unsupported_err};
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 use crate::{fmt, mem};
 
@@ -366,12 +367,12 @@ impl File {
         unsupported()
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
     pub fn unlock(&self) -> io::Result<()> {
diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs
index 39de933b724..3bfb39bac95 100644
--- a/library/std/src/sys/fs/solid.rs
+++ b/library/std/src/sys/fs/solid.rs
@@ -2,6 +2,7 @@
 
 use crate::ffi::{CStr, CString, OsStr, OsString};
 use crate::fmt;
+use crate::fs::TryLockError;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem::MaybeUninit;
 use crate::os::raw::{c_int, c_short};
@@ -11,7 +12,7 @@ use crate::sync::Arc;
 pub use crate::sys::fs::common::exists;
 use crate::sys::pal::{abi, error};
 use crate::sys::time::SystemTime;
-use crate::sys::unsupported;
+use crate::sys::{unsupported, unsupported_err};
 use crate::sys_common::ignore_notfound;
 
 type CIntNotMinusOne = core::num::niche_types::NotAllOnes<c_int>;
@@ -352,12 +353,12 @@ impl File {
         unsupported()
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
     pub fn unlock(&self) -> io::Result<()> {
diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs
index d6ae86bd3d2..416c90b98b6 100644
--- a/library/std/src/sys/fs/uefi.rs
+++ b/library/std/src/sys/fs/uefi.rs
@@ -2,6 +2,7 @@ use r_efi::protocols::file;
 
 use crate::ffi::OsString;
 use crate::fmt;
+use crate::fs::TryLockError;
 use crate::hash::Hash;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
 use crate::path::{Path, PathBuf};
@@ -227,11 +228,11 @@ impl File {
         self.0
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
         self.0
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
         self.0
     }
 
diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs
index 5af59a2a914..863358596c1 100644
--- a/library/std/src/sys/fs/unix.rs
+++ b/library/std/src/sys/fs/unix.rs
@@ -75,6 +75,7 @@ use libc::{dirent64, fstat64, ftruncate64, lseek64, lstat64, off64_t, open64, st
 
 use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt::{self, Write as _};
+use crate::fs::TryLockError;
 use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd};
 use crate::os::unix::prelude::*;
@@ -1310,15 +1311,17 @@ impl File {
         target_os = "netbsd",
         target_vendor = "apple",
     ))]
-    pub fn try_lock(&self) -> io::Result<bool> {
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
         let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) });
-        if let Err(ref err) = result {
+        if let Err(err) = result {
             if err.kind() == io::ErrorKind::WouldBlock {
-                return Ok(false);
+                Err(TryLockError::WouldBlock)
+            } else {
+                Err(TryLockError::Error(err))
             }
+        } else {
+            Ok(())
         }
-        result?;
-        return Ok(true);
     }
 
     #[cfg(not(any(
@@ -1328,8 +1331,11 @@ impl File {
         target_os = "netbsd",
         target_vendor = "apple",
     )))]
-    pub fn try_lock(&self) -> io::Result<bool> {
-        Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock() not supported"))
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(io::const_error!(
+            io::ErrorKind::Unsupported,
+            "try_lock() not supported"
+        )))
     }
 
     #[cfg(any(
@@ -1339,15 +1345,17 @@ impl File {
         target_os = "netbsd",
         target_vendor = "apple",
     ))]
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
         let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH | libc::LOCK_NB) });
-        if let Err(ref err) = result {
+        if let Err(err) = result {
             if err.kind() == io::ErrorKind::WouldBlock {
-                return Ok(false);
+                Err(TryLockError::WouldBlock)
+            } else {
+                Err(TryLockError::Error(err))
             }
+        } else {
+            Ok(())
         }
-        result?;
-        return Ok(true);
     }
 
     #[cfg(not(any(
@@ -1357,8 +1365,11 @@ impl File {
         target_os = "netbsd",
         target_vendor = "apple",
     )))]
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
-        Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported"))
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(io::const_error!(
+            io::ErrorKind::Unsupported,
+            "try_lock_shared() not supported"
+        )))
     }
 
     #[cfg(any(
diff --git a/library/std/src/sys/fs/unsupported.rs b/library/std/src/sys/fs/unsupported.rs
index 45e93deffa3..0ff9533c047 100644
--- a/library/std/src/sys/fs/unsupported.rs
+++ b/library/std/src/sys/fs/unsupported.rs
@@ -1,5 +1,6 @@
 use crate::ffi::OsString;
 use crate::fmt;
+use crate::fs::TryLockError;
 use crate::hash::{Hash, Hasher};
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
 use crate::path::{Path, PathBuf};
@@ -206,11 +207,11 @@ impl File {
         self.0
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
         self.0
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
         self.0
     }
 
diff --git a/library/std/src/sys/fs/wasi.rs b/library/std/src/sys/fs/wasi.rs
index 773040571bc..ebfc7377a2e 100644
--- a/library/std/src/sys/fs/wasi.rs
+++ b/library/std/src/sys/fs/wasi.rs
@@ -1,4 +1,5 @@
 use crate::ffi::{CStr, OsStr, OsString};
+use crate::fs::TryLockError;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem::{self, ManuallyDrop};
 use crate::os::raw::c_int;
@@ -10,7 +11,7 @@ use crate::sys::common::small_c_string::run_path_with_cstr;
 use crate::sys::fd::WasiFd;
 pub use crate::sys::fs::common::exists;
 use crate::sys::time::SystemTime;
-use crate::sys::unsupported;
+use crate::sys::{unsupported, unsupported_err};
 use crate::sys_common::{AsInner, FromInner, IntoInner, ignore_notfound};
 use crate::{fmt, iter, ptr};
 
@@ -461,12 +462,12 @@ impl File {
         unsupported()
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
     pub fn unlock(&self) -> io::Result<()> {
diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs
index 9215f937567..9039fd00f5d 100644
--- a/library/std/src/sys/fs/windows.rs
+++ b/library/std/src/sys/fs/windows.rs
@@ -3,6 +3,7 @@
 use crate::alloc::{Layout, alloc, dealloc};
 use crate::borrow::Cow;
 use crate::ffi::{OsStr, OsString, c_void};
+use crate::fs::TryLockError;
 use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem::{self, MaybeUninit, offset_of};
 use crate::os::windows::io::{AsHandle, BorrowedHandle};
@@ -399,7 +400,7 @@ impl File {
         self.acquire_lock(0)
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
         let result = cvt(unsafe {
             let mut overlapped = mem::zeroed();
             c::LockFileEx(
@@ -413,18 +414,18 @@ impl File {
         });
 
         match result {
-            Ok(_) => Ok(true),
+            Ok(_) => Ok(()),
             Err(err)
                 if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32)
                     || err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) =>
             {
-                Ok(false)
+                Err(TryLockError::WouldBlock)
             }
-            Err(err) => Err(err),
+            Err(err) => Err(TryLockError::Error(err)),
         }
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
         let result = cvt(unsafe {
             let mut overlapped = mem::zeroed();
             c::LockFileEx(
@@ -438,14 +439,14 @@ impl File {
         });
 
         match result {
-            Ok(_) => Ok(true),
+            Ok(_) => Ok(()),
             Err(err)
                 if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32)
                     || err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) =>
             {
-                Ok(false)
+                Err(TryLockError::WouldBlock)
             }
-            Err(err) => Err(err),
+            Err(err) => Err(TryLockError::Error(err)),
         }
     }
 
diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs
index dfff2d3e5d3..4a8808c9230 100644
--- a/library/std/src/sys/os_str/bytes.rs
+++ b/library/std/src/sys/os_str/bytes.rs
@@ -216,19 +216,26 @@ impl Buf {
         self.as_slice().into_rc()
     }
 
-    /// Provides plumbing to core `Vec::truncate`.
-    /// More well behaving alternative to allowing outer types
-    /// full mutable access to the core `Vec`.
-    #[inline]
-    pub(crate) fn truncate(&mut self, len: usize) {
+    /// Provides plumbing to `Vec::truncate` without giving full mutable access
+    /// to the `Vec`.
+    ///
+    /// # Safety
+    ///
+    /// The length must be at an `OsStr` boundary, according to
+    /// `Slice::check_public_boundary`.
+    #[inline]
+    pub unsafe fn truncate_unchecked(&mut self, len: usize) {
         self.inner.truncate(len);
     }
 
-    /// Provides plumbing to core `Vec::extend_from_slice`.
-    /// More well behaving alternative to allowing outer types
-    /// full mutable access to the core `Vec`.
+    /// Provides plumbing to `Vec::extend_from_slice` without giving full
+    /// mutable access to the `Vec`.
+    ///
+    /// # Safety
+    ///
+    /// This encoding has no safety requirements.
     #[inline]
-    pub(crate) fn extend_from_slice(&mut self, other: &[u8]) {
+    pub unsafe fn extend_from_slice_unchecked(&mut self, other: &[u8]) {
         self.inner.extend_from_slice(other);
     }
 }
diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs
index a32f5d40f6a..5174ea65d0c 100644
--- a/library/std/src/sys/os_str/wtf8.rs
+++ b/library/std/src/sys/os_str/wtf8.rs
@@ -195,19 +195,31 @@ impl Buf {
         self.as_slice().into_rc()
     }
 
-    /// Provides plumbing to core `Vec::truncate`.
-    /// More well behaving alternative to allowing outer types
-    /// full mutable access to the core `Vec`.
-    #[inline]
-    pub(crate) fn truncate(&mut self, len: usize) {
+    /// Provides plumbing to `Vec::truncate` without giving full mutable access
+    /// to the `Vec`.
+    ///
+    /// # Safety
+    ///
+    /// The length must be at an `OsStr` boundary, according to
+    /// `Slice::check_public_boundary`.
+    #[inline]
+    pub unsafe fn truncate_unchecked(&mut self, len: usize) {
         self.inner.truncate(len);
     }
 
-    /// Provides plumbing to core `Vec::extend_from_slice`.
-    /// More well behaving alternative to allowing outer types
-    /// full mutable access to the core `Vec`.
+    /// Provides plumbing to `Vec::extend_from_slice` without giving full
+    /// mutable access to the `Vec`.
+    ///
+    /// # Safety
+    ///
+    /// The slice must be valid for the platform encoding (as described in
+    /// [`Slice::from_encoded_bytes_unchecked`]).
+    ///
+    /// This bypasses the WTF-8 surrogate joining, so `self` must not end with a
+    /// leading surrogate half and `other` must not start with with a trailing
+    /// surrogate half.
     #[inline]
-    pub(crate) fn extend_from_slice(&mut self, other: &[u8]) {
+    pub unsafe fn extend_from_slice_unchecked(&mut self, other: &[u8]) {
         self.inner.extend_from_slice(other);
     }
 }
diff --git a/library/std/src/sys/pal/unix/fuchsia.rs b/library/std/src/sys/pal/unix/fuchsia.rs
index 7932bd26d76..c118dee6247 100644
--- a/library/std/src/sys/pal/unix/fuchsia.rs
+++ b/library/std/src/sys/pal/unix/fuchsia.rs
@@ -1,48 +1,35 @@
-#![allow(non_camel_case_types, unused)]
+#![expect(non_camel_case_types)]
 
-use libc::{c_int, c_void, size_t};
+use libc::size_t;
 
+use crate::ffi::{c_char, c_int, c_void};
 use crate::io;
-use crate::mem::MaybeUninit;
-use crate::os::raw::c_char;
 
-pub type zx_handle_t = u32;
-pub type zx_vaddr_t = usize;
-pub type zx_rights_t = u32;
-pub type zx_status_t = i32;
-
-pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
+//////////
+// Time //
+//////////
 
 pub type zx_time_t = i64;
-pub const ZX_TIME_INFINITE: zx_time_t = i64::MAX;
-
-pub type zx_signals_t = u32;
-
-pub const ZX_OBJECT_SIGNAL_3: zx_signals_t = 1 << 3;
 
-pub const ZX_TASK_TERMINATED: zx_signals_t = ZX_OBJECT_SIGNAL_3;
+pub const ZX_TIME_INFINITE: zx_time_t = i64::MAX;
 
-pub const ZX_RIGHT_SAME_RIGHTS: zx_rights_t = 1 << 31;
+unsafe extern "C" {
+    pub safe fn zx_clock_get_monotonic() -> zx_time_t;
+}
 
-// The upper four bits gives the minor version.
-pub type zx_object_info_topic_t = u32;
+/////////////
+// Handles //
+/////////////
 
-pub const ZX_INFO_PROCESS: zx_object_info_topic_t = 3 | (1 << 28);
+pub type zx_handle_t = u32;
 
-pub type zx_info_process_flags_t = u32;
+pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
 
-pub fn zx_cvt<T>(t: T) -> io::Result<T>
-where
-    T: TryInto<zx_status_t> + Copy,
-{
-    if let Ok(status) = TryInto::try_into(t) {
-        if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) }
-    } else {
-        Err(io::Error::last_os_error())
-    }
+unsafe extern "C" {
+    pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t;
 }
 
-// Safe wrapper around zx_handle_t
+/// A safe wrapper around `zx_handle_t`.
 pub struct Handle {
     raw: zx_handle_t,
 }
@@ -65,6 +52,66 @@ impl Drop for Handle {
     }
 }
 
+///////////
+// Futex //
+///////////
+
+pub type zx_futex_t = crate::sync::atomic::Atomic<u32>;
+
+unsafe extern "C" {
+    pub fn zx_object_wait_one(
+        handle: zx_handle_t,
+        signals: zx_signals_t,
+        timeout: zx_time_t,
+        pending: *mut zx_signals_t,
+    ) -> zx_status_t;
+
+    pub fn zx_futex_wait(
+        value_ptr: *const zx_futex_t,
+        current_value: zx_futex_t,
+        new_futex_owner: zx_handle_t,
+        deadline: zx_time_t,
+    ) -> zx_status_t;
+    pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
+    pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t;
+    pub safe fn zx_thread_self() -> zx_handle_t;
+}
+
+////////////////
+// Properties //
+////////////////
+
+pub const ZX_PROP_NAME: u32 = 3;
+
+unsafe extern "C" {
+    pub fn zx_object_set_property(
+        handle: zx_handle_t,
+        property: u32,
+        value: *const libc::c_void,
+        value_size: libc::size_t,
+    ) -> zx_status_t;
+}
+
+/////////////
+// Signals //
+/////////////
+
+pub type zx_signals_t = u32;
+
+pub const ZX_OBJECT_SIGNAL_3: zx_signals_t = 1 << 3;
+pub const ZX_TASK_TERMINATED: zx_signals_t = ZX_OBJECT_SIGNAL_3;
+
+/////////////////
+// Object info //
+/////////////////
+
+// The upper four bits gives the minor version.
+pub type zx_object_info_topic_t = u32;
+
+pub const ZX_INFO_PROCESS: zx_object_info_topic_t = 3 | (1 << 28);
+
+pub type zx_info_process_flags_t = u32;
+
 // Returned for topic ZX_INFO_PROCESS
 #[derive(Default)]
 #[repr(C)]
@@ -76,25 +123,6 @@ pub struct zx_info_process_t {
 }
 
 unsafe extern "C" {
-    pub fn zx_job_default() -> zx_handle_t;
-
-    pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t;
-
-    pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t;
-
-    pub fn zx_handle_duplicate(
-        handle: zx_handle_t,
-        rights: zx_rights_t,
-        out: *const zx_handle_t,
-    ) -> zx_handle_t;
-
-    pub fn zx_object_wait_one(
-        handle: zx_handle_t,
-        signals: zx_signals_t,
-        timeout: zx_time_t,
-        pending: *mut zx_signals_t,
-    ) -> zx_status_t;
-
     pub fn zx_object_get_info(
         handle: zx_handle_t,
         topic: u32,
@@ -105,6 +133,10 @@ unsafe extern "C" {
     ) -> zx_status_t;
 }
 
+///////////////
+// Processes //
+///////////////
+
 #[derive(Default)]
 #[repr(C)]
 pub struct fdio_spawn_action_t {
@@ -130,6 +162,8 @@ unsafe extern "C" {
 
     pub fn fdio_fd_clone(fd: c_int, out_handle: *mut zx_handle_t) -> zx_status_t;
     pub fn fdio_fd_create(handle: zx_handle_t, fd: *mut c_int) -> zx_status_t;
+
+    pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t;
 }
 
 // fdio_spawn_etc flags
@@ -137,173 +171,34 @@ unsafe extern "C" {
 pub const FDIO_SPAWN_CLONE_JOB: u32 = 0x0001;
 pub const FDIO_SPAWN_CLONE_LDSVC: u32 = 0x0002;
 pub const FDIO_SPAWN_CLONE_NAMESPACE: u32 = 0x0004;
-pub const FDIO_SPAWN_CLONE_STDIO: u32 = 0x0008;
 pub const FDIO_SPAWN_CLONE_ENVIRON: u32 = 0x0010;
 pub const FDIO_SPAWN_CLONE_UTC_CLOCK: u32 = 0x0020;
-pub const FDIO_SPAWN_CLONE_ALL: u32 = 0xFFFF;
 
 // fdio_spawn_etc actions
 
-pub const FDIO_SPAWN_ACTION_CLONE_FD: u32 = 0x0001;
 pub const FDIO_SPAWN_ACTION_TRANSFER_FD: u32 = 0x0002;
 
-// Errors
-
-#[allow(unused)]
-pub const ERR_INTERNAL: zx_status_t = -1;
-
-// ERR_NOT_SUPPORTED: The operation is not implemented, supported,
-// or enabled.
-#[allow(unused)]
-pub const ERR_NOT_SUPPORTED: zx_status_t = -2;
-
-// ERR_NO_RESOURCES: The system was not able to allocate some resource
-// needed for the operation.
-#[allow(unused)]
-pub const ERR_NO_RESOURCES: zx_status_t = -3;
-
-// ERR_NO_MEMORY: The system was not able to allocate memory needed
-// for the operation.
-#[allow(unused)]
-pub const ERR_NO_MEMORY: zx_status_t = -4;
-
-// ERR_CALL_FAILED: The second phase of zx_channel_call(; did not complete
-// successfully.
-#[allow(unused)]
-pub const ERR_CALL_FAILED: zx_status_t = -5;
-
-// ERR_INTERRUPTED_RETRY: The system call was interrupted, but should be
-// retried.  This should not be seen outside of the VDSO.
-#[allow(unused)]
-pub const ERR_INTERRUPTED_RETRY: zx_status_t = -6;
-
-// ======= Parameter errors =======
-// ERR_INVALID_ARGS: an argument is invalid, ex. null pointer
-#[allow(unused)]
-pub const ERR_INVALID_ARGS: zx_status_t = -10;
-
-// ERR_BAD_HANDLE: A specified handle value does not refer to a handle.
-#[allow(unused)]
-pub const ERR_BAD_HANDLE: zx_status_t = -11;
-
-// ERR_WRONG_TYPE: The subject of the operation is the wrong type to
-// perform the operation.
-// Example: Attempting a message_read on a thread handle.
-#[allow(unused)]
-pub const ERR_WRONG_TYPE: zx_status_t = -12;
-
-// ERR_BAD_SYSCALL: The specified syscall number is invalid.
-#[allow(unused)]
-pub const ERR_BAD_SYSCALL: zx_status_t = -13;
-
-// ERR_OUT_OF_RANGE: An argument is outside the valid range for this
-// operation.
-#[allow(unused)]
-pub const ERR_OUT_OF_RANGE: zx_status_t = -14;
-
-// ERR_BUFFER_TOO_SMALL: A caller provided buffer is too small for
-// this operation.
-#[allow(unused)]
-pub const ERR_BUFFER_TOO_SMALL: zx_status_t = -15;
-
-// ======= Precondition or state errors =======
-// ERR_BAD_STATE: operation failed because the current state of the
-// object does not allow it, or a precondition of the operation is
-// not satisfied
-#[allow(unused)]
-pub const ERR_BAD_STATE: zx_status_t = -20;
-
-// ERR_TIMED_OUT: The time limit for the operation elapsed before
-// the operation completed.
-#[allow(unused)]
-pub const ERR_TIMED_OUT: zx_status_t = -21;
-
-// ERR_SHOULD_WAIT: The operation cannot be performed currently but
-// potentially could succeed if the caller waits for a prerequisite
-// to be satisfied, for example waiting for a handle to be readable
-// or writable.
-// Example: Attempting to read from a message pipe that has no
-// messages waiting but has an open remote will return ERR_SHOULD_WAIT.
-// Attempting to read from a message pipe that has no messages waiting
-// and has a closed remote end will return ERR_REMOTE_CLOSED.
-#[allow(unused)]
-pub const ERR_SHOULD_WAIT: zx_status_t = -22;
-
-// ERR_CANCELED: The in-progress operation (e.g., a wait) has been
-// // canceled.
-#[allow(unused)]
-pub const ERR_CANCELED: zx_status_t = -23;
-
-// ERR_PEER_CLOSED: The operation failed because the remote end
-// of the subject of the operation was closed.
-#[allow(unused)]
-pub const ERR_PEER_CLOSED: zx_status_t = -24;
-
-// ERR_NOT_FOUND: The requested entity is not found.
-#[allow(unused)]
-pub const ERR_NOT_FOUND: zx_status_t = -25;
-
-// ERR_ALREADY_EXISTS: An object with the specified identifier
-// already exists.
-// Example: Attempting to create a file when a file already exists
-// with that name.
-#[allow(unused)]
-pub const ERR_ALREADY_EXISTS: zx_status_t = -26;
-
-// ERR_ALREADY_BOUND: The operation failed because the named entity
-// is already owned or controlled by another entity. The operation
-// could succeed later if the current owner releases the entity.
-#[allow(unused)]
-pub const ERR_ALREADY_BOUND: zx_status_t = -27;
-
-// ERR_UNAVAILABLE: The subject of the operation is currently unable
-// to perform the operation.
-// Note: This is used when there's no direct way for the caller to
-// observe when the subject will be able to perform the operation
-// and should thus retry.
-#[allow(unused)]
-pub const ERR_UNAVAILABLE: zx_status_t = -28;
-
-// ======= Permission check errors =======
-// ERR_ACCESS_DENIED: The caller did not have permission to perform
-// the specified operation.
-#[allow(unused)]
-pub const ERR_ACCESS_DENIED: zx_status_t = -30;
-
-// ======= Input-output errors =======
-// ERR_IO: Otherwise unspecified error occurred during I/O.
-#[allow(unused)]
-pub const ERR_IO: zx_status_t = -40;
-
-// ERR_REFUSED: The entity the I/O operation is being performed on
-// rejected the operation.
-// Example: an I2C device NAK'ing a transaction or a disk controller
-// rejecting an invalid command.
-#[allow(unused)]
-pub const ERR_IO_REFUSED: zx_status_t = -41;
-
-// ERR_IO_DATA_INTEGRITY: The data in the operation failed an integrity
-// check and is possibly corrupted.
-// Example: CRC or Parity error.
-#[allow(unused)]
-pub const ERR_IO_DATA_INTEGRITY: zx_status_t = -42;
-
-// ERR_IO_DATA_LOSS: The data in the operation is currently unavailable
-// and may be permanently lost.
-// Example: A disk block is irrecoverably damaged.
-#[allow(unused)]
-pub const ERR_IO_DATA_LOSS: zx_status_t = -43;
-
-// Filesystem specific errors
-#[allow(unused)]
-pub const ERR_BAD_PATH: zx_status_t = -50;
-#[allow(unused)]
-pub const ERR_NOT_DIR: zx_status_t = -51;
-#[allow(unused)]
-pub const ERR_NOT_FILE: zx_status_t = -52;
-// ERR_FILE_BIG: A file exceeds a filesystem-specific size limit.
-#[allow(unused)]
-pub const ERR_FILE_BIG: zx_status_t = -53;
-// ERR_NO_SPACE: Filesystem or device space is exhausted.
-#[allow(unused)]
-pub const ERR_NO_SPACE: zx_status_t = -54;
+////////////
+// Errors //
+////////////
+
+pub type zx_status_t = i32;
+
+pub const ZX_OK: zx_status_t = 0;
+pub const ZX_ERR_NOT_SUPPORTED: zx_status_t = -2;
+pub const ZX_ERR_INVALID_ARGS: zx_status_t = -10;
+pub const ZX_ERR_BAD_HANDLE: zx_status_t = -11;
+pub const ZX_ERR_WRONG_TYPE: zx_status_t = -12;
+pub const ZX_ERR_BAD_STATE: zx_status_t = -20;
+pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
+
+pub fn zx_cvt<T>(t: T) -> io::Result<T>
+where
+    T: TryInto<zx_status_t> + Copy,
+{
+    if let Ok(status) = TryInto::try_into(t) {
+        if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) }
+    } else {
+        Err(io::Error::last_os_error())
+    }
+}
diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs
index 8d89163c42c..c23278bdf5e 100644
--- a/library/std/src/sys/pal/unix/futex.rs
+++ b/library/std/src/sys/pal/unix/futex.rs
@@ -255,66 +255,28 @@ pub fn futex_wake_all(futex: &Atomic<u32>) {
 }
 
 #[cfg(target_os = "fuchsia")]
-pub mod zircon {
-    pub type zx_futex_t = crate::sync::atomic::Atomic<u32>;
-    pub type zx_handle_t = u32;
-    pub type zx_status_t = i32;
-    pub type zx_time_t = i64;
-
-    pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
-
-    pub const ZX_TIME_INFINITE: zx_time_t = zx_time_t::MAX;
-
-    pub const ZX_OK: zx_status_t = 0;
-    pub const ZX_ERR_INVALID_ARGS: zx_status_t = -10;
-    pub const ZX_ERR_BAD_HANDLE: zx_status_t = -11;
-    pub const ZX_ERR_WRONG_TYPE: zx_status_t = -12;
-    pub const ZX_ERR_BAD_STATE: zx_status_t = -20;
-    pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
-
-    unsafe extern "C" {
-        pub fn zx_clock_get_monotonic() -> zx_time_t;
-        pub fn zx_futex_wait(
-            value_ptr: *const zx_futex_t,
-            current_value: zx_futex_t,
-            new_futex_owner: zx_handle_t,
-            deadline: zx_time_t,
-        ) -> zx_status_t;
-        pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
-        pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t;
-        pub fn zx_thread_self() -> zx_handle_t;
-    }
-}
-
-#[cfg(target_os = "fuchsia")]
 pub fn futex_wait(futex: &Atomic<u32>, expected: u32, timeout: Option<Duration>) -> bool {
+    use super::fuchsia::*;
+
     // Sleep forever if the timeout is longer than fits in a i64.
     let deadline = timeout
-        .and_then(|d| {
-            i64::try_from(d.as_nanos())
-                .ok()?
-                .checked_add(unsafe { zircon::zx_clock_get_monotonic() })
-        })
-        .unwrap_or(zircon::ZX_TIME_INFINITE);
+        .and_then(|d| i64::try_from(d.as_nanos()).ok()?.checked_add(zx_clock_get_monotonic()))
+        .unwrap_or(ZX_TIME_INFINITE);
 
     unsafe {
-        zircon::zx_futex_wait(
-            futex,
-            core::sync::atomic::AtomicU32::new(expected),
-            zircon::ZX_HANDLE_INVALID,
-            deadline,
-        ) != zircon::ZX_ERR_TIMED_OUT
+        zx_futex_wait(futex, zx_futex_t::new(expected), ZX_HANDLE_INVALID, deadline)
+            != ZX_ERR_TIMED_OUT
     }
 }
 
 // Fuchsia doesn't tell us how many threads are woken up, so this always returns false.
 #[cfg(target_os = "fuchsia")]
 pub fn futex_wake(futex: &Atomic<u32>) -> bool {
-    unsafe { zircon::zx_futex_wake(futex, 1) };
+    unsafe { super::fuchsia::zx_futex_wake(futex, 1) };
     false
 }
 
 #[cfg(target_os = "fuchsia")]
 pub fn futex_wake_all(futex: &Atomic<u32>) {
-    unsafe { zircon::zx_futex_wake(futex, u32::MAX) };
+    unsafe { super::fuchsia::zx_futex_wake(futex, u32::MAX) };
 }
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index 4883303b88e..48609030aed 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -56,7 +56,7 @@ unsafe extern "C" {
     #[cfg_attr(target_os = "aix", link_name = "_Errno")]
     // SAFETY: this will always return the same pointer on a given thread.
     #[unsafe(ffi_const)]
-    fn errno_location() -> *mut c_int;
+    pub safe fn errno_location() -> *mut c_int;
 }
 
 /// Returns the platform-specific value of errno
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 4cdc2eaf0e5..afda7c65e10 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -22,23 +22,6 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 256 * 1024;
 #[cfg(any(target_os = "espidf", target_os = "nuttx"))]
 pub const DEFAULT_MIN_STACK_SIZE: usize = 0; // 0 indicates that the stack size configured in the ESP-IDF/NuttX menuconfig system should be used
 
-#[cfg(target_os = "fuchsia")]
-mod zircon {
-    type zx_handle_t = u32;
-    type zx_status_t = i32;
-    pub const ZX_PROP_NAME: u32 = 3;
-
-    unsafe extern "C" {
-        pub fn zx_object_set_property(
-            handle: zx_handle_t,
-            property: u32,
-            value: *const libc::c_void,
-            value_size: libc::size_t,
-        ) -> zx_status_t;
-        pub fn zx_thread_self() -> zx_handle_t;
-    }
-}
-
 pub struct Thread {
     id: libc::pthread_t,
 }
@@ -216,7 +199,7 @@ impl Thread {
 
     #[cfg(target_os = "fuchsia")]
     pub fn set_name(name: &CStr) {
-        use self::zircon::*;
+        use super::fuchsia::*;
         unsafe {
             zx_object_set_property(
                 zx_thread_self(),
diff --git a/library/std/src/sys_common/process.rs b/library/std/src/sys/process/env.rs
index 9f61d69d858..e08b476540e 100644
--- a/library/std/src/sys_common/process.rs
+++ b/library/std/src/sys/process/env.rs
@@ -1,13 +1,9 @@
-#![allow(dead_code)]
-#![unstable(feature = "process_internals", issue = "none")]
-
 use crate::collections::BTreeMap;
 use crate::ffi::{OsStr, OsString};
-use crate::sys::pipe::read2;
-use crate::sys::process::{EnvKey, ExitStatus, Process, StdioPipes};
-use crate::{env, fmt, io};
+use crate::sys::process::EnvKey;
+use crate::{env, fmt};
 
-// Stores a set of changes to an environment
+/// Stores a set of changes to an environment
 #[derive(Clone, Default)]
 pub struct CommandEnv {
     clear: bool,
@@ -92,30 +88,23 @@ impl CommandEnv {
     }
 }
 
-/// An iterator over the command environment variables.
-///
-/// This struct is created by
-/// [`Command::get_envs`][crate::process::Command::get_envs]. See its
-/// documentation for more.
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "command_access", since = "1.57.0")]
 #[derive(Debug)]
 pub struct CommandEnvs<'a> {
     iter: crate::collections::btree_map::Iter<'a, EnvKey, Option<OsString>>,
 }
 
-#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> Iterator for CommandEnvs<'a> {
     type Item = (&'a OsStr, Option<&'a OsStr>);
+
     fn next(&mut self) -> Option<Self::Item> {
         self.iter.next().map(|(key, value)| (key.as_ref(), value.as_deref()))
     }
+
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
 }
 
-#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> ExactSizeIterator for CommandEnvs<'a> {
     fn len(&self) -> usize {
         self.iter.len()
@@ -124,30 +113,3 @@ impl<'a> ExactSizeIterator for CommandEnvs<'a> {
         self.iter.is_empty()
     }
 }
-
-pub fn wait_with_output(
-    mut process: Process,
-    mut pipes: StdioPipes,
-) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-    drop(pipes.stdin.take());
-
-    let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
-    match (pipes.stdout.take(), pipes.stderr.take()) {
-        (None, None) => {}
-        (Some(out), None) => {
-            let res = out.read_to_end(&mut stdout);
-            res.unwrap();
-        }
-        (None, Some(err)) => {
-            let res = err.read_to_end(&mut stderr);
-            res.unwrap();
-        }
-        (Some(out), Some(err)) => {
-            let res = read2(out, &mut stdout, err, &mut stderr);
-            res.unwrap();
-        }
-    }
-
-    let status = process.wait()?;
-    Ok((status, stdout, stderr))
-}
diff --git a/library/std/src/sys/process/mod.rs b/library/std/src/sys/process/mod.rs
index 92cfac7f47c..91c7005a328 100644
--- a/library/std/src/sys/process/mod.rs
+++ b/library/std/src/sys/process/mod.rs
@@ -14,6 +14,65 @@ cfg_if::cfg_if! {
     }
 }
 
+// This module is shared by all platforms, but nearly all platforms except for
+// the "normal" UNIX ones leave some of this code unused.
+#[cfg_attr(not(target_os = "linux"), allow(dead_code))]
+mod env;
+
+pub use env::CommandEnvs;
 pub use imp::{
     Command, CommandArgs, EnvKey, ExitCode, ExitStatus, ExitStatusError, Process, Stdio, StdioPipes,
 };
+
+#[cfg(any(
+    all(
+        target_family = "unix",
+        not(any(
+            target_os = "espidf",
+            target_os = "horizon",
+            target_os = "vita",
+            target_os = "nuttx"
+        ))
+    ),
+    target_os = "windows",
+))]
+pub fn output(cmd: &mut Command) -> crate::io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
+    use crate::sys::pipe::read2;
+
+    let (mut process, mut pipes) = cmd.spawn(Stdio::MakePipe, false)?;
+
+    drop(pipes.stdin.take());
+    let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
+    match (pipes.stdout.take(), pipes.stderr.take()) {
+        (None, None) => {}
+        (Some(out), None) => {
+            let res = out.read_to_end(&mut stdout);
+            res.unwrap();
+        }
+        (None, Some(err)) => {
+            let res = err.read_to_end(&mut stderr);
+            res.unwrap();
+        }
+        (Some(out), Some(err)) => {
+            let res = read2(out, &mut stdout, err, &mut stderr);
+            res.unwrap();
+        }
+    }
+
+    let status = process.wait()?;
+    Ok((status, stdout, stderr))
+}
+
+#[cfg(not(any(
+    all(
+        target_family = "unix",
+        not(any(
+            target_os = "espidf",
+            target_os = "horizon",
+            target_os = "vita",
+            target_os = "nuttx"
+        ))
+    ),
+    target_os = "windows",
+)))]
+pub use imp::output;
diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs
index 5f922292d05..4864c586988 100644
--- a/library/std/src/sys/process/uefi.rs
+++ b/library/std/src/sys/process/uefi.rs
@@ -1,5 +1,6 @@
 use r_efi::protocols::{simple_text_input, simple_text_output};
 
+use super::env::{CommandEnv, CommandEnvs};
 use crate::collections::BTreeMap;
 pub use crate::ffi::OsString as EnvKey;
 use crate::ffi::{OsStr, OsString};
@@ -10,7 +11,6 @@ use crate::sys::pal::helpers;
 use crate::sys::pal::os::error_string;
 use crate::sys::pipe::AnonPipe;
 use crate::sys::unsupported;
-use crate::sys_common::process::{CommandEnv, CommandEnvs};
 use crate::{fmt, io};
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -139,72 +139,72 @@ impl Command {
             Stdio::MakePipe => unsupported(),
         }
     }
+}
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        let mut cmd = uefi_command_internal::Image::load_image(&self.prog)?;
-
-        // UEFI adds the bin name by default
-        if !self.args.is_empty() {
-            let args = uefi_command_internal::create_args(&self.prog, &self.args);
-            cmd.set_args(args);
-        }
-
-        // Setup Stdout
-        let stdout = self.stdout.unwrap_or(Stdio::MakePipe);
-        let stdout = Self::create_pipe(stdout)?;
-        if let Some(con) = stdout {
-            cmd.stdout_init(con)
-        } else {
-            cmd.stdout_inherit()
-        };
-
-        // Setup Stderr
-        let stderr = self.stderr.unwrap_or(Stdio::MakePipe);
-        let stderr = Self::create_pipe(stderr)?;
-        if let Some(con) = stderr {
-            cmd.stderr_init(con)
-        } else {
-            cmd.stderr_inherit()
-        };
-
-        // Setup Stdin
-        let stdin = self.stdin.unwrap_or(Stdio::Null);
-        let stdin = Self::create_stdin(stdin)?;
-        if let Some(con) = stdin {
-            cmd.stdin_init(con)
-        } else {
-            cmd.stdin_inherit()
-        };
-
-        let env = env_changes(&self.env);
-
-        // Set any new vars
-        if let Some(e) = &env {
-            for (k, (_, v)) in e {
-                match v {
-                    Some(v) => unsafe { crate::env::set_var(k, v) },
-                    None => unsafe { crate::env::remove_var(k) },
-                }
+pub fn output(command: &mut Command) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
+    let mut cmd = uefi_command_internal::Image::load_image(&command.prog)?;
+
+    // UEFI adds the bin name by default
+    if !command.args.is_empty() {
+        let args = uefi_command_internal::create_args(&command.prog, &command.args);
+        cmd.set_args(args);
+    }
+
+    // Setup Stdout
+    let stdout = command.stdout.unwrap_or(Stdio::MakePipe);
+    let stdout = Command::create_pipe(stdout)?;
+    if let Some(con) = stdout {
+        cmd.stdout_init(con)
+    } else {
+        cmd.stdout_inherit()
+    };
+
+    // Setup Stderr
+    let stderr = command.stderr.unwrap_or(Stdio::MakePipe);
+    let stderr = Command::create_pipe(stderr)?;
+    if let Some(con) = stderr {
+        cmd.stderr_init(con)
+    } else {
+        cmd.stderr_inherit()
+    };
+
+    // Setup Stdin
+    let stdin = command.stdin.unwrap_or(Stdio::Null);
+    let stdin = Command::create_stdin(stdin)?;
+    if let Some(con) = stdin {
+        cmd.stdin_init(con)
+    } else {
+        cmd.stdin_inherit()
+    };
+
+    let env = env_changes(&command.env);
+
+    // Set any new vars
+    if let Some(e) = &env {
+        for (k, (_, v)) in e {
+            match v {
+                Some(v) => unsafe { crate::env::set_var(k, v) },
+                None => unsafe { crate::env::remove_var(k) },
             }
         }
+    }
 
-        let stat = cmd.start_image()?;
+    let stat = cmd.start_image()?;
 
-        // Rollback any env changes
-        if let Some(e) = env {
-            for (k, (v, _)) in e {
-                match v {
-                    Some(v) => unsafe { crate::env::set_var(k, v) },
-                    None => unsafe { crate::env::remove_var(k) },
-                }
+    // Rollback any env changes
+    if let Some(e) = env {
+        for (k, (v, _)) in e {
+            match v {
+                Some(v) => unsafe { crate::env::set_var(k, v) },
+                None => unsafe { crate::env::remove_var(k) },
             }
         }
+    }
 
-        let stdout = cmd.stdout()?;
-        let stderr = cmd.stderr()?;
+    let stdout = cmd.stdout()?;
+    let stderr = cmd.stderr()?;
 
-        Ok((ExitStatus(stat), stdout, stderr))
-    }
+    Ok((ExitStatus(stat), stdout, stderr))
 }
 
 impl From<AnonPipe> for Stdio {
diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs
index 8bc17f31491..a9c2510e6d4 100644
--- a/library/std/src/sys/process/unix/common.rs
+++ b/library/std/src/sys/process/unix/common.rs
@@ -12,7 +12,7 @@ use crate::sys::fs::File;
 #[cfg(not(target_os = "fuchsia"))]
 use crate::sys::fs::OpenOptions;
 use crate::sys::pipe::{self, AnonPipe};
-use crate::sys_common::process::{CommandEnv, CommandEnvs};
+use crate::sys::process::env::{CommandEnv, CommandEnvs};
 use crate::sys_common::{FromInner, IntoInner};
 use crate::{fmt, io, ptr};
 
diff --git a/library/std/src/sys/process/unix/fuchsia.rs b/library/std/src/sys/process/unix/fuchsia.rs
index 0de32ecffd4..017ab91797c 100644
--- a/library/std/src/sys/process/unix/fuchsia.rs
+++ b/library/std/src/sys/process/unix/fuchsia.rs
@@ -31,11 +31,6 @@ impl Command {
         Ok((Process { handle: Handle::new(process_handle) }, ours))
     }
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
-        crate::sys_common::process::wait_with_output(proc, pipes)
-    }
-
     pub fn exec(&mut self, default: Stdio) -> io::Error {
         if self.saw_nul() {
             return io::const_error!(
@@ -81,7 +76,7 @@ impl Command {
 
                 let mut handle = ZX_HANDLE_INVALID;
                 let status = fdio_fd_clone(target_fd, &mut handle);
-                if status == ERR_INVALID_ARGS || status == ERR_NOT_SUPPORTED {
+                if status == ZX_ERR_INVALID_ARGS || status == ZX_ERR_NOT_SUPPORTED {
                     // This descriptor is closed; skip it rather than generating an
                     // error.
                     return Ok(Default::default());
@@ -197,7 +192,7 @@ impl Process {
                 zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED, 0, ptr::null_mut());
             match status {
                 0 => {} // Success
-                x if x == ERR_TIMED_OUT => {
+                x if x == ZX_ERR_TIMED_OUT => {
                     return Ok(None);
                 }
                 _ => {
diff --git a/library/std/src/sys/process/unix/mod.rs b/library/std/src/sys/process/unix/mod.rs
index 2e8b38f7de1..ee8fd8b2ca3 100644
--- a/library/std/src/sys/process/unix/mod.rs
+++ b/library/std/src/sys/process/unix/mod.rs
@@ -11,6 +11,7 @@ cfg_if::cfg_if! {
     } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] {
         mod unsupported;
         use unsupported as imp;
+        pub use unsupported::output;
     } else {
         mod unix;
         use unix as imp;
diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs
index ae1c9558281..1b3bd2de265 100644
--- a/library/std/src/sys/process/unix/unix.rs
+++ b/library/std/src/sys/process/unix/unix.rs
@@ -162,11 +162,6 @@ impl Command {
         }
     }
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
-        crate::sys_common::process::wait_with_output(proc, pipes)
-    }
-
     // WatchOS and TVOS headers mark the `fork`/`exec*` functions with
     // `__WATCHOS_PROHIBITED __TVOS_PROHIBITED`, and indicate that the
     // `posix_spawn*` functions should be used instead. It isn't entirely clear
diff --git a/library/std/src/sys/process/unix/unsupported.rs b/library/std/src/sys/process/unix/unsupported.rs
index 78d270923cf..e86561a5c5c 100644
--- a/library/std/src/sys/process/unix/unsupported.rs
+++ b/library/std/src/sys/process/unix/unsupported.rs
@@ -18,15 +18,15 @@ impl Command {
         unsupported()
     }
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        unsupported()
-    }
-
     pub fn exec(&mut self, _default: Stdio) -> io::Error {
         unsupported_err()
     }
 }
 
+pub fn output(_: &mut Command) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
+    unsupported()
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Processes
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/library/std/src/sys/process/unix/vxworks.rs b/library/std/src/sys/process/unix/vxworks.rs
index b92446f0cf6..fab3b36ebf3 100644
--- a/library/std/src/sys/process/unix/vxworks.rs
+++ b/library/std/src/sys/process/unix/vxworks.rs
@@ -112,11 +112,6 @@ impl Command {
         }
     }
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
-        crate::sys_common::process::wait_with_output(proc, pipes)
-    }
-
     pub fn exec(&mut self, default: Stdio) -> io::Error {
         let ret = Command::spawn(self, default, false);
         match ret {
diff --git a/library/std/src/sys/process/unsupported.rs b/library/std/src/sys/process/unsupported.rs
index fee81744f09..469922c78ac 100644
--- a/library/std/src/sys/process/unsupported.rs
+++ b/library/std/src/sys/process/unsupported.rs
@@ -1,3 +1,4 @@
+use super::env::{CommandEnv, CommandEnvs};
 pub use crate::ffi::OsString as EnvKey;
 use crate::ffi::{OsStr, OsString};
 use crate::num::NonZero;
@@ -5,7 +6,6 @@ use crate::path::Path;
 use crate::sys::fs::File;
 use crate::sys::pipe::AnonPipe;
 use crate::sys::unsupported;
-use crate::sys_common::process::{CommandEnv, CommandEnvs};
 use crate::{fmt, io};
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -104,10 +104,10 @@ impl Command {
     ) -> io::Result<(Process, StdioPipes)> {
         unsupported()
     }
+}
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        unsupported()
-    }
+pub fn output(_cmd: &mut Command) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
+    unsupported()
 }
 
 impl From<AnonPipe> for Stdio {
diff --git a/library/std/src/sys/process/windows.rs b/library/std/src/sys/process/windows.rs
index 4cfdf908c58..4acd753eec9 100644
--- a/library/std/src/sys/process/windows.rs
+++ b/library/std/src/sys/process/windows.rs
@@ -5,6 +5,7 @@ mod tests;
 
 use core::ffi::c_void;
 
+use super::env::{CommandEnv, CommandEnvs};
 use crate::collections::BTreeMap;
 use crate::env::consts::{EXE_EXTENSION, EXE_SUFFIX};
 use crate::ffi::{OsStr, OsString};
@@ -24,7 +25,6 @@ use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf};
 use crate::sys::pipe::{self, AnonPipe};
 use crate::sys::{cvt, path, stdio};
 use crate::sys_common::IntoInner;
-use crate::sys_common::process::{CommandEnv, CommandEnvs};
 use crate::{cmp, env, fmt, ptr};
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -389,11 +389,6 @@ impl Command {
             ))
         }
     }
-
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
-        crate::sys_common::process::wait_with_output(proc, pipes)
-    }
 }
 
 impl fmt::Debug for Command {
diff --git a/library/std/src/sys/sync/mutex/fuchsia.rs b/library/std/src/sys/sync/mutex/fuchsia.rs
index 3d388a4564a..cbb1926530f 100644
--- a/library/std/src/sys/sync/mutex/fuchsia.rs
+++ b/library/std/src/sys/sync/mutex/fuchsia.rs
@@ -39,7 +39,7 @@
 
 use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
 use crate::sync::atomic::{Atomic, AtomicU32};
-use crate::sys::futex::zircon::{
+use crate::sys::fuchsia::{
     ZX_ERR_BAD_HANDLE, ZX_ERR_BAD_STATE, ZX_ERR_INVALID_ARGS, ZX_ERR_TIMED_OUT, ZX_ERR_WRONG_TYPE,
     ZX_OK, ZX_TIME_INFINITE, zx_futex_wait, zx_futex_wake_single_owner, zx_handle_t,
     zx_thread_self,
@@ -83,13 +83,13 @@ impl Mutex {
 
     #[inline]
     pub fn try_lock(&self) -> bool {
-        let thread_self = unsafe { zx_thread_self() };
+        let thread_self = zx_thread_self();
         self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed).is_ok()
     }
 
     #[inline]
     pub fn lock(&self) {
-        let thread_self = unsafe { zx_thread_self() };
+        let thread_self = zx_thread_self();
         if let Err(state) =
             self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed)
         {
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 2a5de7f6666..b7f4656fa37 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -20,7 +20,6 @@
 #[cfg(test)]
 mod tests;
 
-pub mod process;
 pub mod wstr;
 pub mod wtf8;