about summary refs log tree commit diff
path: root/library
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-30 17:01:18 +0000
committerbors <bors@rust-lang.org>2024-01-30 17:01:18 +0000
commitf3d71c9249072413f014b378bb5ea79c8a7dc9a7 (patch)
tree6d35d2fb0886ceb2aa7858c88f7694ba2f1e9801 /library
parent5ad7454f7503b6af2800bf4a7c875962cb03f913 (diff)
parent27bc49656462c48f3b98ac1d8ce2b06d446e5ad3 (diff)
downloadrust-f3d71c9249072413f014b378bb5ea79c8a7dc9a7.tar.gz
rust-f3d71c9249072413f014b378bb5ea79c8a7dc9a7.zip
Auto merge of #120496 - GuillaumeGomez:rollup-fmu9jre, r=GuillaumeGomez
Rollup of 11 pull requests

Successful merges:

 - #117906 (Improve display of crate name when hovered)
 - #118533 (Suppress unhelpful diagnostics for unresolved top level attributes)
 - #120293 (Deduplicate more sized errors on call exprs)
 - #120295 (Remove `raw_os_nonzero` feature.)
 - #120310 (adapt test for v0 symbol mangling)
 - #120342 (Remove various `has_errors` or `err_count` uses)
 - #120434 (Revert outdated version of "Add the wasm32-wasi-preview2 target")
 - #120445 (Fix some `Arc` allocator leaks)
 - #120475 (Improve error message when `cargo build` is used to build the compiler)
 - #120476 (Remove some unnecessary check logic for lang items in HIR typeck)
 - #120485 (add missing potential_query_instability for keys and values in hashmap)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'library')
