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/ffi/os_str.rs6
-rw-r--r--library/std/src/fs.rs9
-rw-r--r--library/std/src/os/fd/owned.rs6
-rw-r--r--library/std/src/os/solid/io.rs6
-rw-r--r--library/std/src/os/unix/fs.rs2
-rw-r--r--library/std/src/os/unix/net/datagram.rs4
-rw-r--r--library/std/src/os/windows/io/handle.rs6
-rw-r--r--library/std/src/os/windows/io/socket.rs7
-rw-r--r--library/std/src/path.rs6
-rw-r--r--library/std/src/rt.rs2
-rw-r--r--library/std/src/sys/pal/hermit/thread.rs6
-rw-r--r--library/std/src/sys/pal/sgx/abi/tls/mod.rs4
-rw-r--r--library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs7
-rw-r--r--library/std/src/sys/pal/sgx/fd.rs10
-rw-r--r--library/std/src/sys/pal/teeos/thread.rs16
-rw-r--r--library/std/src/sys/pal/unix/fd.rs2
-rw-r--r--library/std/src/sys/pal/unix/fs.rs24
-rw-r--r--library/std/src/sys/pal/unix/mod.rs3
-rw-r--r--library/std/src/sys/pal/unix/net.rs29
-rw-r--r--library/std/src/sys/pal/unix/process/process_vxworks.rs9
-rw-r--r--library/std/src/sys/pal/unix/thread.rs14
-rw-r--r--library/std/src/sys/pal/wasi/thread.rs10
-rw-r--r--library/std/src/sys/pal/windows/alloc.rs8
-rw-r--r--library/std/src/sys/pal/windows/c.rs73
-rw-r--r--library/std/src/sys/pal/windows/c/bindings.txt2
-rw-r--r--library/std/src/sys/pal/windows/c/windows_sys.rs24
-rw-r--r--library/std/src/sys/pal/windows/compat.rs14
-rw-r--r--library/std/src/sys/pal/windows/fs.rs4
-rw-r--r--library/std/src/sys/pal/windows/handle.rs11
-rw-r--r--library/std/src/sys/pal/windows/mod.rs2
-rw-r--r--library/std/src/sys/personality/gcc.rs321
-rw-r--r--library/std/src/sys_common/net.rs1
-rw-r--r--library/std/src/thread/mod.rs33
33 files changed, 354 insertions, 327 deletions
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index f9dba08da4c..0fb3964c9a9 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -115,10 +115,8 @@ impl crate::sealed::Sealed for OsString {}
 #[stable(feature = "rust1", since = "1.0.0")]
 // `OsStr::from_inner` current implementation relies
 // on `OsStr` being layout-compatible with `Slice`.
-// However, `OsStr` layout is considered an implementation detail and must not be relied upon. We
-// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
-// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
-#[cfg_attr(not(doc), repr(transparent))]
+// However, `OsStr` layout is considered an implementation detail and must not be relied upon.
+#[repr(transparent)]
 pub struct OsStr {
     inner: Slice,
 }
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 6413b3515ec..536d0d1b356 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -2400,13 +2400,8 @@ pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///
 /// # Errors
 ///
-/// This function will return an error in the following situations, but is not
-/// limited to just these cases:
-///
-/// * If any directory in the path specified by `path`
-/// does not already exist and it could not be created otherwise. The specific
-/// error conditions for when a directory is being created (after it is
-/// determined to not exist) are outlined by [`fs::create_dir`].
+/// The function will return an error if any directory specified in path does not exist and
+/// could not be created. There may be other error conditions; see [`fs::create_dir`] for specifics.
 ///
 /// Notable exception is made for situations where any of the directories
 /// specified in the `path` could not be created as it was being created concurrently.
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 5833c597256..bbd5093e44c 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -8,7 +8,7 @@ use crate::fmt;
 use crate::fs;
 use crate::io;
 use crate::marker::PhantomData;
-use crate::mem::forget;
+use crate::mem::ManuallyDrop;
 #[cfg(not(any(target_arch = "wasm32", target_env = "sgx", target_os = "hermit")))]
 use crate::sys::cvt;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
@@ -148,9 +148,7 @@ impl AsRawFd for OwnedFd {
 impl IntoRawFd for OwnedFd {
     #[inline]
     fn into_raw_fd(self) -> RawFd {
-        let fd = self.fd;
-        forget(self);
-        fd
+        ManuallyDrop::new(self).fd
     }
 }
 
diff --git a/library/std/src/os/solid/io.rs b/library/std/src/os/solid/io.rs
index e75bcf74e5c..bbf7e96d53d 100644
--- a/library/std/src/os/solid/io.rs
+++ b/library/std/src/os/solid/io.rs
@@ -48,7 +48,7 @@
 
 use crate::fmt;
 use crate::marker::PhantomData;
-use crate::mem::forget;
+use crate::mem::ManuallyDrop;
 use crate::net;
 use crate::sys;
 use crate::sys_common::{self, AsInner, FromInner, IntoInner};
@@ -148,9 +148,7 @@ impl AsRawFd for OwnedFd {
 impl IntoRawFd for OwnedFd {
     #[inline]
     fn into_raw_fd(self) -> RawFd {
-        let fd = self.fd;
-        forget(self);
-        fd
+        ManuallyDrop::new(self).fd
     }
 }
 
diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs
index 970023d8cf1..20c472040fa 100644
--- a/library/std/src/os/unix/fs.rs
+++ b/library/std/src/os/unix/fs.rs
@@ -1064,7 +1064,7 @@ pub fn lchown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io:
 /// }
 /// ```
 #[stable(feature = "unix_chroot", since = "1.56.0")]
-#[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))]
+#[cfg(not(target_os = "fuchsia"))]
 pub fn chroot<P: AsRef<Path>>(dir: P) -> io::Result<()> {
     sys::fs::chroot(dir.as_ref())
 }
diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs
index b29f9099a11..f58f9b4d9ab 100644
--- a/library/std/src/os/unix/net/datagram.rs
+++ b/library/std/src/os/unix/net/datagram.rs
@@ -20,6 +20,8 @@ use crate::{fmt, io};
     target_os = "freebsd",
     target_os = "openbsd",
     target_os = "netbsd",
+    target_os = "solaris",
+    target_os = "illumos",
     target_os = "haiku",
     target_os = "nto",
 ))]
@@ -31,6 +33,8 @@ use libc::MSG_NOSIGNAL;
     target_os = "freebsd",
     target_os = "openbsd",
     target_os = "netbsd",
+    target_os = "solaris",
+    target_os = "illumos",
     target_os = "haiku",
     target_os = "nto",
 )))]
diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index a9d1983dce6..9865386e753 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -7,7 +7,7 @@ use crate::fmt;
 use crate::fs;
 use crate::io;
 use crate::marker::PhantomData;
-use crate::mem::{forget, ManuallyDrop};
+use crate::mem::ManuallyDrop;
 use crate::ptr;
 use crate::sys;
 use crate::sys::cvt;
