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.rs4
-rw-r--r--library/std/src/f128.rs9
-rw-r--r--library/std/src/f16.rs9
-rw-r--r--library/std/src/f32.rs9
-rw-r--r--library/std/src/f64.rs9
-rw-r--r--library/std/src/fs.rs3
-rw-r--r--library/std/src/io/error.rs32
-rw-r--r--library/std/src/io/mod.rs2
-rw-r--r--library/std/src/io/stdio.rs7
-rw-r--r--library/std/src/keyword_docs.rs4
-rw-r--r--library/std/src/lib.rs14
-rw-r--r--library/std/src/os/wasi/mod.rs2
-rw-r--r--library/std/src/rt.rs21
-rw-r--r--library/std/src/sys/pal/sgx/net.rs14
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs24
-rw-r--r--library/std/src/sys/pal/uefi/os.rs63
-rw-r--r--library/std/src/sys/pal/unix/fs.rs6
-rw-r--r--library/std/src/sys/pal/unix/process/process_common.rs4
-rw-r--r--library/std/src/sys/pal/unix/process/process_unix.rs2
-rw-r--r--library/std/src/sys/pal/unix/process/process_vxworks.rs2
-rw-r--r--library/std/src/sys/pal/wasip2/net.rs74
-rw-r--r--library/std/src/sys/pal/windows/args.rs19
-rw-r--r--library/std/src/sys/pal/windows/c.rs2
-rw-r--r--library/std/src/sys/pal/windows/compat.rs8
-rw-r--r--library/std/src/sys/pal/windows/mod.rs1
-rw-r--r--library/std/src/sys/sync/once_box.rs4
-rw-r--r--library/std/src/sys/sync/thread_parking/mod.rs1
-rw-r--r--library/std/src/thread/current.rs20
-rw-r--r--library/std/src/thread/mod.rs24
30 files changed, 270 insertions, 143 deletions
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index f2e523dca77..ded4f404d78 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -1438,7 +1438,7 @@ impl<K, V> Clone for Iter<'_, K, V> {
     }
 }
 
-#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "default_iters_hash", since = "1.83.0")]
 impl<K, V> Default for Iter<'_, K, V> {
     #[inline]
     fn default() -> Self {
@@ -1484,7 +1484,7 @@ impl<'a, K, V> IterMut<'a, K, V> {
     }
 }
 
-#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "default_iters_hash", since = "1.83.0")]
 impl<K, V> Default for IterMut<'_, K, V> {
     #[inline]
     fn default() -> Self {
@@ -1522,7 +1522,7 @@ impl<K, V> IntoIter<K, V> {
     }
 }
 
-#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "default_iters_hash", since = "1.83.0")]
 impl<K, V> Default for IntoIter<K, V> {
     #[inline]
     fn default() -> Self {
@@ -1562,7 +1562,7 @@ impl<K, V> Clone for Keys<'_, K, V> {
     }
 }
 
-#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "default_iters_hash", since = "1.83.0")]
 impl<K, V> Default for Keys<'_, K, V> {
     #[inline]
     fn default() -> Self {
@@ -1609,7 +1609,7 @@ impl<K, V> Clone for Values<'_, K, V> {
     }
 }
 
-#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "default_iters_hash", since = "1.83.0")]
 impl<K, V> Default for Values<'_, K, V> {
     #[inline]
     fn default() -> Self {
@@ -1705,7 +1705,7 @@ pub struct ValuesMut<'a, K: 'a, V: 'a> {
     inner: IterMut<'a, K, V>,
 }
 