-rw-r--r--library/alloc/src/sync.rs44
-rw-r--r--library/alloc/src/sync/tests.rs65
-rw-r--r--library/core/src/ffi/mod.rs64
-rw-r--r--library/std/src/collections/hash/map.rs3
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/os/mod.rs3
-rw-r--r--library/std/src/os/wasi/mod.rs3
-rw-r--r--library/std/src/os/wasi_preview2/mod.rs5
-rw-r--r--library/std/src/sys/pal/mod.rs3
-rw-r--r--library/std/src/sys/pal/unix/process/process_unix.rs7
-rw-r--r--library/std/src/sys/pal/unix/process/process_unsupported.rs5
-rw-r--r--library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs5
-rw-r--r--library/std/src/sys/pal/unix/process/process_vxworks.rs7
-rw-r--r--library/std/src/sys/pal/wasi/helpers.rs123
-rw-r--r--library/std/src/sys/pal/wasi/mod.rs132
-rw-r--r--library/std/src/sys/pal/wasi_preview2/mod.rs78
-rw-r--r--library/std/src/sys/pal/windows/c.rs4
17 files changed, 233 insertions, 319 deletions
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index d0f98f9c7db..e16574f3d80 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -280,6 +280,12 @@ impl<T: ?Sized> Arc<T> {
 
 impl<T: ?Sized, A: Allocator> Arc<T, A> {
     #[inline]
+    fn internal_into_inner_with_allocator(self) -> (NonNull<ArcInner<T>>, A) {
+        let this = mem::ManuallyDrop::new(self);
+        (this.ptr, unsafe { ptr::read(&this.alloc) })
+    }
+
+    #[inline]
     unsafe fn from_inner_in(ptr: NonNull<ArcInner<T>>, alloc: A) -> Self {
         Self { ptr, phantom: PhantomData, alloc }
     }
@@ -1275,12 +1281,9 @@ impl<T, A: Allocator> Arc<mem::MaybeUninit<T>, A> {
     #[unstable(feature = "new_uninit", issue = "63291")]
     #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
-    pub unsafe fn assume_init(self) -> Arc<T, A>
-    where
-        A: Clone,
-    {
-        let md_self = mem::ManuallyDrop::new(self);
-        unsafe { Arc::from_inner_in(md_self.ptr.cast(), md_self.alloc.clone()) }
+    pub unsafe fn assume_init(self) -> Arc<T, A> {
+        let (ptr, alloc) = self.internal_into_inner_with_allocator();
+        unsafe { Arc::from_inner_in(ptr.cast(), alloc) }
     }
 }
 
@@ -1320,12 +1323,9 @@ impl<T, A: Allocator> Arc<[mem::MaybeUninit<T>], A> {
     #[unstable(feature = "new_uninit", issue = "63291")]
     #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
-    pub unsafe fn assume_init(self) -> Arc<[T], A>
-    where
-        A: Clone,
-    {
-        let md_self = mem::ManuallyDrop::new(self);
-        unsafe { Arc::from_ptr_in(md_self.ptr.as_ptr() as _, md_self.alloc.clone()) }
+    pub unsafe fn assume_init(self) -> Arc<[T], A> {
+        let (ptr, alloc) = self.internal_into_inner_with_allocator();
+        unsafe { Arc::from_ptr_in(ptr.as_ptr() as _, alloc) }
     }
 }
 
@@ -2413,7 +2413,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Arc<T, A> {
     }
 }
 
-impl<A: Allocator + Clone> Arc<dyn Any + Send + Sync, A> {
+impl<A: Allocator> Arc<dyn Any + Send + Sync, A> {
     /// Attempt to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.
     ///
     /// # Examples
@@ -2440,10 +2440,8 @@ impl<A: Allocator + Clone> Arc<dyn Any + Send + Sync, A> {
     {
         if (*self).is::<T>() {
             unsafe {
-                let ptr = self.ptr.cast::<ArcInner<T>>();
-                let alloc = self.alloc.clone();
-                mem::forget(self);
-                Ok(Arc::from_inner_in(ptr, alloc))
+                let (ptr, alloc) = self.internal_into_inner_with_allocator();
+                Ok(Arc::from_inner_in(ptr.cast(), alloc))
             }
         } else {
             Err(self)
@@ -2483,10 +2481,8 @@ impl<A: Allocator + Clone> Arc<dyn Any + Send + Sync, A> {
         T: Any + Send + Sync,
     {
         unsafe {
-            let ptr = self.ptr.cast::<ArcInner<T>>();
-            let alloc = self.alloc.clone();
-            mem::forget(self);
-            Arc::from_inner_in(ptr, alloc)
+            let (ptr, alloc) = self.internal_into_inner_with_allocator();
+            Arc::from_inner_in(ptr.cast(), alloc)
         }
     }
 }
@@ -3442,13 +3438,13 @@ impl From<Arc<str>> for Arc<[u8]> {
 }
 
 #[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
-impl<T, A: Allocator + Clone, const N: usize> TryFrom<Arc<[T], A>> for Arc<[T; N], A> {
+impl<T, A: Allocator, const N: usize> TryFrom<Arc<[T], A>> for Arc<[T; N], A> {
     type Error = Arc<[T], A>;
 
     fn try_from(boxed_slice: Arc<[T], A>) -> Result<Self, Self::Error> {
         if boxed_slice.len() == N {
-            let alloc = boxed_slice.alloc.clone();
-            Ok(unsafe { Arc::from_raw_in(Arc::into_raw(boxed_slice) as *mut [T; N], alloc) })
+            let (ptr, alloc) = boxed_slice.internal_into_inner_with_allocator();
+            Ok(unsafe { Arc::from_inner_in(ptr.cast(), alloc) })
         } else {
             Err(boxed_slice)
         }
diff --git a/library/alloc/src/sync/tests.rs b/library/alloc/src/sync/tests.rs
index d37e45569cf..49eae718c16 100644
--- a/library/alloc/src/sync/tests.rs
+++ b/library/alloc/src/sync/tests.rs
@@ -1,13 +1,15 @@
 use super::*;
 
 use std::clone::Clone;
+use std::mem::MaybeUninit;
 use std::option::Option::None;
+use std::sync::atomic::AtomicUsize;
 use std::sync::atomic::Ordering::SeqCst;
 use std::sync::mpsc::channel;
 use std::sync::Mutex;
 use std::thread;
 
-struct Canary(*mut atomic::AtomicUsize);
+struct Canary(*mut AtomicUsize);
 
 impl Drop for Canary {
     fn drop(&mut self) {
@@ -21,6 +23,37 @@ impl Drop for Canary {
     }
 }
 
+struct AllocCanary<'a>(&'a AtomicUsize);
+
+impl<'a> AllocCanary<'a> {
+    fn new(counter: &'a AtomicUsize) -> Self {
+        counter.fetch_add(1, SeqCst);
+        Self(counter)
+    }
+}
+
+unsafe impl Allocator for AllocCanary<'_> {
+    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
+        std::alloc::Global.allocate(layout)
+    }
+
+    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
+        unsafe { std::alloc::Global.deallocate(ptr, layout) }
+    }
+}
+
+impl Clone for AllocCanary<'_> {
+    fn clone(&self) -> Self {
+        Self::new(self.0)
+    }
+}
+
+impl Drop for AllocCanary<'_> {
+    fn drop(&mut self) {
+        self.0.fetch_sub(1, SeqCst);
+    }
+}
+
 #[test]
 #[cfg_attr(target_os = "emscripten", ignore)]
 fn manually_share_arc() {
@@ -295,16 +328,16 @@ fn weak_self_cyclic() {
 
 #[test]
 fn drop_arc() {
-    let mut canary = atomic::AtomicUsize::new(0);
-    let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize));
+    let mut canary = AtomicUsize::new(0);
+    let x = Arc::new(Canary(&mut canary as *mut AtomicUsize));
     drop(x);
     assert!(canary.load(Acquire) == 1);
 }
 
 #[test]
 fn drop_arc_weak() {
-    let mut canary = atomic::AtomicUsize::new(0);
-    let arc = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize));
+    let mut canary = AtomicUsize::new(0);
+    let arc = Arc::new(Canary(&mut canary as *mut AtomicUsize));
     let arc_weak = Arc::downgrade(&arc);
     assert!(canary.load(Acquire) == 0);
     drop(arc);
@@ -660,3 +693,25 @@ fn arc_drop_dereferenceable_race() {
         thread.join().unwrap();
     }
 }
+
+#[test]
+fn arc_doesnt_leak_allocator() {
+    let counter = AtomicUsize::new(0);
+
+    {
+        let arc: Arc<dyn Any + Send + Sync, _> = Arc::new_in(5usize, AllocCanary::new(&counter));
+        drop(arc.downcast::<usize>().unwrap());
+
+        let arc: Arc<dyn Any + Send + Sync, _> = Arc::new_in(5usize, AllocCanary::new(&counter));
+        drop(unsafe { arc.downcast_unchecked::<usize>() });
+
+        let arc = Arc::new_in(MaybeUninit::<usize>::new(5usize), AllocCanary::new(&counter));
+        drop(unsafe { arc.assume_init() });
+
+        let arc: Arc<[MaybeUninit<usize>], _> =
+            Arc::new_zeroed_slice_in(5, AllocCanary::new(&counter));
+        drop(unsafe { arc.assume_init() });
+    }
+
+    assert_eq!(counter.load(SeqCst), 0);
+}
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index 7340ad90da5..44200926a32 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -11,7 +11,6 @@
 
 use crate::fmt;
 use crate::marker::PhantomData;
-use crate::num::*;
 use crate::ops::{Deref, DerefMut};
 
 #[stable(feature = "core_c_str", since = "1.64.0")]
@@ -19,7 +18,7 @@ pub use self::c_str::{CStr, FromBytesUntilNulError, FromBytesWithNulError};
 
 mod c_str;
 
-macro_rules! type_alias_no_nz {
+macro_rules! type_alias {
     {
       $Docfile:tt, $Alias:ident = $Real:ty;
       $( $Cfg:tt )*
@@ -31,49 +30,24 @@ macro_rules! type_alias_no_nz {
     }
 }
 
-// To verify that the NonZero types in this file's macro invocations correspond
-//
-//  perl -n < library/std/src/os/raw/mod.rs -e 'next unless m/type_alias\!/; die "$_ ?" unless m/, (c_\w+) = (\w+), NonZero_(\w+) = NonZero(\w+)/; die "$_ ?" unless $3 eq $1 and $4 eq ucfirst $2'
-//
-// NB this does not check that the main c_* types are right.
-
-macro_rules! type_alias {
-    {
-      $Docfile:tt, $Alias:ident = $Real:ty, $NZAlias:ident = $NZReal:ty;
-      $( $Cfg:tt )*
-    } => {
-        type_alias_no_nz! { $Docfile, $Alias = $Real; $( $Cfg )* }
-
-        #[doc = concat!("Type alias for `NonZero` version of [`", stringify!($Alias), "`]")]
-        #[unstable(feature = "raw_os_nonzero", issue = "82363")]
-        $( $Cfg )*
-        pub type $NZAlias = $NZReal;
-    }
-}
-
-type_alias! { "c_char.md", c_char = c_char_definition::c_char, NonZero_c_char = c_char_definition::NonZero_c_char;
-#[doc(cfg(all()))] }
+type_alias! { "c_char.md", c_char = c_char_definition::c_char; #[doc(cfg(all()))] }
 
-type_alias! { "c_schar.md", c_schar = i8, NonZero_c_schar = NonZeroI8; }
-type_alias! { "c_uchar.md", c_uchar = u8, NonZero_c_uchar = NonZeroU8; }
-type_alias! { "c_short.md", c_short = i16, NonZero_c_short = NonZeroI16; }
-type_alias! { "c_ushort.md", c_ushort = u16, NonZero_c_ushort = NonZeroU16; }
+type_alias! { "c_schar.md", c_schar = i8; }
+type_alias! { "c_uchar.md", c_uchar = u8; }
+type_alias! { "c_short.md", c_short = i16; }
+type_alias! { "c_ushort.md", c_ushort = u16; }
 
-type_alias! { "c_int.md", c_int = c_int_definition::c_int, NonZero_c_int = c_int_definition::NonZero_c_int;
-#[doc(cfg(all()))] }
-type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint, NonZero_c_uint = c_int_definition::NonZero_c_uint;
-#[doc(cfg(all()))] }
+type_alias! { "c_int.md", c_int = c_int_definition::c_int; #[doc(cfg(all()))] }
+type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint; #[doc(cfg(all()))] }
 
-type_alias! { "c_long.md", c_long = c_long_definition::c_long, NonZero_c_long = c_long_definition::NonZero_c_long;
-#[doc(cfg(all()))] }
-type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong, NonZero_c_ulong = c_long_definition::NonZero_c_ulong;
-#[doc(cfg(all()))] }
+type_alias! { "c_long.md", c_long = c_long_definition::c_long; #[doc(cfg(all()))] }
+type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong; #[doc(cfg(all()))] }
 
-type_alias! { "c_longlong.md", c_longlong = i64, NonZero_c_longlong = NonZeroI64; }
-type_alias! { "c_ulonglong.md", c_ulonglong = u64, NonZero_c_ulonglong = NonZeroU64; }
+type_alias! { "c_longlong.md", c_longlong = i64; }
+type_alias! { "c_ulonglong.md", c_ulonglong = u64; }
 
-type_alias_no_nz! { "c_float.md", c_float = f32; }
-type_alias_no_nz! { "c_double.md", c_double = f64; }
+type_alias! { "c_float.md", c_float = f32; }
+type_alias! { "c_double.md", c_double = f64; }
 
 /// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
 ///
@@ -152,11 +126,9 @@ mod c_char_definition {
             target_os = "horizon"
         ))] {
             pub type c_char = u8;
-            pub type NonZero_c_char = crate::num::NonZeroU8;
         } else {
             // On every other target, c_char is signed.
             pub type c_char = i8;
-            pub type NonZero_c_char = crate::num::NonZeroI8;
         }
     }
 }
@@ -165,14 +137,10 @@ mod c_int_definition {
     cfg_if! {
         if #[cfg(any(target_arch = "avr", target_arch = "msp430"))] {
             pub type c_int = i16;
-            pub type NonZero_c_int = crate::num::NonZeroI16;
             pub type c_uint = u16;
-            pub type NonZero_c_uint = crate::num::NonZeroU16;
         } else {
             pub type c_int = i32;
-            pub type NonZero_c_int = crate::num::NonZeroI32;
             pub type c_uint = u32;
-            pub type NonZero_c_uint = crate::num::NonZeroU32;
         }
     }
 }
@@ -181,15 +149,11 @@ mod c_long_definition {
     cfg_if! {
         if #[cfg(all(target_pointer_width = "64", not(windows)))] {
             pub type c_long = i64;
-            pub type NonZero_c_long = crate::num::NonZeroI64;
             pub type c_ulong = u64;
-            pub type NonZero_c_ulong = crate::num::NonZeroU64;
         } else {
             // The minimal size of `long` in the C standard is 32 bits
             pub type c_long = i32;
-            pub type NonZero_c_long = crate::num::NonZeroI32;
             pub type c_ulong = u32;
-            pub type NonZero_c_ulong = crate::num::NonZeroU32;
         }
     }
 }
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index fc27b6a67bf..0d4c1fa05cc 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -356,6 +356,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// In the current implementation, iterating over keys takes O(capacity) time
     /// instead of O(len) because it internally visits empty buckets too.
+    #[rustc_lint_query_instability]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn keys(&self) -> Keys<'_, K, V> {
         Keys { inner: self.iter() }
@@ -417,6 +418,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// In the current implementation, iterating over values takes O(capacity) time
     /// instead of O(len) because it internally visits empty buckets too.
+    #[rustc_lint_query_instability]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn values(&self) -> Values<'_, K, V> {
         Values { inner: self.iter() }
@@ -449,6 +451,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// In the current implementation, iterating over values takes O(capacity) time
     /// instead of O(len) because it internally visits empty buckets too.
+    #[rustc_lint_query_instability]
     #[stable(feature = "map_values_mut", since = "1.10.0")]
     pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
         ValuesMut { inner: self.iter_mut() }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 2e458562744..ccc7a159231 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -338,7 +338,6 @@
 #![feature(portable_simd)]
 #![feature(prelude_2024)]
 #![feature(ptr_as_uninit)]
-#![feature(raw_os_nonzero)]
 #![feature(slice_internals)]
 #![feature(slice_ptr_get)]
 #![feature(slice_range)]
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index f03e0790305..6e11b92b618 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -85,9 +85,6 @@ pub mod linux;
 #[cfg(any(target_os = "wasi", doc))]
 pub mod wasi;
 
-#[cfg(any(all(target_os = "wasi", target_env = "preview2"), doc))]
-pub mod wasi_preview2;
-
 // windows
 #[cfg(not(all(
     doc,
diff --git a/library/std/src/os/wasi/mod.rs b/library/std/src/os/wasi/mod.rs
index 05c8d30073f..bbaf328f457 100644
--- a/library/std/src/os/wasi/mod.rs
+++ b/library/std/src/os/wasi/mod.rs
@@ -28,8 +28,7 @@
 //! [`OsStr`]: crate::ffi::OsStr
 //! [`OsString`]: crate::ffi::OsString
 
-#![cfg_attr(not(target_env = "preview2"), stable(feature = "rust1", since = "1.0.0"))]
-#![cfg_attr(target_env = "preview2", unstable(feature = "wasm_preview2", issue = "none"))]
+#![stable(feature = "rust1", since = "1.0.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
 #![doc(cfg(target_os = "wasi"))]
 
diff --git a/library/std/src/os/wasi_preview2/mod.rs b/library/std/src/os/wasi_preview2/mod.rs
deleted file mode 100644
index 1d44dd72814..00000000000
--- a/library/std/src/os/wasi_preview2/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//! Platform-specific extensions to `std` for Preview 2 of the WebAssembly System Interface (WASI).
-//!
-//! This module is currently empty, but will be filled over time as wasi-libc support for WASI Preview 2 is stabilized.
-
-#![stable(feature = "raw_ext", since = "1.1.0")]
diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs
index f927d88d46c..041b7c35582 100644
--- a/library/std/src/sys/pal/mod.rs
+++ b/library/std/src/sys/pal/mod.rs
@@ -40,9 +40,6 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "wasi")] {
         mod wasi;
         pub use self::wasi::*;
-    } else if #[cfg(all(target_os = "wasi", target_env = "preview2"))] {
-        mod wasi_preview2;
-        pub use self::wasi_preview2::*;
     } else if #[cfg(target_family = "wasm")] {
         mod wasm;
         pub use self::wasm::*;
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 df0fe2bb9d8..94c4c56bd51 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -1,11 +1,10 @@
 use crate::fmt;
 use crate::io::{self, Error, ErrorKind};
 use crate::mem;
-use crate::num::NonZeroI32;
+use crate::num::{NonZero, NonZeroI32};
 use crate::sys;
 use crate::sys::cvt;
 use crate::sys::process::process_common::*;
-use core::ffi::NonZero_c_int;
 
 #[cfg(target_os = "linux")]
 use crate::os::linux::process::PidFd;
@@ -935,7 +934,7 @@ impl ExitStatus {
         // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
         // true for a platform pretending to be Unix, the tests (our doctests, and also
         // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
-        match NonZero_c_int::try_from(self.0) {
+        match NonZero::try_from(self.0) {
             /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)),
             /* was zero, couldn't convert */ Err(_) => Ok(()),
         }
@@ -1092,7 +1091,7 @@ impl fmt::Display for ExitStatus {
 }
 
 #[derive(PartialEq, Eq, Clone, Copy)]
-pub struct ExitStatusError(NonZero_c_int);
+pub struct ExitStatusError(NonZero<c_int>);
 
 impl Into<ExitStatus> for ExitStatusError {
     fn into(self) -> ExitStatus {
diff --git a/library/std/src/sys/pal/unix/process/process_unsupported.rs b/library/std/src/sys/pal/unix/process/process_unsupported.rs
index 9453c8a384e..89a2a0c6e56 100644
--- a/library/std/src/sys/pal/unix/process/process_unsupported.rs
+++ b/library/std/src/sys/pal/unix/process/process_unsupported.rs
@@ -1,9 +1,8 @@
 use crate::fmt;
 use crate::io;
-use crate::num::NonZeroI32;
+use crate::num::{NonZero, NonZeroI32};
 use crate::sys::pal::unix::unsupported::*;
 use crate::sys::process::process_common::*;
-use core::ffi::NonZero_c_int;
 
 use libc::{c_int, pid_t};
 
@@ -59,7 +58,7 @@ mod wait_status;
 pub use wait_status::ExitStatus;
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitStatusError(NonZero_c_int);
+pub struct ExitStatusError(NonZero<c_int>);
 
 impl Into<ExitStatus> for ExitStatusError {
     fn into(self) -> ExitStatus {
diff --git a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs b/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs
index 72b7ae18cff..e6dfadcf4a4 100644
--- a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs
+++ b/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs
@@ -1,10 +1,9 @@
 //! Emulated wait status for non-Unix #[cfg(unix) platforms
 //!
 //! Separate module to facilitate testing against a real Unix implementation.
-use core::ffi::NonZero_c_int;
-
 use crate::ffi::c_int;
 use crate::fmt;
+use crate::num::NonZero;
 
 use super::ExitStatusError;
 
@@ -50,7 +49,7 @@ impl ExitStatus {
         // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
         // true for a platform pretending to be Unix, the tests (our doctests, and also
         // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
-        match NonZero_c_int::try_from(self.wait_status) {
+        match NonZero::try_from(self.wait_status) {
             /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)),
             /* was zero, couldn't convert */ Err(_) => 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 1ff2b2fb383..5b4e94d0f1b 100644
--- a/library/std/src/sys/pal/unix/process/process_vxworks.rs
+++ b/library/std/src/sys/pal/unix/process/process_vxworks.rs
@@ -1,11 +1,10 @@
 use crate::fmt;
 use crate::io::{self, Error, ErrorKind};
-use crate::num::NonZeroI32;
+use crate::num::{NonZero, NonZeroI32};
 use crate::sys;
 use crate::sys::cvt;
 use crate::sys::process::process_common::*;
 use crate::sys_common::thread;
-use core::ffi::NonZero_c_int;
 use libc::RTP_ID;
 use libc::{self, c_char, c_int};
 
@@ -197,7 +196,7 @@ impl ExitStatus {
         // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
         // true for a platform pretending to be Unix, the tests (our doctests, and also
         // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
-        match NonZero_c_int::try_from(self.0) {
+        match NonZero::try_from(self.0) {
             Ok(failure) => Err(ExitStatusError(failure)),
             Err(_) => Ok(()),
         }
@@ -249,7 +248,7 @@ impl fmt::Display for ExitStatus {
 }
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitStatusError(NonZero_c_int);
+pub struct ExitStatusError(NonZero<c_int>);
 
 impl Into<ExitStatus> for ExitStatusError {
     fn into(self) -> ExitStatus {
diff --git a/library/std/src/sys/pal/wasi/helpers.rs b/library/std/src/sys/pal/wasi/helpers.rs
deleted file mode 100644
index 82149cef8fa..00000000000
--- a/library/std/src/sys/pal/wasi/helpers.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-use crate::io as std_io;
-use crate::mem;
-
-#[inline]
-pub fn is_interrupted(errno: i32) -> bool {
-    errno == wasi::ERRNO_INTR.raw().into()
-}
-
-pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
-    use std_io::ErrorKind;
-
-    let Ok(errno) = u16::try_from(errno) else {
-        return ErrorKind::Uncategorized;
-    };
-
-    macro_rules! match_errno {
-        ($($($errno:ident)|+ => $errkind:ident),*, _ => $wildcard:ident $(,)?) => {
-            match errno {
-                $(e if $(e == ::wasi::$errno.raw())||+ => ErrorKind::$errkind),*,
-                _ => ErrorKind::$wildcard,
-            }
-        };
-    }
-
-    match_errno! {
-        ERRNO_2BIG           => ArgumentListTooLong,
-        ERRNO_ACCES          => PermissionDenied,
-        ERRNO_ADDRINUSE      => AddrInUse,
-        ERRNO_ADDRNOTAVAIL   => AddrNotAvailable,
-        ERRNO_AFNOSUPPORT    => Unsupported,
-        ERRNO_AGAIN          => WouldBlock,
-        //    ALREADY        => "connection already in progress",
-        //    BADF           => "bad file descriptor",
-        //    BADMSG         => "bad message",
-        ERRNO_BUSY           => ResourceBusy,
-        //    CANCELED       => "operation canceled",
-        //    CHILD          => "no child processes",
-        ERRNO_CONNABORTED    => ConnectionAborted,
-        ERRNO_CONNREFUSED    => ConnectionRefused,
-        ERRNO_CONNRESET      => ConnectionReset,
-        ERRNO_DEADLK         => Deadlock,
-        //    DESTADDRREQ    => "destination address required",
-        ERRNO_DOM            => InvalidInput,
-        //    DQUOT          => /* reserved */,
-        ERRNO_EXIST          => AlreadyExists,
-        //    FAULT          => "bad address",
-        ERRNO_FBIG           => FileTooLarge,
-        ERRNO_HOSTUNREACH    => HostUnreachable,
-        //    IDRM           => "identifier removed",
-        //    ILSEQ          => "illegal byte sequence",
-        //    INPROGRESS     => "operation in progress",
-        ERRNO_INTR           => Interrupted,
-        ERRNO_INVAL          => InvalidInput,
-        ERRNO_IO             => Uncategorized,
-        //    ISCONN         => "socket is connected",
-        ERRNO_ISDIR          => IsADirectory,
-        ERRNO_LOOP           => FilesystemLoop,
-        //    MFILE          => "file descriptor value too large",
-        ERRNO_MLINK          => TooManyLinks,
-        //    MSGSIZE        => "message too large",
-        //    MULTIHOP       => /* reserved */,
-        ERRNO_NAMETOOLONG    => InvalidFilename,
-        ERRNO_NETDOWN        => NetworkDown,
-        //    NETRESET       => "connection aborted by network",
-        ERRNO_NETUNREACH     => NetworkUnreachable,
-        //    NFILE          => "too many files open in system",
-        //    NOBUFS         => "no buffer space available",
-        ERRNO_NODEV          => NotFound,
-        ERRNO_NOENT          => NotFound,
-        //    NOEXEC         => "executable file format error",
-        //    NOLCK          => "no locks available",
-        //    NOLINK         => /* reserved */,
-        ERRNO_NOMEM          => OutOfMemory,
-        //    NOMSG          => "no message of the desired type",
-        //    NOPROTOOPT     => "protocol not available",
-        ERRNO_NOSPC          => StorageFull,
-        ERRNO_NOSYS          => Unsupported,
-        ERRNO_NOTCONN        => NotConnected,
-        ERRNO_NOTDIR         => NotADirectory,
-        ERRNO_NOTEMPTY       => DirectoryNotEmpty,
-        //    NOTRECOVERABLE => "state not recoverable",
-        //    NOTSOCK        => "not a socket",
-        ERRNO_NOTSUP         => Unsupported,
-        //    NOTTY          => "inappropriate I/O control operation",
-        ERRNO_NXIO           => NotFound,
-        //    OVERFLOW       => "value too large to be stored in data type",
-        //    OWNERDEAD      => "previous owner died",
-        ERRNO_PERM           => PermissionDenied,
-        ERRNO_PIPE           => BrokenPipe,
-        //    PROTO          => "protocol error",
-        ERRNO_PROTONOSUPPORT => Unsupported,
-        //    PROTOTYPE      => "protocol wrong type for socket",
-        //    RANGE          => "result too large",
-        ERRNO_ROFS           => ReadOnlyFilesystem,
-        ERRNO_SPIPE          => NotSeekable,
-        ERRNO_SRCH           => NotFound,
-        //    STALE          => /* reserved */,
-        ERRNO_TIMEDOUT       => TimedOut,
-        ERRNO_TXTBSY         => ResourceBusy,
-        ERRNO_XDEV           => CrossesDevices,
-        ERRNO_NOTCAPABLE     => PermissionDenied,
-        _                    => Uncategorized,
-    }
-}
-
-pub fn abort_internal() -> ! {
-    unsafe { libc::abort() }
-}
-
-pub fn hashmap_random_keys() -> (u64, u64) {
-    let mut ret = (0u64, 0u64);
-    unsafe {
-        let base = &mut ret as *mut (u64, u64) as *mut u8;
-        let len = mem::size_of_val(&ret);
-        wasi::random_get(base, len).expect("random_get failure");
-    }
-    return ret;
-}
-
-#[inline]
-pub(crate) fn err2io(err: wasi::Errno) -> std_io::Error {
-    std_io::Error::from_raw_os_error(err.raw().into())
-}
diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs
index a4b55093bf4..4ffc8ecdd67 100644
--- a/library/std/src/sys/pal/wasi/mod.rs
+++ b/library/std/src/sys/pal/wasi/mod.rs
@@ -14,6 +14,9 @@
 //! compiling for wasm. That way it's a compile time error for something that's
 //! guaranteed to be a runtime error!
 
+use crate::io as std_io;
+use crate::mem;
+
 #[path = "../unix/alloc.rs"]
 pub mod alloc;
 pub mod args;
@@ -69,12 +72,123 @@ cfg_if::cfg_if! {
 mod common;
 pub use common::*;
 
-mod helpers;
-// These exports are listed individually to work around Rust's glob import
-// conflict rules. If we glob export `helpers` and `common` together, then
-// the compiler complains about conflicts.
-pub use helpers::abort_internal;
-pub use helpers::decode_error_kind;
-use helpers::err2io;
-pub use helpers::hashmap_random_keys;
-pub use helpers::is_interrupted;
+#[inline]
+pub fn is_interrupted(errno: i32) -> bool {
+    errno == wasi::ERRNO_INTR.raw().into()
+}
+
+pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
+    use std_io::ErrorKind;
+
+    let Ok(errno) = u16::try_from(errno) else {
+        return ErrorKind::Uncategorized;
+    };
+
+    macro_rules! match_errno {
+        ($($($errno:ident)|+ => $errkind:ident),*, _ => $wildcard:ident $(,)?) => {
+            match errno {
+                $(e if $(e == ::wasi::$errno.raw())||+ => ErrorKind::$errkind),*,
+                _ => ErrorKind::$wildcard,
+            }
+        };
+    }
+
+    match_errno! {
+        ERRNO_2BIG           => ArgumentListTooLong,
+        ERRNO_ACCES          => PermissionDenied,
+        ERRNO_ADDRINUSE      => AddrInUse,
+        ERRNO_ADDRNOTAVAIL   => AddrNotAvailable,
+        ERRNO_AFNOSUPPORT    => Unsupported,
+        ERRNO_AGAIN          => WouldBlock,
+        //    ALREADY        => "connection already in progress",
+        //    BADF           => "bad file descriptor",
+        //    BADMSG         => "bad message",
+        ERRNO_BUSY           => ResourceBusy,
+        //    CANCELED       => "operation canceled",
+        //    CHILD          => "no child processes",
+        ERRNO_CONNABORTED    => ConnectionAborted,
+        ERRNO_CONNREFUSED    => ConnectionRefused,
+        ERRNO_CONNRESET      => ConnectionReset,
+        ERRNO_DEADLK         => Deadlock,
+        //    DESTADDRREQ    => "destination address required",
+        ERRNO_DOM            => InvalidInput,
+        //    DQUOT          => /* reserved */,
+        ERRNO_EXIST          => AlreadyExists,
+        //    FAULT          => "bad address",
+        ERRNO_FBIG           => FileTooLarge,
+        ERRNO_HOSTUNREACH    => HostUnreachable,
+        //    IDRM           => "identifier removed",
+        //    ILSEQ          => "illegal byte sequence",
+        //    INPROGRESS     => "operation in progress",
+        ERRNO_INTR           => Interrupted,
+        ERRNO_INVAL          => InvalidInput,
+        ERRNO_IO             => Uncategorized,
+        //    ISCONN         => "socket is connected",
+        ERRNO_ISDIR          => IsADirectory,
+        ERRNO_LOOP           => FilesystemLoop,
+        //    MFILE          => "file descriptor value too large",
+        ERRNO_MLINK          => TooManyLinks,
+        //    MSGSIZE        => "message too large",
+        //    MULTIHOP       => /* reserved */,
+        ERRNO_NAMETOOLONG    => InvalidFilename,
+        ERRNO_NETDOWN        => NetworkDown,
+        //    NETRESET       => "connection aborted by network",
+        ERRNO_NETUNREACH     => NetworkUnreachable,
+        //    NFILE          => "too many files open in system",
+        //    NOBUFS         => "no buffer space available",
+        ERRNO_NODEV          => NotFound,
+        ERRNO_NOENT          => NotFound,
+        //    NOEXEC         => "executable file format error",
+        //    NOLCK          => "no locks available",
+        //    NOLINK         => /* reserved */,
+        ERRNO_NOMEM          => OutOfMemory,
+        //    NOMSG          => "no message of the desired type",
+        //    NOPROTOOPT     => "protocol not available",
+        ERRNO_NOSPC          => StorageFull,
+        ERRNO_NOSYS          => Unsupported,
+        ERRNO_NOTCONN        => NotConnected,
+        ERRNO_NOTDIR         => NotADirectory,
+        ERRNO_NOTEMPTY       => DirectoryNotEmpty,
+        //    NOTRECOVERABLE => "state not recoverable",
+        //    NOTSOCK        => "not a socket",
+        ERRNO_NOTSUP         => Unsupported,
+        //    NOTTY          => "inappropriate I/O control operation",
+        ERRNO_NXIO           => NotFound,
+        //    OVERFLOW       => "value too large to be stored in data type",
+        //    OWNERDEAD      => "previous owner died",
+        ERRNO_PERM           => PermissionDenied,
+        ERRNO_PIPE           => BrokenPipe,
+        //    PROTO          => "protocol error",
+        ERRNO_PROTONOSUPPORT => Unsupported,
+        //    PROTOTYPE      => "protocol wrong type for socket",
+        //    RANGE          => "result too large",
+        ERRNO_ROFS           => ReadOnlyFilesystem,
+        ERRNO_SPIPE          => NotSeekable,
+        ERRNO_SRCH           => NotFound,
+        //    STALE          => /* reserved */,
+        ERRNO_TIMEDOUT       => TimedOut,
+        ERRNO_TXTBSY         => ResourceBusy,
+        ERRNO_XDEV           => CrossesDevices,
+        ERRNO_NOTCAPABLE     => PermissionDenied,
+        _                    => Uncategorized,
+    }
+}
+
+pub fn abort_internal() -> ! {
+    unsafe { libc::abort() }
+}
+
+pub fn hashmap_random_keys() -> (u64, u64) {
+    let mut ret = (0u64, 0u64);
+    unsafe {
+        let base = &mut ret as *mut (u64, u64) as *mut u8;
+        let len = mem::size_of_val(&ret);
+        wasi::random_get(base, len).expect("random_get failure");
+    }
+    return ret;
+}
+
+#[inline]
+fn err2io(err: wasi::Errno) -> std_io::Error {
+    std_io::Error::from_raw_os_error(err.raw().into())
+}
diff --git a/library/std/src/sys/pal/wasi_preview2/mod.rs b/library/std/src/sys/pal/wasi_preview2/mod.rs
deleted file mode 100644
index b61695015bb..00000000000
--- a/library/std/src/sys/pal/wasi_preview2/mod.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-//! System bindings for the wasi preview 2 target.
-//!
-//! This is the next evolution of the original wasi target, and is intended to
-//! replace that target over time.
-//!
-//! To begin with, this target mirrors the wasi target 1 to 1, but over
-//! time this will change significantly.
-
-#[path = "../unix/alloc.rs"]
-pub mod alloc;
-#[path = "../wasi/args.rs"]
-pub mod args;
-#[path = "../unix/cmath.rs"]
-pub mod cmath;
-#[path = "../wasi/env.rs"]
-pub mod env;
-#[path = "../wasi/fd.rs"]
-pub mod fd;
-#[path = "../wasi/fs.rs"]
-pub mod fs;
-#[allow(unused)]
-#[path = "../wasm/atomics/futex.rs"]
-pub mod futex;
-#[path = "../wasi/io.rs"]
-pub mod io;
-
-#[path = "../wasi/net.rs"]
-pub mod net;
-#[path = "../wasi/os.rs"]
-pub mod os;
-#[path = "../unix/os_str.rs"]
-pub mod os_str;
-#[path = "../unix/path.rs"]
-pub mod path;
-#[path = "../unsupported/pipe.rs"]
-pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
-#[path = "../wasi/stdio.rs"]
-pub mod stdio;
-#[path = "../wasi/thread.rs"]
-pub mod thread;
-#[path = "../unsupported/thread_local_dtor.rs"]
-pub mod thread_local_dtor;
-#[path = "../unsupported/thread_local_key.rs"]
-pub mod thread_local_key;
-#[path = "../wasi/time.rs"]
-pub mod time;
-
-cfg_if::cfg_if! {
-    if #[cfg(target_feature = "atomics")] {
-        compile_error!("The wasm32-wasi-preview2 target does not support atomics");
-    } else {
-        #[path = "../unsupported/locks/mod.rs"]
-        pub mod locks;
-        #[path = "../unsupported/once.rs"]
-        pub mod once;
-        #[path = "../unsupported/thread_parking.rs"]
-        pub mod thread_parking;
-    }
-}
-
-#[path = "../unsupported/common.rs"]
-#[deny(unsafe_op_in_unsafe_fn)]
-#[allow(unused)]
-mod common;
-pub use common::*;
-
-#[path = "../wasi/helpers.rs"]
-mod helpers;
-// These exports are listed individually to work around Rust's glob import
-// conflict rules. If we glob export `helpers` and `common` together, then
-// the compiler complains about conflicts.
-pub use helpers::abort_internal;
-pub use helpers::decode_error_kind;
-use helpers::err2io;
-pub use helpers::hashmap_random_keys;
-pub use helpers::is_interrupted;
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index d55d9bace81..1a59ac9a9ca 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -7,17 +7,17 @@
 
 use crate::ffi::CStr;
 use crate::mem;
+use crate::num::NonZero;
 pub use crate::os::raw::c_int;
 use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_void};
 use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
 use crate::ptr;
-use core::ffi::NonZero_c_ulong;
 
 mod windows_sys;
 pub use windows_sys::*;
 
 pub type DWORD = c_ulong;
-pub type NonZeroDWORD = NonZero_c_ulong;
+pub type NonZeroDWORD = NonZero<c_ulong>;
 pub type LARGE_INTEGER = c_longlong;
 #[cfg_attr(target_vendor = "uwp", allow(unused))]
 pub type LONG = c_long;