@@ -319,9 +319,7 @@ impl AsRawHandle for OwnedHandle {
 impl IntoRawHandle for OwnedHandle {
     #[inline]
     fn into_raw_handle(self) -> RawHandle {
-        let handle = self.handle;
-        forget(self);
-        handle
+        ManuallyDrop::new(self).handle
     }
 }
 
diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs
index 4334d041439..df5b56d3062 100644
--- a/library/std/src/os/windows/io/socket.rs
+++ b/library/std/src/os/windows/io/socket.rs
@@ -6,8 +6,7 @@ use super::raw::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
 use crate::fmt;
 use crate::io;
 use crate::marker::PhantomData;
-use crate::mem;
-use crate::mem::forget;
+use crate::mem::{self, ManuallyDrop};
 use crate::sys;
 #[cfg(not(target_vendor = "uwp"))]
 use crate::sys::cvt;
@@ -191,9 +190,7 @@ impl AsRawSocket for OwnedSocket {
 impl IntoRawSocket for OwnedSocket {
     #[inline]
     fn into_raw_socket(self) -> RawSocket {
-        let socket = self.socket;
-        forget(self);
-        socket
+        ManuallyDrop::new(self).socket
     }
 }
 
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index d5121a554bf..0cef862549c 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -2079,10 +2079,8 @@ impl AsRef<OsStr> for PathBuf {
 #[stable(feature = "rust1", since = "1.0.0")]
 // `Path::new` current implementation relies
 // on `Path` being layout-compatible with `OsStr`.
-// However, `Path` layout is considered an implementation detail and must not be relied upon. We
-// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
-// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
-#[cfg_attr(not(doc), repr(transparent))]
+// However, `Path` layout is considered an implementation detail and must not be relied upon.
+#[repr(transparent)]
 pub struct Path {
     inner: OsStr,
 }
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index deb4a8fa7ee..307a543c9d2 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -16,9 +16,11 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 #![allow(unused_macros)]
 
+#[rustfmt::skip]
 pub use crate::panicking::{begin_panic, panic_count};
 pub use core::panicking::{panic_display, panic_fmt};
 
+#[rustfmt::skip]
 use crate::sync::Once;
 use crate::sys;
 use crate::thread::{self, Thread};
diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs
index a244b953d2a..3723f03081c 100644
--- a/library/std/src/sys/pal/hermit/thread.rs
+++ b/library/std/src/sys/pal/hermit/thread.rs
@@ -3,7 +3,7 @@
 use super::hermit_abi;
 use crate::ffi::CStr;
 use crate::io;
-use crate::mem;
+use crate::mem::ManuallyDrop;
 use crate::num::NonZero;
 use crate::ptr;
 use crate::time::Duration;
@@ -90,9 +90,7 @@ impl Thread {
 
     #[inline]
     pub fn into_id(self) -> Tid {
-        let id = self.tid;
-        mem::forget(self);
-        id
+        ManuallyDrop::new(self).tid
     }
 }
 
diff --git a/library/std/src/sys/pal/sgx/abi/tls/mod.rs b/library/std/src/sys/pal/sgx/abi/tls/mod.rs
index 8a9ea4ac00d..bab59a3422d 100644
--- a/library/std/src/sys/pal/sgx/abi/tls/mod.rs
+++ b/library/std/src/sys/pal/sgx/abi/tls/mod.rs
@@ -95,8 +95,8 @@ impl Tls {
     #[allow(unused)]
     pub unsafe fn activate_persistent(self: Box<Self>) {
         // FIXME: Needs safety information. See entry.S for `set_tls_ptr` definition.
-        unsafe { set_tls_ptr(core::ptr::addr_of!(*self) as _) };
-        mem::forget(self);
+        let ptr = Box::into_raw(self).cast_const().cast::<u8>();
+        unsafe { set_tls_ptr(ptr) };
     }
 
     unsafe fn current<'a>() -> &'a Tls {
diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
index f99cea360f1..b625636752c 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
@@ -5,7 +5,7 @@ use crate::cell::UnsafeCell;
 use crate::cmp;
 use crate::convert::TryInto;
 use crate::intrinsics;
-use crate::mem;
+use crate::mem::{self, ManuallyDrop};
 use crate::ops::{CoerceUnsized, Deref, DerefMut, Index, IndexMut};
 use crate::ptr::{self, NonNull};
 use crate::slice;
@@ -176,6 +176,7 @@ unsafe impl<T: UserSafeSized> UserSafe for [T] {
 /// are used solely to indicate intent: a mutable reference is for writing to
 /// user memory, an immutable reference for reading from user memory.
 #[unstable(feature = "sgx_platform", issue = "56975")]
+#[repr(transparent)]
 pub struct UserRef<T: ?Sized>(UnsafeCell<T>);
 /// An owned type in userspace memory. `User<T>` is equivalent to `Box<T>` in
 /// enclave memory. Access to the memory is only allowed by copying to avoid
@@ -266,9 +267,7 @@ where
     /// Converts this value into a raw pointer. The value will no longer be
     /// automatically freed.
     pub fn into_raw(self) -> *mut T {
-        let ret = self.0;
-        mem::forget(self);
-        ret.as_ptr() as _
+        ManuallyDrop::new(self).0.as_ptr() as _
     }
 }
 
diff --git a/library/std/src/sys/pal/sgx/fd.rs b/library/std/src/sys/pal/sgx/fd.rs
index b3686d0e283..c41b527cff7 100644
--- a/library/std/src/sys/pal/sgx/fd.rs
+++ b/library/std/src/sys/pal/sgx/fd.rs
@@ -2,7 +2,7 @@ use fortanix_sgx_abi::Fd;
 
 use super::abi::usercalls;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
-use crate::mem;
+use crate::mem::ManuallyDrop;
 use crate::sys::{AsInner, FromInner, IntoInner};
 
 #[derive(Debug)]
@@ -21,9 +21,7 @@ impl FileDesc {
 
     /// Extracts the actual file descriptor without closing it.
     pub fn into_raw(self) -> Fd {
-        let fd = self.fd;
-        mem::forget(self);
-        fd
+        ManuallyDrop::new(self).fd
     }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
@@ -70,9 +68,7 @@ impl AsInner<Fd> for FileDesc {
 
 impl IntoInner<Fd> for FileDesc {
     fn into_inner(self) -> Fd {
-        let fd = self.fd;
-        mem::forget(self);
-        fd
+        ManuallyDrop::new(self).fd
     }
 }
 
diff --git a/library/std/src/sys/pal/teeos/thread.rs b/library/std/src/sys/pal/teeos/thread.rs
index 7a27d749f1c..b821e98f9cb 100644
--- a/library/std/src/sys/pal/teeos/thread.rs
+++ b/library/std/src/sys/pal/teeos/thread.rs
@@ -1,9 +1,7 @@
-use core::convert::TryInto;
-
 use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
-use crate::mem;
+use crate::mem::{self, ManuallyDrop};
 use crate::num::NonZero;
 use crate::ptr;
 use crate::sys::os;
@@ -115,11 +113,9 @@ impl Thread {
 
     /// must join, because no pthread_detach supported
     pub fn join(self) {
-        unsafe {
-            let ret = libc::pthread_join(self.id, ptr::null_mut());
-            mem::forget(self);
-            assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
-        }
+        let id = self.into_id();
+        let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
+        assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
     }
 
     pub fn id(&self) -> libc::pthread_t {
@@ -127,9 +123,7 @@ impl Thread {
     }
 
     pub fn into_id(self) -> libc::pthread_t {
-        let id = self.id;
-        mem::forget(self);
-        id
+        ManuallyDrop::new(self).id
     }
 }
 
diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/pal/unix/fd.rs
index 10ae3c3ab57..f705bd61442 100644
--- a/library/std/src/sys/pal/unix/fd.rs
+++ b/library/std/src/sys/pal/unix/fd.rs
@@ -125,6 +125,7 @@ impl FileDesc {
         (&mut me).read_to_end(buf)
     }
 
+    #[cfg_attr(target_os = "vxworks", allow(unused_unsafe))]
     pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
         #[cfg(not(any(
             all(target_os = "linux", not(target_env = "musl")),
@@ -318,6 +319,7 @@ impl FileDesc {
         cfg!(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))
     }
 
+    #[cfg_attr(target_os = "vxworks", allow(unused_unsafe))]
     pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
         #[cfg(not(any(
             all(target_os = "linux", not(target_env = "musl")),
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index b323da8d859..c7915e26e3f 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -857,6 +857,7 @@ impl Drop for Dir {
             target_os = "espidf",
             target_os = "fuchsia",
             target_os = "horizon",
+            target_os = "vxworks",
         )))]
         {
             let fd = unsafe { libc::dirfd(self.0) };
@@ -1313,7 +1314,12 @@ impl File {
     }
 
     pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
-        #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
+        #[cfg(not(any(
+            target_os = "redox",
+            target_os = "espidf",
+            target_os = "horizon",
+            target_os = "vxworks"
+        )))]
         let to_timespec = |time: Option<SystemTime>| match time {
             Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts),
             Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_io_error!(
@@ -1327,10 +1333,11 @@ impl File {
             None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
         };
         cfg_if::cfg_if! {
-            if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] {
+            if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "vxworks"))] {
                 // Redox doesn't appear to support `UTIME_OMIT`.
                 // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
                 // the same as for Redox.
+                // `futimens` and `UTIME_OMIT` are a work in progress for vxworks.
                 let _ = times;
                 Err(io::const_io_error!(
                     io::ErrorKind::Unsupported,
@@ -1962,6 +1969,7 @@ pub fn fchown(fd: c_int, uid: u32, gid: u32) -> io::Result<()> {
     Ok(())
 }
 
+#[cfg(not(target_os = "vxworks"))]
 pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> {
     run_path_with_cstr(path, &|path| {
         cvt(unsafe { libc::lchown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })
@@ -1969,11 +1977,23 @@ pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> {
     })
 }
 
+#[cfg(target_os = "vxworks")]
+pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> {
+    let (_, _, _) = (path, uid, gid);
+    Err(io::const_io_error!(io::ErrorKind::Unsupported, "lchown not supported by vxworks"))
+}
+
 #[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))]
 pub fn chroot(dir: &Path) -> io::Result<()> {
     run_path_with_cstr(dir, &|dir| cvt(unsafe { libc::chroot(dir.as_ptr()) }).map(|_| ()))
 }
 
+#[cfg(target_os = "vxworks")]
+pub fn chroot(dir: &Path) -> io::Result<()> {
+    let _ = dir;
+    Err(io::const_io_error!(io::ErrorKind::Unsupported, "chroot not supported by vxworks"))
+}
+
 pub use remove_dir_impl::remove_dir_all;
 
 // Fallback for REDOX, ESP-ID, Horizon, Vita, Vxworks and Miri
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index 262f9c704a8..bdb995876ff 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -164,6 +164,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
             target_os = "emscripten",
             target_os = "fuchsia",
             target_os = "horizon",
+            target_os = "vxworks",
             // Unikraft's `signal` implementation is currently broken:
             // https://github.com/unikraft/lib-musl/issues/57
             target_vendor = "unikraft",
@@ -209,6 +210,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
     target_os = "emscripten",
     target_os = "fuchsia",
     target_os = "horizon",
+    target_os = "vxworks",
 )))]
 static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool =
     crate::sync::atomic::AtomicBool::new(false);