-#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "default_iters_hash", since = "1.83.0")]
 impl<K, V> Default for ValuesMut<'_, K, V> {
     #[inline]
     fn default() -> Self {
@@ -1735,7 +1735,7 @@ pub struct IntoKeys<K, V> {
     inner: IntoIter<K, V>,
 }
 
-#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "default_iters_hash", since = "1.83.0")]
 impl<K, V> Default for IntoKeys<K, V> {
     #[inline]
     fn default() -> Self {
@@ -1765,7 +1765,7 @@ pub struct IntoValues<K, V> {
     inner: IntoIter<K, V>,
 }
 
-#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "default_iters_hash", since = "1.83.0")]
 impl<K, V> Default for IntoValues<K, V> {
     #[inline]
     fn default() -> Self {
@@ -2865,7 +2865,7 @@ impl<'a, K, V> Entry<'a, K, V> {
     /// assert_eq!(entry.key(), &"poneyland");
     /// ```
     #[inline]
-    #[stable(feature = "entry_insert", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "entry_insert", since = "1.83.0")]
     pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
         match self {
             Occupied(mut entry) => {
@@ -3152,7 +3152,7 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
     /// assert_eq!(map["poneyland"], 37);
     /// ```
     #[inline]
-    #[stable(feature = "entry_insert", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "entry_insert", since = "1.83.0")]
     pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
         let base = self.base.insert_entry(value);
         OccupiedEntry { base }
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 210f5715225..e1e0eb36d23 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -1244,7 +1244,7 @@ pub struct Iter<'a, K: 'a> {
     base: base::Iter<'a, K>,
 }
 
-#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "default_iters_hash", since = "1.83.0")]
 impl<K> Default for Iter<'_, K> {
     #[inline]
     fn default() -> Self {
@@ -1273,7 +1273,7 @@ pub struct IntoIter<K> {
     base: base::IntoIter<K>,
 }
 
-#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "default_iters_hash", since = "1.83.0")]
 impl<K> Default for IntoIter<K> {
     #[inline]
     fn default() -> Self {
diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs
index b436fe9929c..229f979b5b1 100644
--- a/library/std/src/f128.rs
+++ b/library/std/src/f128.rs
@@ -210,8 +210,9 @@ impl f128 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn abs(self) -> Self {
+    pub const fn abs(self) -> Self {
         // FIXME(f16_f128): replace with `intrinsics::fabsf128` when available
         // We don't do this now because LLVM has lowering bugs for f128 math.
         Self::from_bits(self.to_bits() & !(1 << 127))
@@ -240,8 +241,9 @@ impl f128 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn signum(self) -> f128 {
+    pub const fn signum(self) -> f128 {
         if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) }
     }
 
@@ -278,8 +280,9 @@ impl f128 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn copysign(self, sign: f128) -> f128 {
+    pub const fn copysign(self, sign: f128) -> f128 {
         unsafe { intrinsics::copysignf128(self, sign) }
     }
 
diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs
index b2cd5fae9d0..bed21cda1cd 100644
--- a/library/std/src/f16.rs
+++ b/library/std/src/f16.rs
@@ -210,8 +210,9 @@ impl f16 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn abs(self) -> Self {
+    pub const fn abs(self) -> Self {
         // FIXME(f16_f128): replace with `intrinsics::fabsf16` when available
         Self::from_bits(self.to_bits() & !(1 << 15))
     }
@@ -239,8 +240,9 @@ impl f16 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn signum(self) -> f16 {
+    pub const fn signum(self) -> f16 {
         if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) }
     }
 
@@ -277,8 +279,9 @@ impl f16 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn copysign(self, sign: f16) -> f16 {
+    pub const fn copysign(self, sign: f16) -> f16 {
         unsafe { intrinsics::copysignf16(self, sign) }
     }
 
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index fa0b3ef6484..30cf4e1f756 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -194,8 +194,9 @@ impl f32 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[inline]
-    pub fn abs(self) -> f32 {
+    pub const fn abs(self) -> f32 {
         unsafe { intrinsics::fabsf32(self) }
     }
 
@@ -218,8 +219,9 @@ impl f32 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[inline]
-    pub fn signum(self) -> f32 {
+    pub const fn signum(self) -> f32 {
         if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) }
     }
 
@@ -253,7 +255,8 @@ impl f32 {
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "copysign", since = "1.35.0")]
-    pub fn copysign(self, sign: f32) -> f32 {
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    pub const fn copysign(self, sign: f32) -> f32 {
         unsafe { intrinsics::copysignf32(self, sign) }
     }
 
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index 9fa43a6742e..51d5476b372 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -194,8 +194,9 @@ impl f64 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[inline]
-    pub fn abs(self) -> f64 {
+    pub const fn abs(self) -> f64 {
         unsafe { intrinsics::fabsf64(self) }
     }
 
@@ -218,8 +219,9 @@ impl f64 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[inline]
-    pub fn signum(self) -> f64 {
+    pub const fn signum(self) -> f64 {
         if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) }
     }
 
@@ -252,8 +254,9 @@ impl f64 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "copysign", since = "1.35.0")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[inline]
-    pub fn copysign(self, sign: f64) -> f64 {
+    pub const fn copysign(self, sign: f64) -> f64 {
         unsafe { intrinsics::copysignf64(self, sign) }
     }
 
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 124ef121b18..675140ff18f 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -394,7 +394,8 @@ impl File {
     ///
     /// # Errors
     ///
-    /// This function will return an error if `path` does not already exist.
+    /// This function will return an error if `path` does not already exist,
+    /// or if memory allocation fails for the new buffer.
     /// Other errors may also be returned according to [`OpenOptions::open`].
     ///
     /// # Examples
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index f20814dd95c..adf103e9430 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -223,10 +223,10 @@ pub enum ErrorKind {
     #[stable(feature = "rust1", since = "1.0.0")]
     ConnectionReset,
     /// The remote host is not reachable.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     HostUnreachable,
     /// The network containing the remote host is not reachable.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     NetworkUnreachable,
     /// The connection was aborted (terminated) by the remote server.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -243,7 +243,7 @@ pub enum ErrorKind {
     #[stable(feature = "rust1", since = "1.0.0")]
     AddrNotAvailable,
     /// The system's networking is down.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     NetworkDown,
     /// The operation failed because a pipe was closed.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -259,18 +259,18 @@ pub enum ErrorKind {
     ///
     /// For example, a filesystem path was specified where one of the intermediate directory
     /// components was, in fact, a plain file.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     NotADirectory,
     /// The filesystem object is, unexpectedly, a directory.
     ///
     /// A directory was specified when a non-directory was expected.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     IsADirectory,
     /// A non-empty directory was specified where an empty directory was expected.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     DirectoryNotEmpty,
     /// The filesystem or storage medium is read-only, but a write operation was attempted.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     ReadOnlyFilesystem,
     /// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links.
     ///
@@ -285,7 +285,7 @@ pub enum ErrorKind {
     ///
     /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated
     /// by problems with the network or server.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     StaleNetworkFileHandle,
     /// A parameter was incorrect.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -319,13 +319,13 @@ pub enum ErrorKind {
     /// The underlying storage (typically, a filesystem) is full.
     ///
     /// This does not include out of quota errors.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     StorageFull,
     /// Seek on unseekable file.
     ///
     /// Seeking was attempted on an open file handle which is not suitable for seeking - for
     /// example, on Unix, a named pipe opened with `File::open`.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     NotSeekable,
     /// Filesystem quota was exceeded.
     #[unstable(feature = "io_error_more", issue = "86442")]
@@ -335,22 +335,22 @@ pub enum ErrorKind {
     /// This might arise from a hard limit of the underlying filesystem or file access API, or from
     /// an administratively imposed resource limitation.  Simple disk full, and out of quota, have
     /// their own errors.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     FileTooLarge,
     /// Resource is busy.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     ResourceBusy,
     /// Executable file is busy.
     ///
     /// An attempt was made to write to a file which is also in use as a running program.  (Not all
     /// operating systems detect this situation.)
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     ExecutableFileBusy,
     /// Deadlock (avoided).
     ///
     /// A file locking operation would result in deadlock.  This situation is typically detected, if
     /// at all, on a best-effort basis.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     Deadlock,
     /// Cross-device or cross-filesystem (hard) link or rename.
     #[unstable(feature = "io_error_more", issue = "86442")]
@@ -358,7 +358,7 @@ pub enum ErrorKind {
     /// Too many (hard) links to the same filesystem object.
     ///
     /// The filesystem does not support making so many hardlinks to the same file.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     TooManyLinks,
     /// A filename was invalid.
     ///
@@ -369,7 +369,7 @@ pub enum ErrorKind {
     ///
     /// When trying to run an external program, a system or process limit on the size of the
     /// arguments would have been exceeded.
-    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     ArgumentListTooLong,
     /// This operation was interrupted.
     ///
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 8fedcb241d0..71dfd0676c9 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -2405,7 +2405,7 @@ pub trait BufRead: Read {
     /// assert_eq!(num_bytes, 11);
     /// assert_eq!(animal, b"Crustacean\0");
     /// ```
-    #[stable(feature = "bufread_skip_until", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "bufread_skip_until", since = "1.83.0")]
     fn skip_until(&mut self, byte: u8) -> Result<usize> {
         skip_until(self, byte)
     }
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index bf242e715bd..35b38ed783f 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -370,7 +370,12 @@ impl Stdin {
     /// Locks this handle and reads a line of input, appending it to the specified buffer.
     ///
     /// For detailed semantics of this method, see the documentation on
-    /// [`BufRead::read_line`].
+    /// [`BufRead::read_line`]. In particular:
+    /// * Previous content of the buffer will be preserved. To avoid appending
+    ///   to the buffer, you need to [`clear`] it first.
+    /// * The trailing newline character, if any, is included in the buffer.
+    ///
+    /// [`clear`]: String::clear
     ///
     /// # Examples
     ///
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index 9f4d244b547..453b2708daa 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -2349,12 +2349,13 @@ mod async_keyword {}
 /// [`async`]: ../std/keyword.async.html
 mod await_keyword {}
 
+// FIXME(dyn_compat_renaming): Update URL and link text.
 #[doc(keyword = "dyn")]
 //
 /// `dyn` is a prefix of a [trait object]'s type.
 ///
 /// The `dyn` keyword is used to highlight that calls to methods on the associated `Trait`
-/// are [dynamically dispatched]. To use the trait this way, it must be 'object safe'.
+/// are [dynamically dispatched]. To use the trait this way, it must be 'dyn-compatible'[^1].
 ///
 /// Unlike generic parameters or `impl Trait`, the compiler does not know the concrete type that
 /// is being passed. That is, the type has been [erased].
@@ -2382,6 +2383,7 @@ mod await_keyword {}
 /// [ref-trait-obj]: ../reference/types/trait-object.html
 /// [ref-obj-safety]: ../reference/items/traits.html#object-safety
 /// [erased]: https://en.wikipedia.org/wiki/Type_erasure
+/// [^1]: Formerly known as 'object safe'.
 mod dyn_keyword {}
 
 #[doc(keyword = "union")]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 65a9aa66c7c..3ab65238368 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -267,6 +267,7 @@
 #![allow(unused_features)]
 //
 // Features:
+#![cfg_attr(not(bootstrap), feature(autodiff))]
 #![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count, rt))]
 #![cfg_attr(
     all(target_vendor = "fortanix", target_env = "sgx"),
@@ -278,7 +279,6 @@
 //
 // Language features:
 // tidy-alphabetical-start
-#![cfg_attr(bootstrap, feature(const_mut_refs))]
 #![feature(alloc_error_handler)]
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
@@ -288,6 +288,7 @@
 #![feature(cfg_target_thread_local)]
 #![feature(cfi_encoding)]
 #![feature(concat_idents)]
+#![feature(const_float_methods)]
 #![feature(decl_macro)]
 #![feature(deprecated_suggestion)]
 #![feature(doc_cfg)]
@@ -414,9 +415,6 @@
 // tidy-alphabetical-start
 #![feature(const_collections_with_hasher)]
 #![feature(const_hash)]
-#![feature(const_ip)]
-#![feature(const_ipv4)]
-#![feature(const_ipv6)]
 #![feature(thread_local_internals)]
 // tidy-alphabetical-end
 //
@@ -627,7 +625,13 @@ pub mod simd {
     #[doc(inline)]
     pub use crate::std_float::StdFloat;
 }
-
+#[cfg(not(bootstrap))]
+#[unstable(feature = "autodiff", issue = "124509")]
+/// This module provides support for automatic differentiation.
+pub mod autodiff {
+    /// This macro handles automatic differentiation.
+    pub use core::autodiff::autodiff;
+}
 #[stable(feature = "futures_api", since = "1.36.0")]
 pub mod task {
     //! Types and Traits for working with asynchronous tasks.
diff --git a/library/std/src/os/wasi/mod.rs b/library/std/src/os/wasi/mod.rs
index 33b50c9e53b..2ee6aa46600 100644
--- a/library/std/src/os/wasi/mod.rs
+++ b/library/std/src/os/wasi/mod.rs
@@ -36,6 +36,8 @@
 pub mod ffi;
 pub mod fs;
 pub mod io;
+
+#[cfg(all(target_os = "wasi", target_env = "p1"))]
 pub mod net;
 
 /// A prelude for conveniently writing platform-specific code.
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 0a841f07e3b..80e7c3c026b 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -102,9 +102,24 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
         sys::init(argc, argv, sigpipe)
     };
 
-    // Set up the current thread to give it the right name.
-    let thread = Thread::new_main();
-    thread::set_current(thread);
+    // Set up the current thread handle to give it the right name.
+    //
+    // When code running before main uses `ReentrantLock` (for example by
+    // using `println!`), the thread ID can become initialized before we
+    // create this handle. Since `set_current` fails when the ID of the
+    // handle does not match the current ID, we should attempt to use the
+    // current thread ID here instead of unconditionally creating a new
+    // one. Also see #130210.
+    let thread = Thread::new_main(thread::current_id());
+    if let Err(_thread) = thread::set_current(thread) {
+        // `thread::current` will create a new handle if none has been set yet.
+        // Thus, if someone uses it before main, this call will fail. That's a
+        // bad idea though, as we then cannot set the main thread name here.
+        //
+        // FIXME: detect the main thread in `thread::current` and use the
+        //        correct name there.
+        rtabort!("code running before main must not use thread::current");
+    }
 }
 
 /// Clean up the thread-local runtime state. This *should* be run after all other
diff --git a/library/std/src/sys/pal/sgx/net.rs b/library/std/src/sys/pal/sgx/net.rs
index 44913ffe3a9..c966886d163 100644
--- a/library/std/src/sys/pal/sgx/net.rs
+++ b/library/std/src/sys/pal/sgx/net.rs
@@ -78,9 +78,8 @@ fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
     }
 }
 
-fn addr_to_sockaddr(addr: &Option<String>) -> io::Result<SocketAddr> {
-    addr.as_ref()
-        .ok_or(io::ErrorKind::AddrNotAvailable)?
+fn addr_to_sockaddr(addr: Option<&str>) -> io::Result<SocketAddr> {
+    addr.ok_or(io::ErrorKind::AddrNotAvailable)?
         .to_socket_addrs()
         // unwrap OK: if an iterator is returned, we're guaranteed to get exactly one entry
         .map(|mut it| it.next().unwrap())
@@ -161,11 +160,11 @@ impl TcpStream {
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        addr_to_sockaddr(&self.peer_addr)
+        addr_to_sockaddr(self.peer_addr.as_deref())
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        addr_to_sockaddr(&self.inner.local_addr)
+        addr_to_sockaddr(self.inner.local_addr.as_deref())
     }
 
     pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
@@ -255,13 +254,14 @@ impl TcpListener {
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        addr_to_sockaddr(&self.inner.local_addr)
+        addr_to_sockaddr(self.inner.local_addr.as_deref())
     }
 
     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
         let (fd, local_addr, peer_addr) = usercalls::accept_stream(self.inner.inner.raw())?;
         let peer_addr = Some(peer_addr);
-        let ret_peer = addr_to_sockaddr(&peer_addr).unwrap_or_else(|_| ([0; 4], 0).into());
+        let ret_peer =
+            addr_to_sockaddr(peer_addr.as_deref()).unwrap_or_else(|_| ([0; 4], 0).into());
         Ok((TcpStream { inner: Socket::new(fd, local_addr), peer_addr }, ret_peer))
     }
 
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index bd8a6684b64..4ced7065c82 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -177,16 +177,8 @@ pub(crate) fn device_path_to_text(path: NonNull<device_path::Protocol>) -> io::R
             )
         };
 
-        // SAFETY: `convert_device_path_to_text` returns a pointer to a null-terminated UTF-16
-        // string, and that string cannot be deallocated prior to dropping the `WStrUnits`, so
-        // it's safe for `WStrUnits` to use.
-        let path_len = unsafe {
-            WStrUnits::new(path_ptr)
-                .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?
-                .count()
-        };
-
-        let path = OsString::from_wide(unsafe { slice::from_raw_parts(path_ptr.cast(), path_len) });
+        let path = os_string_from_raw(path_ptr)
+            .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?;
 
         if let Some(boot_services) = crate::os::uefi::env::boot_services() {
             let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast();
@@ -420,3 +412,15 @@ impl<T> Drop for OwnedTable<T> {
         unsafe { crate::alloc::dealloc(self.ptr as *mut u8, self.layout) };
     }
 }
+
+/// Create OsString from a pointer to NULL terminated UTF-16 string
+pub(crate) fn os_string_from_raw(ptr: *mut r_efi::efi::Char16) -> Option<OsString> {
+    let path_len = unsafe { WStrUnits::new(ptr)?.count() };
+    Some(OsString::from_wide(unsafe { slice::from_raw_parts(ptr.cast(), path_len) }))
+}
+
+/// Create NULL terminated UTF-16 string
+pub(crate) fn os_string_to_raw(s: &OsStr) -> Option<Box<[r_efi::efi::Char16]>> {
+    let temp = s.encode_wide().chain(Some(0)).collect::<Box<[r_efi::efi::Char16]>>();
+    if temp[..temp.len() - 1].contains(&0) { None } else { Some(temp) }
+}
diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs
index 9aee67d622f..4eb7698b43a 100644
--- a/library/std/src/sys/pal/uefi/os.rs
+++ b/library/std/src/sys/pal/uefi/os.rs
@@ -1,7 +1,7 @@
 use r_efi::efi::Status;
 use r_efi::efi::protocols::{device_path, loaded_image_device_path};
 
-use super::{RawOsError, helpers, unsupported};
+use super::{RawOsError, helpers, unsupported_err};
 use crate::error::Error as StdError;
 use crate::ffi::{OsStr, OsString};
 use crate::marker::PhantomData;
@@ -125,11 +125,32 @@ pub fn error_string(errno: RawOsError) -> String {
 }
 
 pub fn getcwd() -> io::Result<PathBuf> {
-    unsupported()
+    match uefi_shell::open_shell() {
+        Some(shell) => {
+            // SAFETY: path_ptr is managed by UEFI shell and should not be deallocated
+            let path_ptr = unsafe { ((*shell.as_ptr()).get_cur_dir)(crate::ptr::null_mut()) };
+            helpers::os_string_from_raw(path_ptr)
+                .map(PathBuf::from)
+                .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))
+        }
+        None => {
+            let mut t = current_exe()?;
+            // SAFETY: This should never fail since the disk prefix will be present even for root
+            // executables
+            assert!(t.pop());
+            Ok(t)
+        }
+    }
 }
 
-pub fn chdir(_: &path::Path) -> io::Result<()> {
-    unsupported()
+pub fn chdir(p: &path::Path) -> io::Result<()> {
+    let shell = uefi_shell::open_shell().ok_or(unsupported_err())?;
+
+    let mut p = helpers::os_string_to_raw(p.as_os_str())
+        .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?;
+
+    let r = unsafe { ((*shell.as_ptr()).set_cur_dir)(crate::ptr::null_mut(), p.as_mut_ptr()) };
+    if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
 }
 
 pub struct SplitPaths<'a>(!, PhantomData<&'a ()>);
@@ -239,3 +260,37 @@ pub fn exit(code: i32) -> ! {
 pub fn getpid() -> u32 {
     panic!("no pids on this platform")
 }
+
+mod uefi_shell {
+    use r_efi::protocols::shell;
+
+    use super::super::helpers;
+    use crate::ptr::NonNull;
+    use crate::sync::atomic::{AtomicPtr, Ordering};
+
+    pub fn open_shell() -> Option<NonNull<shell::Protocol>> {
+        static LAST_VALID_HANDLE: AtomicPtr<crate::ffi::c_void> =
+            AtomicPtr::new(crate::ptr::null_mut());
+
+        if let Some(handle) = NonNull::new(LAST_VALID_HANDLE.load(Ordering::Acquire)) {
+            if let Ok(protocol) = helpers::open_protocol::<shell::Protocol>(
+                handle,
+                r_efi::protocols::shell::PROTOCOL_GUID,
+            ) {
+                return Some(protocol);
+            }
+        }
+
+        let handles = helpers::locate_handles(shell::PROTOCOL_GUID).ok()?;
+        for handle in handles {
+            if let Ok(protocol) =
+                helpers::open_protocol::<shell::Protocol>(handle, shell::PROTOCOL_GUID)
+            {
+                LAST_VALID_HANDLE.store(handle.as_ptr(), Ordering::Release);
+                return Some(protocol);
+            }
+        }
+
+        None
+    }
+}
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 39aabf0b2d6..567577b2b4d 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -899,7 +899,7 @@ impl DirEntry {
             target_os = "android",
             target_os = "hurd"
         ),
-        not(miri)
+        not(miri) // no dirfd on Miri
     ))]
     pub fn metadata(&self) -> io::Result<FileAttr> {
         let fd = cvt(unsafe { dirfd(self.dir.dirp.0) })?;
@@ -1538,7 +1538,7 @@ impl fmt::Debug for File {
             Some(PathBuf::from(OsString::from_vec(buf)))
         }
 
-        #[cfg(all(target_os = "freebsd", target_arch = "x86_64"))]
+        #[cfg(target_os = "freebsd")]
         fn get_path(fd: c_int) -> Option<PathBuf> {
             let info = Box::<libc::kinfo_file>::new_zeroed();
             let mut info = unsafe { info.assume_init() };
@@ -1566,7 +1566,7 @@ impl fmt::Debug for File {
         #[cfg(not(any(
             target_os = "linux",
             target_os = "vxworks",
-            all(target_os = "freebsd", target_arch = "x86_64"),
+            target_os = "freebsd",
             target_os = "netbsd",
             target_os = "illumos",
             target_os = "solaris",
diff --git a/library/std/src/sys/pal/unix/process/process_common.rs b/library/std/src/sys/pal/unix/process/process_common.rs
index d9c41d43487..13290fed762 100644
--- a/library/std/src/sys/pal/unix/process/process_common.rs
+++ b/library/std/src/sys/pal/unix/process/process_common.rs
@@ -312,8 +312,8 @@ impl Command {
     }
 
     #[allow(dead_code)]
-    pub fn get_cwd(&self) -> &Option<CString> {
-        &self.cwd
+    pub fn get_cwd(&self) -> Option<&CStr> {
+        self.cwd.as_deref()
     }
     #[allow(dead_code)]
     pub fn get_uid(&self) -> Option<uid_t> {
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index 5d30f388da1..4551d49e841 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -335,7 +335,7 @@ impl Command {
                 cvt(libc::setuid(u as uid_t))?;
             }
         }
-        if let Some(ref cwd) = *self.get_cwd() {
+        if let Some(cwd) = self.get_cwd() {
             cvt(libc::chdir(cwd.as_ptr()))?;
         }
 
diff --git a/library/std/src/sys/pal/unix/process/process_vxworks.rs b/library/std/src/sys/pal/unix/process/process_vxworks.rs
index 2d9a304c495..38daf6af918 100644
--- a/library/std/src/sys/pal/unix/process/process_vxworks.rs
+++ b/library/std/src/sys/pal/unix/process/process_vxworks.rs
@@ -57,7 +57,7 @@ impl Command {
                 t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO)));
             }
 
-            if let Some(ref cwd) = *self.get_cwd() {
+            if let Some(cwd) = self.get_cwd() {
                 t!(cvt(libc::chdir(cwd.as_ptr())));
             }
 
diff --git a/library/std/src/sys/pal/wasip2/net.rs b/library/std/src/sys/pal/wasip2/net.rs
index c40eb229ba9..06e623df843 100644
--- a/library/std/src/sys/pal/wasip2/net.rs
+++ b/library/std/src/sys/pal/wasip2/net.rs
@@ -2,13 +2,12 @@
 
 use libc::{c_int, c_void, size_t};
 
-use super::fd::WasiFd;
 use crate::ffi::CStr;
 use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::net::{Shutdown, SocketAddr};
-use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
+use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
 use crate::sys::unsupported;
-use crate::sys_common::net::{TcpListener, getsockopt, setsockopt, sockaddr_to_addr};
+use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr};
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::time::{Duration, Instant};
 use crate::{cmp, mem, str};
@@ -71,7 +70,9 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
 
 pub fn init() {}
 
-pub struct Socket(WasiFd);
+pub struct WasiSocket(OwnedFd);
+
+pub struct Socket(WasiSocket);
 
 impl Socket {
     pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
@@ -327,53 +328,90 @@ impl Socket {
     }
 }
 
-impl AsInner<WasiFd> for Socket {
+impl AsInner<OwnedFd> for WasiSocket {
     #[inline]
-    fn as_inner(&self) -> &WasiFd {
+    fn as_inner(&self) -> &OwnedFd {
         &self.0
     }
 }
 
-impl IntoInner<WasiFd> for Socket {
-    fn into_inner(self) -> WasiFd {
+impl IntoInner<OwnedFd> for WasiSocket {
+    fn into_inner(self) -> OwnedFd {
         self.0
     }
 }
 
-impl FromInner<WasiFd> for Socket {
-    fn from_inner(inner: WasiFd) -> Socket {
-        Socket(inner)
+impl FromInner<OwnedFd> for WasiSocket {
+    fn from_inner(owned_fd: OwnedFd) -> Self {
+        Self(owned_fd)
     }
 }
 
-impl AsFd for Socket {
+impl AsFd for WasiSocket {
     fn as_fd(&self) -> BorrowedFd<'_> {
         self.0.as_fd()
     }
 }
 
-impl AsRawFd for Socket {
+impl AsRawFd for WasiSocket {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
         self.0.as_raw_fd()
     }
 }
 
-impl IntoRawFd for Socket {
+impl IntoRawFd for WasiSocket {
     fn into_raw_fd(self) -> RawFd {
         self.0.into_raw_fd()
     }
 }
 
-impl FromRawFd for Socket {
+impl FromRawFd for WasiSocket {
     unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
         unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) }
     }
 }
 
-impl AsInner<Socket> for TcpListener {
+impl AsInner<WasiSocket> for Socket {
+    #[inline]
+    fn as_inner(&self) -> &WasiSocket {
+        &self.0
+    }
+}
+
+impl IntoInner<WasiSocket> for Socket {
+    fn into_inner(self) -> WasiSocket {
+        self.0
+    }
+}
+
+impl FromInner<WasiSocket> for Socket {
+    fn from_inner(sock: WasiSocket) -> Socket {
+        Socket(sock)
+    }
+}
+
+impl AsFd for Socket {
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        self.0.as_fd()
+    }
+}
+
+impl AsRawFd for Socket {
     #[inline]
-    fn as_inner(&self) -> &Socket {
-        &self.socket()
+    fn as_raw_fd(&self) -> RawFd {
+        self.0.as_raw_fd()
+    }
+}
+
+impl IntoRawFd for Socket {
+    fn into_raw_fd(self) -> RawFd {
+        self.0.into_raw_fd()
+    }
+}
+
+impl FromRawFd for Socket {
+    unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
+        unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) }
     }
 }
diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs
index 848632ec2a7..e9fc19bcb99 100644
--- a/library/std/src/sys/pal/windows/args.rs
+++ b/library/std/src/sys/pal/windows/args.rs
@@ -18,17 +18,6 @@ use crate::sys_common::AsInner;
 use crate::sys_common::wstr::WStrUnits;
 use crate::{fmt, io, iter, vec};
 
-/// This is the const equivalent to `NonZero::new(n).unwrap()`
-///
-/// FIXME(const-hack): This can be removed once `Option::unwrap` is stably const.
-/// See the `const_option` feature (#67441).
-const fn non_zero_u16(n: u16) -> NonZero<u16> {
-    match NonZero::new(n) {
-        Some(n) => n,
-        None => panic!("called `unwrap` on a `None` value"),
-    }
-}
-
 pub fn args() -> Args {
     // SAFETY: `GetCommandLineW` returns a pointer to a null terminated UTF-16
     // string so it's safe for `WStrUnits` to use.
@@ -66,10 +55,10 @@ fn parse_lp_cmd_line<'a, F: Fn() -> OsString>(
     lp_cmd_line: Option<WStrUnits<'a>>,
     exe_name: F,
 ) -> Vec<OsString> {
-    const BACKSLASH: NonZero<u16> = non_zero_u16(b'\\' as u16);
-    const QUOTE: NonZero<u16> = non_zero_u16(b'"' as u16);
-    const TAB: NonZero<u16> = non_zero_u16(b'\t' as u16);
-    const SPACE: NonZero<u16> = non_zero_u16(b' ' as u16);
+    const BACKSLASH: NonZero<u16> = NonZero::new(b'\\' as u16).unwrap();
+    const QUOTE: NonZero<u16> = NonZero::new(b'"' as u16).unwrap();
+    const TAB: NonZero<u16> = NonZero::new(b'\t' as u16).unwrap();
+    const SPACE: NonZero<u16> = NonZero::new(b' ' as u16).unwrap();
 
     let mut ret_val = Vec::new();
     // If the cmd line pointer is null or it points to an empty string then
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index b65ad7dbe8c..9ce3e912caf 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -175,9 +175,9 @@ extern "system" {
     pub fn WakeByAddressAll(address: *const c_void);
 }
 
+// These are loaded by `load_synch_functions`.
 #[cfg(target_vendor = "win7")]
 compat_fn_optional! {
-    crate::sys::compat::load_synch_functions();
     pub fn WaitOnAddress(
         address: *const c_void,
         compareaddress: *const c_void,
diff --git a/library/std/src/sys/pal/windows/compat.rs b/library/std/src/sys/pal/windows/compat.rs
index c8e25dd0c94..42999da1664 100644
--- a/library/std/src/sys/pal/windows/compat.rs
+++ b/library/std/src/sys/pal/windows/compat.rs
@@ -198,11 +198,10 @@ macro_rules! compat_fn_with_fallback {
 
 /// Optionally loaded functions.
 ///
-/// Actual loading of the function defers to $load_functions.
+/// Relies on the functions being pre-loaded elsewhere.
 #[cfg(target_vendor = "win7")]
 macro_rules! compat_fn_optional {
-    ($load_functions:expr;
-    $(
+    ($(
         $(#[$meta:meta])*
         $vis:vis fn $symbol:ident($($argname:ident: $argtype:ty),*) $(-> $rettype:ty)?;
     )+) => (
@@ -221,9 +220,6 @@ macro_rules! compat_fn_optional {
 
                 #[inline(always)]
                 pub fn option() -> Option<F> {
-                    // Miri does not understand the way we do preloading
-                    // therefore load the function here instead.
-                    #[cfg(miri)] $load_functions;
                     NonNull::new(PTR.load(Ordering::Relaxed)).map(|f| unsafe { mem::transmute(f) })
                 }
             }
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index 1ea253e5e52..a9886012e8e 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -346,7 +346,6 @@ pub fn abort_internal() -> ! {
     }
 }
 
-// miri is sensitive to changes here so check that miri is happy if touching this
 #[cfg(miri)]
 pub fn abort_internal() -> ! {
     crate::intrinsics::abort();
diff --git a/library/std/src/sys/sync/once_box.rs b/library/std/src/sys/sync/once_box.rs
index 1422b5a1721..9d24db2245a 100644
--- a/library/std/src/sys/sync/once_box.rs
+++ b/library/std/src/sys/sync/once_box.rs
@@ -8,7 +8,7 @@
 use crate::mem::replace;
 use crate::ptr::null_mut;
 use crate::sync::atomic::AtomicPtr;
-use crate::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed};
+use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
 
 pub(crate) struct OnceBox<T> {
     ptr: AtomicPtr<T>,
@@ -60,7 +60,7 @@ impl<T> OnceBox<T> {
     #[cold]
     fn initialize(&self, f: impl FnOnce() -> Box<T>) -> &T {
         let new_ptr = Box::into_raw(f());
-        match self.ptr.compare_exchange(null_mut(), new_ptr, AcqRel, Acquire) {
+        match self.ptr.compare_exchange(null_mut(), new_ptr, Release, Acquire) {
             Ok(_) => unsafe { &*new_ptr },
             Err(ptr) => {
                 // Lost the race to another thread.
diff --git a/library/std/src/sys/sync/thread_parking/mod.rs b/library/std/src/sys/sync/thread_parking/mod.rs
index 0ebc5e093ee..f4d8fa0a58c 100644
--- a/library/std/src/sys/sync/thread_parking/mod.rs
+++ b/library/std/src/sys/sync/thread_parking/mod.rs
@@ -23,6 +23,7 @@ cfg_if::cfg_if! {
         mod windows7;
         pub use windows7::Parker;
     } else if #[cfg(all(target_vendor = "apple", not(miri)))] {
+        // Doesn't work in Miri, see <https://github.com/rust-lang/miri/issues/2589>.
         mod darwin;
         pub use darwin::Parker;
     } else if #[cfg(target_os = "xous")] {
diff --git a/library/std/src/thread/current.rs b/library/std/src/thread/current.rs
index b38149a0da7..e6eb90c4c30 100644
--- a/library/std/src/thread/current.rs
+++ b/library/std/src/thread/current.rs
@@ -110,22 +110,24 @@ mod id {
     }
 }
 
-/// Sets the thread handle for the current thread.
-///
-/// Aborts if the handle or the ID has been set already.
-pub(crate) fn set_current(thread: Thread) {
-    if CURRENT.get() != NONE || id::get().is_some() {
-        // Using `panic` here can add ~3kB to the binary size. We have complete
-        // control over where this is called, so just abort if there is a bug.
-        rtabort!("thread::set_current should only be called once per thread");
+/// Tries to set the thread handle for the current thread. Fails if a handle was
+/// already set or if the thread ID of `thread` would change an already-set ID.
+pub(crate) fn set_current(thread: Thread) -> Result<(), Thread> {
+    if CURRENT.get() != NONE {
+        return Err(thread);
     }
 
-    id::set(thread.id());
+    match id::get() {
+        Some(id) if id == thread.id() => {}
+        None => id::set(thread.id()),
+        _ => return Err(thread),
+    }
 
     // Make sure that `crate::rt::thread_cleanup` will be run, which will
     // call `drop_current`.
     crate::sys::thread_local::guard::enable();
     CURRENT.set(thread.into_raw().cast_mut());
+    Ok(())
 }
 
 /// Gets the id of the thread that invokes it.
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index d1d4eabb9bd..39753888509 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -519,9 +519,14 @@ impl Builder {
 
         let f = MaybeDangling::new(f);
         let main = move || {
-            // Immediately store the thread handle to avoid setting it or its ID
-            // twice, which would cause an abort.
-            set_current(their_thread.clone());
+            if let Err(_thread) = set_current(their_thread.clone()) {
+                // Both the current thread handle and the ID should not be
+                // initialized yet. Since only the C runtime and some of our
+                // platform code run before this, this point shouldn't be
+                // reachable. Use an abort to save binary size (see #123356).
+                rtabort!("something here is badly broken!");
+            }
+
             if let Some(name) = their_thread.cname() {
                 imp::Thread::set_name(name);
             }
@@ -1159,9 +1164,6 @@ pub fn park_timeout(dur: Duration) {
 pub struct ThreadId(NonZero<u64>);
 
 impl ThreadId {
-    // DO NOT rely on this value.
-    const MAIN_THREAD: ThreadId = ThreadId(unsafe { NonZero::new_unchecked(1) });
-
     // Generate a new unique thread ID.
     pub(crate) fn new() -> ThreadId {
         #[cold]
@@ -1173,7 +1175,7 @@ impl ThreadId {
             if #[cfg(target_has_atomic = "64")] {
                 use crate::sync::atomic::AtomicU64;
 
-                static COUNTER: AtomicU64 = AtomicU64::new(1);
+                static COUNTER: AtomicU64 = AtomicU64::new(0);
 
                 let mut last = COUNTER.load(Ordering::Relaxed);
                 loop {
@@ -1189,7 +1191,7 @@ impl ThreadId {
             } else {
                 use crate::sync::{Mutex, PoisonError};
 
-                static COUNTER: Mutex<u64> = Mutex::new(1);
+                static COUNTER: Mutex<u64> = Mutex::new(0);
 
                 let mut counter = COUNTER.lock().unwrap_or_else(PoisonError::into_inner);
                 let Some(id) = counter.checked_add(1) else {
@@ -1326,9 +1328,9 @@ impl Thread {
         Self::new_inner(id, ThreadName::Unnamed)
     }
 
-    // Used in runtime to construct main thread
-    pub(crate) fn new_main() -> Thread {
-        Self::new_inner(ThreadId::MAIN_THREAD, ThreadName::Main)
+    /// Constructs the thread handle for the main thread.
+    pub(crate) fn new_main(id: ThreadId) -> Thread {
+        Self::new_inner(id, ThreadName::Main)
     }
 
     fn new_inner(id: ThreadId, name: ThreadName) -> Thread {