@@ -218,6 +220,7 @@ static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool =
     target_os = "emscripten",
     target_os = "fuchsia",
     target_os = "horizon",
+    target_os = "vxworks",
 )))]
 pub(crate) fn on_broken_pipe_flag_used() -> bool {
     ON_BROKEN_PIPE_FLAG_USED.load(crate::sync::atomic::Ordering::Relaxed)
diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs
index bedb06043a7..eafde51c608 100644
--- a/library/std/src/sys/pal/unix/net.rs
+++ b/library/std/src/sys/pal/unix/net.rs
@@ -214,16 +214,25 @@ impl Socket {
                 }
                 0 => {}
                 _ => {
-                    // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
-                    // for POLLHUP rather than read readiness
-                    if pollfd.revents & libc::POLLHUP != 0 {
-                        let e = self.take_error()?.unwrap_or_else(|| {
-                            io::const_io_error!(
-                                io::ErrorKind::Uncategorized,
-                                "no error set after POLLHUP",
-                            )
-                        });
-                        return Err(e);
+                    if cfg!(target_os = "vxworks") {
+                        // VxWorks poll does not return  POLLHUP or POLLERR in revents. Check if the
+                        // connnection actually succeeded and return ok only when the socket is
+                        // ready and no errors were found.
+                        if let Some(e) = self.take_error()? {
+                            return Err(e);
+                        }
+                    } else {
+                        // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
+                        // for POLLHUP or POLLERR rather than read readiness
+                        if pollfd.revents & (libc::POLLHUP | libc::POLLERR) != 0 {
+                            let e = self.take_error()?.unwrap_or_else(|| {
+                                io::const_io_error!(
+                                    io::ErrorKind::Uncategorized,
+                                    "no error set after POLLHUP",
+                                )
+                            });
+                            return Err(e);
+                        }
                     }
 
                     return Ok(());
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 5007dbd34b4..26b8a0a39dc 100644
--- a/library/std/src/sys/pal/unix/process/process_vxworks.rs
+++ b/library/std/src/sys/pal/unix/process/process_vxworks.rs
@@ -3,8 +3,8 @@ use crate::io::{self, ErrorKind};
 use crate::num::NonZero;
 use crate::sys;
 use crate::sys::cvt;
+use crate::sys::pal::unix::thread;
 use crate::sys::process::process_common::*;
-use crate::sys_common::thread;
 use libc::RTP_ID;
 use libc::{self, c_char, c_int};
 
@@ -68,7 +68,12 @@ impl Command {
                 .as_ref()
                 .map(|c| c.as_ptr())
                 .unwrap_or_else(|| *sys::os::environ() as *const _);
-            let stack_size = thread::min_stack();
+            let stack_size = crate::cmp::max(
+                crate::env::var_os("RUST_MIN_STACK")
+                    .and_then(|s| s.to_str().and_then(|s| s.parse().ok()))
+                    .unwrap_or(thread::DEFAULT_MIN_STACK_SIZE),
+                libc::PTHREAD_STACK_MIN,
+            );
 
             // ensure that access to the environment is synchronized
             let _lock = sys::os::env_read_lock();
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 619f4e4121e..483697b8597 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -1,7 +1,7 @@
 use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
-use crate::mem;
+use crate::mem::{self, ManuallyDrop};
 use crate::num::NonZero;
 use crate::ptr;
 use crate::sys::{os, stack_overflow};
@@ -268,11 +268,9 @@ impl Thread {
     }
 
     pub fn join(self) {
-        unsafe {
-            let ret = libc::pthread_join(self.id, ptr::null_mut());
-            mem::forget(self);
-            assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
-        }
+        let id = self.into_id();
+        let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
+        assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
     }
 
     pub fn id(&self) -> libc::pthread_t {
@@ -280,9 +278,7 @@ impl Thread {
     }
 
     pub fn into_id(self) -> libc::pthread_t {
-        let id = self.id;
-        mem::forget(self);
-        id
+        ManuallyDrop::new(self).id
     }
 }
 
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs
index 975eef2451f..2a3a39aafa7 100644
--- a/library/std/src/sys/pal/wasi/thread.rs
+++ b/library/std/src/sys/pal/wasi/thread.rs
@@ -172,12 +172,10 @@ impl Thread {
     pub fn join(self) {
         cfg_if::cfg_if! {
             if #[cfg(target_feature = "atomics")] {
-                unsafe {
-                    let ret = libc::pthread_join(self.id, ptr::null_mut());
-                    mem::forget(self);
-                    if ret != 0 {
-                        rtabort!("failed to join thread: {}", io::Error::from_raw_os_error(ret));
-                    }
+                let id = mem::ManuallyDrop::new(self).id;
+                let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
+                if ret != 0 {
+                    rtabort!("failed to join thread: {}", io::Error::from_raw_os_error(ret));
                 }
             } else {
                 self.0
diff --git a/library/std/src/sys/pal/windows/alloc.rs b/library/std/src/sys/pal/windows/alloc.rs
index 987be6b69ee..020a2a4f3a2 100644
--- a/library/std/src/sys/pal/windows/alloc.rs
+++ b/library/std/src/sys/pal/windows/alloc.rs
@@ -37,7 +37,7 @@ windows_targets::link!("kernel32.dll" "system" fn GetProcessHeap() -> c::HANDLE)
 // Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
 //
 // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc
-windows_targets::link!("kernel32.dll" "system" fn HeapAlloc(hheap: c::HANDLE, dwflags: u32, dwbytes: usize) -> *mut core::ffi::c_void);
+windows_targets::link!("kernel32.dll" "system" fn HeapAlloc(hheap: c::HANDLE, dwflags: u32, dwbytes: usize) -> *mut c_void);
 
 // Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`,
 // to a block of at least `dwBytes` bytes, either shrinking the block in place,
@@ -61,9 +61,9 @@ windows_targets::link!("kernel32.dll" "system" fn HeapAlloc(hheap: c::HANDLE, dw
 windows_targets::link!("kernel32.dll" "system" fn HeapReAlloc(
     hheap: c::HANDLE,
     dwflags : u32,
-    lpmem: *const core::ffi::c_void,
+    lpmem: *const c_void,
     dwbytes: usize
-) -> *mut core::ffi::c_void);
+) -> *mut c_void);
 
 // Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`.
 // Returns a nonzero value if the operation is successful, and zero if the operation fails.
@@ -79,7 +79,7 @@ windows_targets::link!("kernel32.dll" "system" fn HeapReAlloc(
 // Note that `lpMem` is allowed to be null, which will not cause the operation to fail.
 //
 // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
-windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap: c::HANDLE, dwflags: u32, lpmem: *const core::ffi::c_void) -> c::BOOL);
+windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap: c::HANDLE, dwflags: u32, lpmem: *const c_void) -> c::BOOL);
 
 // Cached handle to the default heap of the current process.
 // Either a non-null handle returned by `GetProcessHeap`, or null when not yet initialized or `GetProcessHeap` failed.
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index f8d8398b825..f7ec17fde22 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -4,12 +4,10 @@
 #![cfg_attr(test, allow(dead_code))]
 #![unstable(issue = "none", feature = "windows_c")]
 #![allow(clippy::style)]
-#![allow(unsafe_op_in_unsafe_fn)]
 
-use crate::ffi::CStr;
-use crate::mem;
-use crate::os::raw::{c_uint, c_ulong, c_ushort, c_void};
-use crate::ptr;
+use core::ffi::{c_uint, c_ulong, c_ushort, c_void, CStr};
+use core::mem;
+use core::ptr;
 
 pub(super) mod windows_targets;
 
@@ -136,26 +134,26 @@ compat_fn_with_fallback! {
     // >= Win10 1607
     // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
     pub fn SetThreadDescription(hthread: HANDLE, lpthreaddescription: PCWSTR) -> HRESULT {
-        SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL
+        unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL }
     }
 
     // >= Win10 1607
     // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreaddescription
     pub fn GetThreadDescription(hthread: HANDLE, lpthreaddescription: *mut PWSTR) -> HRESULT {
-        SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL
+        unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL }
     }
 
     // >= Win8 / Server 2012
     // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime
     #[cfg(target_vendor = "win7")]
     pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () {
-        GetSystemTimeAsFileTime(lpsystemtimeasfiletime)
+        unsafe { GetSystemTimeAsFileTime(lpsystemtimeasfiletime) }
     }
 
     // >= Win11 / Server 2022
     // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a
     pub fn GetTempPath2W(bufferlength: u32, buffer: PWSTR) -> u32 {
-        GetTempPathW(bufferlength, buffer)
+        unsafe {  GetTempPathW(bufferlength, buffer) }
     }
 }
 
@@ -188,12 +186,12 @@ extern "system" {
 compat_fn_optional! {
     crate::sys::compat::load_synch_functions();
     pub fn WaitOnAddress(
-        address: *const ::core::ffi::c_void,
-        compareaddress: *const ::core::ffi::c_void,
+        address: *const c_void,
+        compareaddress: *const c_void,
         addresssize: usize,
         dwmilliseconds: u32
     ) -> BOOL;
-    pub fn WakeByAddressSingle(address: *const ::core::ffi::c_void);
+    pub fn WakeByAddressSingle(address: *const c_void);
 }
 
 #[cfg(any(target_vendor = "win7", target_vendor = "uwp"))]
@@ -240,7 +238,7 @@ compat_fn_with_fallback! {
         shareaccess: FILE_SHARE_MODE,
         createdisposition: NTCREATEFILE_CREATE_DISPOSITION,
         createoptions: NTCREATEFILE_CREATE_OPTIONS,
-        eabuffer: *const ::core::ffi::c_void,
+        eabuffer: *const c_void,
         ealength: u32
     ) -> NTSTATUS {
         STATUS_NOT_IMPLEMENTED
@@ -250,9 +248,9 @@ compat_fn_with_fallback! {
         filehandle: HANDLE,
         event: HANDLE,
         apcroutine: PIO_APC_ROUTINE,
-        apccontext: *const core::ffi::c_void,
+        apccontext: *const c_void,
         iostatusblock: *mut IO_STATUS_BLOCK,
-        buffer: *mut core::ffi::c_void,
+        buffer: *mut c_void,
         length: u32,
         byteoffset: *const i64,
         key: *const u32
@@ -264,9 +262,9 @@ compat_fn_with_fallback! {
         filehandle: HANDLE,
         event: HANDLE,
         apcroutine: PIO_APC_ROUTINE,
-        apccontext: *const core::ffi::c_void,
+        apccontext: *const c_void,
         iostatusblock: *mut IO_STATUS_BLOCK,
-        buffer: *const core::ffi::c_void,
+        buffer: *const c_void,
         length: u32,
         byteoffset: *const i64,
         key: *const u32
@@ -278,44 +276,3 @@ compat_fn_with_fallback! {
         Status as u32
     }
 }
-
-// # Arm32 shim
-//
-// AddVectoredExceptionHandler and WSAStartup use platform-specific types.
-// However, Microsoft no longer supports thumbv7a so definitions for those targets
-// are not included in the win32 metadata. We work around that by defining them here.
-//
-// Where possible, these definitions should be kept in sync with https://docs.rs/windows-sys
-cfg_if::cfg_if! {
-if #[cfg(not(target_vendor = "uwp"))] {
-    #[link(name = "kernel32")]
-    extern "system" {
-        pub fn AddVectoredExceptionHandler(
-            first: u32,
-            handler: PVECTORED_EXCEPTION_HANDLER,
-        ) -> *mut c_void;
-    }
-    pub type PVECTORED_EXCEPTION_HANDLER = Option<
-        unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32,
-    >;
-    #[repr(C)]
-    pub struct EXCEPTION_POINTERS {
-        pub ExceptionRecord: *mut EXCEPTION_RECORD,
-        pub ContextRecord: *mut CONTEXT,
-    }
-    #[cfg(target_arch = "arm")]
-    pub enum CONTEXT {}
-}}
-// WSAStartup is only redefined here so that we can override WSADATA for Arm32
-windows_targets::link!("ws2_32.dll" "system" fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32);
-#[cfg(target_arch = "arm")]
-#[repr(C)]
-pub struct WSADATA {
-    pub wVersion: u16,
-    pub wHighVersion: u16,
-    pub szDescription: [u8; 257],
-    pub szSystemStatus: [u8; 129],
-    pub iMaxSockets: u16,
-    pub iMaxUdpDg: u16,
-    pub lpVendorInfo: PSTR,
-}
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index de4f1050e92..afacc370c34 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -2176,6 +2176,7 @@ Windows.Win32.Networking.WinSock.WSARecv
 Windows.Win32.Networking.WinSock.WSASend
 Windows.Win32.Networking.WinSock.WSASERVICE_NOT_FOUND
 Windows.Win32.Networking.WinSock.WSASocketW
+Windows.Win32.Networking.WinSock.WSAStartup
 Windows.Win32.Networking.WinSock.WSASYSCALLFAILURE
 Windows.Win32.Networking.WinSock.WSASYSNOTREADY
 Windows.Win32.Networking.WinSock.WSATRY_AGAIN
@@ -2420,6 +2421,7 @@ Windows.Win32.System.Console.STD_HANDLE
 Windows.Win32.System.Console.STD_INPUT_HANDLE
 Windows.Win32.System.Console.STD_OUTPUT_HANDLE
 Windows.Win32.System.Console.WriteConsoleW
+Windows.Win32.System.Diagnostics.Debug.AddVectoredExceptionHandler
 Windows.Win32.System.Diagnostics.Debug.ARM64_NT_NEON128
 Windows.Win32.System.Diagnostics.Debug.CONTEXT
 Windows.Win32.System.Diagnostics.Debug.EXCEPTION_RECORD
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index 29110bde3b4..9f22f548195 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -5,6 +5,7 @@ windows_targets::link!("advapi32.dll" "system" fn OpenProcessToken(processhandle
 windows_targets::link!("advapi32.dll" "system" "SystemFunction036" fn RtlGenRandom(randombuffer : *mut core::ffi::c_void, randombufferlength : u32) -> BOOLEAN);
 windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockExclusive(srwlock : *mut SRWLOCK));
 windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockShared(srwlock : *mut SRWLOCK));
+windows_targets::link!("kernel32.dll" "system" fn AddVectoredExceptionHandler(first : u32, handler : PVECTORED_EXCEPTION_HANDLER) -> *mut core::ffi::c_void);
 windows_targets::link!("kernel32.dll" "system" fn CancelIo(hfile : HANDLE) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn CloseHandle(hobject : HANDLE) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn CompareStringOrdinal(lpstring1 : PCWSTR, cchcount1 : i32, lpstring2 : PCWSTR, cchcount2 : i32, bignorecase : BOOL) -> COMPARESTRING_RESULT);
@@ -114,6 +115,7 @@ windows_targets::link!("ws2_32.dll" "system" fn WSAGetLastError() -> WSA_ERROR);
 windows_targets::link!("ws2_32.dll" "system" fn WSARecv(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytesrecvd : *mut u32, lpflags : *mut u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn WSASend(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytessent : *mut u32, dwflags : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn WSASocketW(af : i32, r#type : i32, protocol : i32, lpprotocolinfo : *const WSAPROTOCOL_INFOW, g : u32, dwflags : u32) -> SOCKET);
+windows_targets::link!("ws2_32.dll" "system" fn WSAStartup(wversionrequested : u16, lpwsadata : *mut WSADATA) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn accept(s : SOCKET, addr : *mut SOCKADDR, addrlen : *mut i32) -> SOCKET);
 windows_targets::link!("ws2_32.dll" "system" fn bind(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn closesocket(s : SOCKET) -> i32);
@@ -2284,6 +2286,12 @@ pub type EXCEPTION_DISPOSITION = i32;
 pub const EXCEPTION_MAXIMUM_PARAMETERS: u32 = 15u32;
 #[repr(C)]
 #[derive(Clone, Copy)]
+pub struct EXCEPTION_POINTERS {
+    pub ExceptionRecord: *mut EXCEPTION_RECORD,
+    pub ContextRecord: *mut CONTEXT,
+}
+#[repr(C)]
+#[derive(Clone, Copy)]
 pub struct EXCEPTION_RECORD {
     pub ExceptionCode: NTSTATUS,
     pub ExceptionFlags: u32,
@@ -2860,6 +2868,8 @@ pub type PTIMERAPCROUTINE = Option<
         dwtimerhighvalue: u32,
     ),
 >;
+pub type PVECTORED_EXCEPTION_HANDLER =
+    Option<unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32>;
 pub type PWSTR = *mut u16;
 pub const READ_CONTROL: FILE_ACCESS_RIGHTS = 131072u32;
 pub const REALTIME_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 256u32;
@@ -3292,5 +3302,19 @@ pub struct XSAVE_FORMAT {
     pub XmmRegisters: [M128A; 8],
     pub Reserved4: [u8; 224],
 }
+
+#[cfg(target_arch = "arm")]
+#[repr(C)]
+pub struct WSADATA {
+    pub wVersion: u16,
+    pub wHighVersion: u16,
+    pub szDescription: [u8; 257],
+    pub szSystemStatus: [u8; 129],
+    pub iMaxSockets: u16,
+    pub iMaxUdpDg: u16,
+    pub lpVendorInfo: PSTR,
+}
+#[cfg(target_arch = "arm")]
+pub enum CONTEXT {}
 // ignore-tidy-filelength
 use super::windows_targets;
diff --git a/library/std/src/sys/pal/windows/compat.rs b/library/std/src/sys/pal/windows/compat.rs
index 49fa1603f3e..75232dfc0b0 100644
--- a/library/std/src/sys/pal/windows/compat.rs
+++ b/library/std/src/sys/pal/windows/compat.rs
@@ -158,8 +158,10 @@ macro_rules! compat_fn_with_fallback {
             static PTR: AtomicPtr<c_void> = AtomicPtr::new(load as *mut _);
 
             unsafe extern "system" fn load($($argname: $argtype),*) -> $rettype {
-                let func = load_from_module(Module::new($module));
-                func($($argname),*)
+                unsafe {
+                    let func = load_from_module(Module::new($module));
+                    func($($argname),*)
+                }
             }
 
             fn load_from_module(module: Option<Module>) -> F {
@@ -182,8 +184,10 @@ macro_rules! compat_fn_with_fallback {
 
             #[inline(always)]
             pub unsafe fn call($($argname: $argtype),*) -> $rettype {
-                let func: F = mem::transmute(PTR.load(Ordering::Relaxed));
-                func($($argname),*)
+                unsafe {
+                    let func: F = mem::transmute(PTR.load(Ordering::Relaxed));
+                    func($($argname),*)
+                }
             }
         }
         #[allow(unused)]
@@ -225,7 +229,7 @@ macro_rules! compat_fn_optional {
             }
             #[inline]
             pub unsafe extern "system" fn $symbol($($argname: $argtype),*) $(-> $rettype)? {
-                $symbol::option().unwrap()($($argname),*)
+                unsafe { $symbol::option().unwrap()($($argname),*) }
             }
         )+
     )
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index 15d446786ad..ea19bd1e961 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -416,8 +416,8 @@ impl File {
                     dwHighDateTime: (info.LastWriteTime >> 32) as u32,
                 },
                 change_time: Some(c::FILETIME {
-                    dhLowDateTime: info.ChangeTime as c::DWORD,
-                    dhHighDateTime: (info.ChangeTime >> 32) as c::DWORD,
+                    dwLowDateTime: info.ChangeTime as u32,
+                    dwHighDateTime: (info.ChangeTime >> 32) as u32,
                 }),
                 file_size: 0,
                 reparse_tag: 0,
diff --git a/library/std/src/sys/pal/windows/handle.rs b/library/std/src/sys/pal/windows/handle.rs
index 94408f69e25..e5b2da69782 100644
--- a/library/std/src/sys/pal/windows/handle.rs
+++ b/library/std/src/sys/pal/windows/handle.rs
@@ -3,16 +3,17 @@
 #[cfg(test)]
 mod tests;
 
-use crate::cmp;
 use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut, Read};
-use crate::mem;
 use crate::os::windows::io::{
     AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle,
 };
-use crate::ptr;
 use crate::sys::c;
 use crate::sys::cvt;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
+use core::cmp;
+use core::ffi::c_void;
+use core::mem;
+use core::ptr;
 
 /// An owned container for `HANDLE` object, closing them on Drop.
 ///
@@ -255,7 +256,7 @@ impl Handle {
                 None,
                 ptr::null_mut(),
                 &mut io_status,
-                buf.cast::<core::ffi::c_void>(),
+                buf.cast::<c_void>(),
                 len,
                 offset.as_ref().map(|n| ptr::from_ref(n).cast::<i64>()).unwrap_or(ptr::null()),
                 ptr::null(),
@@ -305,7 +306,7 @@ impl Handle {
                 None,
                 ptr::null_mut(),
                 &mut io_status,
-                buf.as_ptr().cast::<core::ffi::c_void>(),
+                buf.as_ptr().cast::<c_void>(),
                 len,
                 offset.as_ref().map(|n| ptr::from_ref(n).cast::<i64>()).unwrap_or(ptr::null()),
                 ptr::null(),
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index b85a8318bcb..881ca17936d 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -1,5 +1,5 @@
 #![allow(missing_docs, nonstandard_style)]
-#![deny(unsafe_op_in_unsafe_fn)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 use crate::ffi::{OsStr, OsString};
 use crate::io::ErrorKind;
diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs
index 0dc53550ca9..1fb85a10179 100644
--- a/library/std/src/sys/personality/gcc.rs
+++ b/library/std/src/sys/personality/gcc.rs
@@ -35,6 +35,7 @@
 //!
 //! Once stack has been unwound down to the handler frame level, unwinding stops
 //! and the last personality routine transfers control to the catch block.
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 use super::dwarf::eh::{self, EHAction, EHContext};
 use crate::ffi::c_int;
@@ -92,107 +93,116 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1
 // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
 
 cfg_if::cfg_if! {
-    if #[cfg(all(not(all(target_vendor = "apple", not(target_os = "watchos"))), target_arch = "arm", not(target_os = "netbsd")))] {
-        // ARM EHABI personality routine.
-        // https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
-        //
-        // Apple 32-bit ARM (but not watchOS) uses the default routine instead
-        // since it uses SjLj unwinding.
+    if #[cfg(all(
+            target_arch = "arm",
+            not(all(target_vendor = "apple", not(target_os = "watchos"))),
+            not(target_os = "netbsd"),
+        ))] {
+        /// personality fn called by [ARM EHABI][armeabi-eh]
+        ///
+        /// Apple 32-bit ARM (but not watchOS) uses the default routine instead
+        /// since it uses "setjmp-longjmp" unwinding.
+        ///
+        /// [armeabi-eh]: https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
         #[lang = "eh_personality"]
         unsafe extern "C" fn rust_eh_personality(
             state: uw::_Unwind_State,
             exception_object: *mut uw::_Unwind_Exception,
             context: *mut uw::_Unwind_Context,
         ) -> uw::_Unwind_Reason_Code {
-            let state = state as c_int;
-            let action = state & uw::_US_ACTION_MASK as c_int;
-            let search_phase = if action == uw::_US_VIRTUAL_UNWIND_FRAME as c_int {
-                // Backtraces on ARM will call the personality routine with
-                // state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
-                // we want to continue unwinding the stack, otherwise all our backtraces
-                // would end at __rust_try
-                if state & uw::_US_FORCE_UNWIND as c_int != 0 {
+            unsafe {
+                let state = state as c_int;
+                let action = state & uw::_US_ACTION_MASK as c_int;
+                let search_phase = if action == uw::_US_VIRTUAL_UNWIND_FRAME as c_int {
+                    // Backtraces on ARM will call the personality routine with
+                    // state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
+                    // we want to continue unwinding the stack, otherwise all our backtraces
+                    // would end at __rust_try
+                    if state & uw::_US_FORCE_UNWIND as c_int != 0 {
+                        return continue_unwind(exception_object, context);
+                    }
+                    true
+                } else if action == uw::_US_UNWIND_FRAME_STARTING as c_int {
+                    false
+                } else if action == uw::_US_UNWIND_FRAME_RESUME as c_int {
                     return continue_unwind(exception_object, context);
-                }
-                true
-            } else if action == uw::_US_UNWIND_FRAME_STARTING as c_int {
-                false
-            } else if action == uw::_US_UNWIND_FRAME_RESUME as c_int {
-                return continue_unwind(exception_object, context);
-            } else {
-                return uw::_URC_FAILURE;
-            };
+                } else {
+                    return uw::_URC_FAILURE;
+                };
 
-            // The DWARF unwinder assumes that _Unwind_Context holds things like the function
-            // and LSDA pointers, however ARM EHABI places them into the exception object.
-            // To preserve signatures of functions like _Unwind_GetLanguageSpecificData(), which
-            // take only the context pointer, GCC personality routines stash a pointer to
-            // exception_object in the context, using location reserved for ARM's
-            // "scratch register" (r12).
-            uw::_Unwind_SetGR(context, uw::UNWIND_POINTER_REG, exception_object as uw::_Unwind_Ptr);
-            // ...A more principled approach would be to provide the full definition of ARM's
-            // _Unwind_Context in our libunwind bindings and fetch the required data from there
-            // directly, bypassing DWARF compatibility functions.
+                // The DWARF unwinder assumes that _Unwind_Context holds things like the function
+                // and LSDA pointers, however ARM EHABI places them into the exception object.
+                // To preserve signatures of functions like _Unwind_GetLanguageSpecificData(), which
+                // take only the context pointer, GCC personality routines stash a pointer to
+                // exception_object in the context, using location reserved for ARM's
+                // "scratch register" (r12).
+                uw::_Unwind_SetGR(context, uw::UNWIND_POINTER_REG, exception_object as uw::_Unwind_Ptr);
+                // ...A more principled approach would be to provide the full definition of ARM's
+                // _Unwind_Context in our libunwind bindings and fetch the required data from there
+                // directly, bypassing DWARF compatibility functions.
 
-            let eh_action = match find_eh_action(context) {
-                Ok(action) => action,
-                Err(_) => return uw::_URC_FAILURE,
-            };
-            if search_phase {
-                match eh_action {
-                    EHAction::None | EHAction::Cleanup(_) => {
-                        return continue_unwind(exception_object, context);
-                    }
-                    EHAction::Catch(_) | EHAction::Filter(_) => {
-                        // EHABI requires the personality routine to update the
-                        // SP value in the barrier cache of the exception object.
-                        (*exception_object).private[5] =
-                            uw::_Unwind_GetGR(context, uw::UNWIND_SP_REG);
-                        return uw::_URC_HANDLER_FOUND;
+                let eh_action = match find_eh_action(context) {
+                    Ok(action) => action,
+                    Err(_) => return uw::_URC_FAILURE,
+                };
+                if search_phase {
+                    match eh_action {
+                        EHAction::None | EHAction::Cleanup(_) => {
+                            return continue_unwind(exception_object, context);
+                        }
+                        EHAction::Catch(_) | EHAction::Filter(_) => {
+                            // EHABI requires the personality routine to update the
+                            // SP value in the barrier cache of the exception object.
+                            (*exception_object).private[5] =
+                                uw::_Unwind_GetGR(context, uw::UNWIND_SP_REG);
+                            return uw::_URC_HANDLER_FOUND;
+                        }
+                        EHAction::Terminate => return uw::_URC_FAILURE,
                     }
-                    EHAction::Terminate => return uw::_URC_FAILURE,
-                }
-            } else {
-                match eh_action {
-                    EHAction::None => return continue_unwind(exception_object, context),
-                    EHAction::Filter(_) if state & uw::_US_FORCE_UNWIND as c_int != 0 => return continue_unwind(exception_object, context),
-                    EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
-                        uw::_Unwind_SetGR(
-                            context,
-                            UNWIND_DATA_REG.0,
-                            exception_object as uw::_Unwind_Ptr,
-                        );
-                        uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, core::ptr::null());
-                        uw::_Unwind_SetIP(context, lpad);
-                        return uw::_URC_INSTALL_CONTEXT;
+                } else {
+                    match eh_action {
+                        EHAction::None => return continue_unwind(exception_object, context),
+                        EHAction::Filter(_) if state & uw::_US_FORCE_UNWIND as c_int != 0 => return continue_unwind(exception_object, context),
+                        EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
+                            uw::_Unwind_SetGR(
+                                context,
+                                UNWIND_DATA_REG.0,
+                                exception_object as uw::_Unwind_Ptr,
+                            );
+                            uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, core::ptr::null());
+                            uw::_Unwind_SetIP(context, lpad);
+                            return uw::_URC_INSTALL_CONTEXT;
+                        }
+                        EHAction::Terminate => return uw::_URC_FAILURE,
                     }
-                    EHAction::Terminate => return uw::_URC_FAILURE,
                 }
-            }
 
-            // On ARM EHABI the personality routine is responsible for actually
-            // unwinding a single stack frame before returning (ARM EHABI Sec. 6.1).
-            unsafe fn continue_unwind(
-                exception_object: *mut uw::_Unwind_Exception,
-                context: *mut uw::_Unwind_Context,
-            ) -> uw::_Unwind_Reason_Code {
-                if __gnu_unwind_frame(exception_object, context) == uw::_URC_NO_REASON {
-                    uw::_URC_CONTINUE_UNWIND
-                } else {
-                    uw::_URC_FAILURE
-                }
-            }
-            // defined in libgcc
-            extern "C" {
-                fn __gnu_unwind_frame(
+                // On ARM EHABI the personality routine is responsible for actually
+                // unwinding a single stack frame before returning (ARM EHABI Sec. 6.1).
+                unsafe fn continue_unwind(
                     exception_object: *mut uw::_Unwind_Exception,
                     context: *mut uw::_Unwind_Context,
-                ) -> uw::_Unwind_Reason_Code;
+                ) -> uw::_Unwind_Reason_Code {
+                    unsafe {
+                        if __gnu_unwind_frame(exception_object, context) == uw::_URC_NO_REASON {
+                            uw::_URC_CONTINUE_UNWIND
+                        } else {
+                            uw::_URC_FAILURE
+                        }
+                    }
+                }
+                // defined in libgcc
+                extern "C" {
+                    fn __gnu_unwind_frame(
+                        exception_object: *mut uw::_Unwind_Exception,
+                        context: *mut uw::_Unwind_Context,
+                    ) -> uw::_Unwind_Reason_Code;
+                }
             }
         }
     } else {
-        // Default personality routine, which is used directly on most targets
-        // and indirectly on Windows x86_64 via SEH.
+        /// Default personality routine, which is used directly on most targets
+        /// and indirectly on Windows x86_64 and AArch64 via SEH.
         unsafe extern "C" fn rust_eh_personality_impl(
             version: c_int,
             actions: uw::_Unwind_Action,
@@ -200,43 +210,49 @@ cfg_if::cfg_if! {
             exception_object: *mut uw::_Unwind_Exception,
             context: *mut uw::_Unwind_Context,
         ) -> uw::_Unwind_Reason_Code {
-            if version != 1 {
-                return uw::_URC_FATAL_PHASE1_ERROR;
-            }
-            let eh_action = match find_eh_action(context) {
-                Ok(action) => action,
-                Err(_) => return uw::_URC_FATAL_PHASE1_ERROR,
-            };
-            if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
-                match eh_action {
-                    EHAction::None | EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
-                    EHAction::Catch(_) | EHAction::Filter(_) => uw::_URC_HANDLER_FOUND,
-                    EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
+            unsafe {
+                if version != 1 {
+                    return uw::_URC_FATAL_PHASE1_ERROR;
                 }
-            } else {
-                match eh_action {
-                    EHAction::None => uw::_URC_CONTINUE_UNWIND,
-                    // Forced unwinding hits a terminate action.
-                    EHAction::Filter(_) if actions as i32 & uw::_UA_FORCE_UNWIND as i32 != 0 => uw::_URC_CONTINUE_UNWIND,
-                    EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
-                        uw::_Unwind_SetGR(
-                            context,
-                            UNWIND_DATA_REG.0,
-                            exception_object.cast(),
-                        );
-                        uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, core::ptr::null());
-                        uw::_Unwind_SetIP(context, lpad);
-                        uw::_URC_INSTALL_CONTEXT
+                let eh_action = match find_eh_action(context) {
+                    Ok(action) => action,
+                    Err(_) => return uw::_URC_FATAL_PHASE1_ERROR,
+                };
+                if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
+                    match eh_action {
+                        EHAction::None | EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
+                        EHAction::Catch(_) | EHAction::Filter(_) => uw::_URC_HANDLER_FOUND,
+                        EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
+                    }
+                } else {
+                    match eh_action {
+                        EHAction::None => uw::_URC_CONTINUE_UNWIND,
+                        // Forced unwinding hits a terminate action.
+                        EHAction::Filter(_) if actions as i32 & uw::_UA_FORCE_UNWIND as i32 != 0 => uw::_URC_CONTINUE_UNWIND,
+                        EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
+                            uw::_Unwind_SetGR(
+                                context,
+                                UNWIND_DATA_REG.0,
+                                exception_object.cast(),
+                            );
+                            uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, core::ptr::null());
+                            uw::_Unwind_SetIP(context, lpad);
+                            uw::_URC_INSTALL_CONTEXT
+                        }
+                        EHAction::Terminate => uw::_URC_FATAL_PHASE2_ERROR,
                     }
-                    EHAction::Terminate => uw::_URC_FATAL_PHASE2_ERROR,
                 }
             }
         }
 
         cfg_if::cfg_if! {
             if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] {
-                // On x86_64 MinGW targets, the unwinding mechanism is SEH however the unwind
-                // handler data (aka LSDA) uses GCC-compatible encoding.
+                /// personality fn called by [Windows Structured Exception Handling][windows-eh]
+                ///
+                /// On x86_64 and AArch64 MinGW targets, the unwinding mechanism is SEH,
+                /// however the unwind handler data (aka LSDA) uses GCC-compatible encoding
+                ///
+                /// [windows-eh]: https://learn.microsoft.com/en-us/cpp/cpp/structured-exception-handling-c-cpp?view=msvc-170
                 #[lang = "eh_personality"]
                 #[allow(nonstandard_style)]
                 unsafe extern "C" fn rust_eh_personality(
@@ -245,16 +261,33 @@ cfg_if::cfg_if! {
                     contextRecord: *mut uw::CONTEXT,
                     dispatcherContext: *mut uw::DISPATCHER_CONTEXT,
                 ) -> uw::EXCEPTION_DISPOSITION {
-                    uw::_GCC_specific_handler(
-                        exceptionRecord,
-                        establisherFrame,
-                        contextRecord,
-                        dispatcherContext,
-                        rust_eh_personality_impl,
-                    )
+                    // SAFETY: the cfg is still target_os = "windows" and target_env = "gnu",
+                    // which means that this is the correct function to call, passing our impl fn
+                    // as the callback which gets actually used
+                    unsafe {
+                        uw::_GCC_specific_handler(
+                            exceptionRecord,
+                            establisherFrame,
+                            contextRecord,
+                            dispatcherContext,
+                            rust_eh_personality_impl,
+                        )
+                    }
                 }
             } else {
-                // The personality routine for most of our targets.
+                /// personality fn called by [Itanium C++ ABI Exception Handling][itanium-eh]
+                ///
+                /// The personality routine for most non-Windows targets. This will be called by
+                /// the unwinding library:
+                /// - "In the search phase, the framework repeatedly calls the personality routine,
+                ///   with the _UA_SEARCH_PHASE flag as described below, first for the current PC
+                ///   and register state, and then unwinding a frame to a new PC at each step..."
+                /// - "If the search phase reports success, the framework restarts in the cleanup
+                ///    phase. Again, it repeatedly calls the personality routine, with the
+                ///   _UA_CLEANUP_PHASE flag as described below, first for the current PC and
+                ///   register state, and then unwinding a frame to a new PC at each step..."i
+                ///
+                /// [itanium-eh]: https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
                 #[lang = "eh_personality"]
                 unsafe extern "C" fn rust_eh_personality(
                     version: c_int,
@@ -263,13 +296,17 @@ cfg_if::cfg_if! {
                     exception_object: *mut uw::_Unwind_Exception,
                     context: *mut uw::_Unwind_Context,
                 ) -> uw::_Unwind_Reason_Code {
-                    rust_eh_personality_impl(
-                        version,
-                        actions,
-                        exception_class,
-                        exception_object,
-                        context,
-                    )
+                    // SAFETY: the platform support must modify the cfg for the inner fn
+                    // if it needs something different than what is currently invoked.
+                    unsafe {
+                        rust_eh_personality_impl(
+                            version,
+                            actions,
+                            exception_class,
+                            exception_object,
+                            context,
+                        )
+                    }
                 }
             }
         }
@@ -277,18 +314,20 @@ cfg_if::cfg_if! {
 }
 
 unsafe fn find_eh_action(context: *mut uw::_Unwind_Context) -> Result<EHAction, ()> {
-    let lsda = uw::_Unwind_GetLanguageSpecificData(context) as *const u8;
-    let mut ip_before_instr: c_int = 0;
-    let ip = uw::_Unwind_GetIPInfo(context, &mut ip_before_instr);
-    let eh_context = EHContext {
-        // The return address points 1 byte past the call instruction,
-        // which could be in the next IP range in LSDA range table.
-        //
-        // `ip = -1` has special meaning, so use wrapping sub to allow for that
-        ip: if ip_before_instr != 0 { ip } else { ip.wrapping_sub(1) },
-        func_start: uw::_Unwind_GetRegionStart(context),
-        get_text_start: &|| uw::_Unwind_GetTextRelBase(context),
-        get_data_start: &|| uw::_Unwind_GetDataRelBase(context),
-    };
-    eh::find_eh_action(lsda, &eh_context)
+    unsafe {
+        let lsda = uw::_Unwind_GetLanguageSpecificData(context) as *const u8;
+        let mut ip_before_instr: c_int = 0;
+        let ip = uw::_Unwind_GetIPInfo(context, &mut ip_before_instr);
+        let eh_context = EHContext {
+            // The return address points 1 byte past the call instruction,
+            // which could be in the next IP range in LSDA range table.
+            //
+            // `ip = -1` has special meaning, so use wrapping sub to allow for that
+            ip: if ip_before_instr != 0 { ip } else { ip.wrapping_sub(1) },
+            func_start: uw::_Unwind_GetRegionStart(context),
+            get_text_start: &|| uw::_Unwind_GetTextRelBase(context),
+            get_data_start: &|| uw::_Unwind_GetDataRelBase(context),
+        };
+        eh::find_eh_action(lsda, &eh_context)
+    }
 }
diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs
index 95ca67fc2e0..0a82b50ae1a 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -42,6 +42,7 @@ cfg_if::cfg_if! {
         target_os = "hurd",
         target_os = "dragonfly", target_os = "freebsd",
         target_os = "openbsd", target_os = "netbsd",
+        target_os = "solaris", target_os = "illumos",
         target_os = "haiku", target_os = "nto"))] {
         use libc::MSG_NOSIGNAL;
     } else {
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index e9731bc85d6..40c0d44df90 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -165,7 +165,7 @@ use crate::ffi::CStr;
 use crate::fmt;
 use crate::io;
 use crate::marker::PhantomData;
-use crate::mem::{self, forget};
+use crate::mem::{self, forget, ManuallyDrop};
 use crate::num::NonZero;
 use crate::panic;
 use crate::panicking;
@@ -192,22 +192,14 @@ pub use scoped::{scope, Scope, ScopedJoinHandle};
 #[macro_use]
 mod local;
 
-cfg_if::cfg_if! {
-    if #[cfg(test)] {
-        // Avoid duplicating the global state associated with thread-locals between this crate and
-        // realstd. Miri relies on this.
-        pub use realstd::thread::{local_impl, AccessError, LocalKey};
-    } else {
-        #[stable(feature = "rust1", since = "1.0.0")]
-        pub use self::local::{AccessError, LocalKey};
-
-        // Implementation details used by the thread_local!{} macro.
-        #[doc(hidden)]
-        #[unstable(feature = "thread_local_internals", issue = "none")]
-        pub mod local_impl {
-            pub use crate::sys::thread_local::*;
-        }
-    }
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::local::{AccessError, LocalKey};
+
+// Implementation details used by the thread_local!{} macro.
+#[doc(hidden)]
+#[unstable(feature = "thread_local_internals", issue = "none")]
+pub mod local_impl {
+    pub use crate::sys::thread_local::*;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -510,11 +502,10 @@ impl Builder {
                 MaybeDangling(mem::MaybeUninit::new(x))
             }
             fn into_inner(self) -> T {
-                // SAFETY: we are always initialized.
-                let ret = unsafe { self.0.assume_init_read() };
                 // Make sure we don't drop.
-                mem::forget(self);
-                ret
+                let this = ManuallyDrop::new(self);
+                // SAFETY: we are always initialized.
+                unsafe { this.0.assume_init_read() }
             }
         }
         impl<T> Drop for MaybeDangling<T> {