about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDan Gohman <dev@sunfishcode.online>2022-03-08 15:38:08 -0800
committerDan Gohman <dev@sunfishcode.online>2022-06-14 14:46:22 -0700
commit67ed99e6d2f377fffabedc2cd15fab484095fbea (patch)
tree6962a249b5d99d681948464a1d02ac1a6a008dbe
parent1f34da9ec8a85b6f86c5fa1c121ab6f88f2f4966 (diff)
downloadrust-67ed99e6d2f377fffabedc2cd15fab484095fbea.tar.gz
rust-67ed99e6d2f377fffabedc2cd15fab484095fbea.zip
Implement stabilization of `#[feature(io_safety)]`.
Implement stabilization of [I/O safety], aka `#[feature(io_safety)]`.

Fixes #87074.

[I/O safety]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md
-rw-r--r--library/std/src/os/fd/mod.rs2
-rw-r--r--library/std/src/os/fd/owned.rs61
-rw-r--r--library/std/src/os/unix/io/fd.rs3
-rw-r--r--library/std/src/os/unix/io/mod.rs2
-rw-r--r--library/std/src/os/unix/net/datagram.rs6
-rw-r--r--library/std/src/os/unix/net/listener.rs6
-rw-r--r--library/std/src/os/unix/net/stream.rs6
-rw-r--r--library/std/src/os/unix/process.rs14
-rw-r--r--library/std/src/os/windows/io/handle.rs72
-rw-r--r--library/std/src/os/windows/io/mod.rs4
-rw-r--r--library/std/src/os/windows/io/socket.rs35
-rw-r--r--library/std/src/os/windows/process.rs6
-rw-r--r--library/std/src/sys/unix/stdio.rs12
13 files changed, 145 insertions, 84 deletions
diff --git a/library/std/src/os/fd/mod.rs b/library/std/src/os/fd/mod.rs
index 13bb079194f..a456947534a 100644
--- a/library/std/src/os/fd/mod.rs
+++ b/library/std/src/os/fd/mod.rs
@@ -1,6 +1,6 @@
 //! Owned and borrowed Unix-like file descriptors.
 
-#![unstable(feature = "io_safety", issue = "87074")]
+#![stable(feature = "io_safety", since = "1.63.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
 
 // `RawFd`, `AsRawFd`, etc.
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 53433823fbd..1d947cc853e 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -1,6 +1,6 @@
 //! Owned and borrowed Unix-like file descriptors.
 
-#![unstable(feature = "io_safety", issue = "87074")]
+#![stable(feature = "io_safety", since = "1.63.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
 
 use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
@@ -33,7 +33,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
 // because c_int is 32 bits.
 #[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
 #[rustc_nonnull_optimization_guaranteed]
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub struct BorrowedFd<'fd> {
     fd: RawFd,
     _phantom: PhantomData<&'fd OwnedFd>,
@@ -54,7 +54,7 @@ pub struct BorrowedFd<'fd> {
 // because c_int is 32 bits.
 #[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
 #[rustc_nonnull_optimization_guaranteed]
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub struct OwnedFd {
     fd: RawFd,
 }
@@ -67,7 +67,8 @@ impl BorrowedFd<'_> {
     /// The resource pointed to by `fd` must remain open for the duration of
     /// the returned `BorrowedFd`, and it must not have the value `-1`.
     #[inline]
-    #[unstable(feature = "io_safety", issue = "87074")]
+    #[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
+    #[stable(feature = "io_safety", since = "1.63.0")]
     pub const unsafe fn borrow_raw(fd: RawFd) -> Self {
         assert!(fd != u32::MAX as RawFd);
         // SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned)
@@ -79,6 +80,7 @@ impl OwnedFd {
     /// Creates a new `OwnedFd` instance that shares the same underlying file handle
     /// as the existing `OwnedFd` instance.
     #[cfg(not(target_arch = "wasm32"))]
+    #[stable(feature = "io_safety", since = "1.63.0")]
     pub fn try_clone(&self) -> crate::io::Result<Self> {
         // We want to atomically duplicate this file descriptor and set the
         // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
@@ -106,7 +108,7 @@ impl OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsRawFd for BorrowedFd<'_> {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
@@ -114,7 +116,7 @@ impl AsRawFd for BorrowedFd<'_> {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsRawFd for OwnedFd {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
@@ -122,7 +124,7 @@ impl AsRawFd for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl IntoRawFd for OwnedFd {
     #[inline]
     fn into_raw_fd(self) -> RawFd {
@@ -132,7 +134,7 @@ impl IntoRawFd for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl FromRawFd for OwnedFd {
     /// Constructs a new instance of `Self` from the given raw file descriptor.
     ///
@@ -148,7 +150,7 @@ impl FromRawFd for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl Drop for OwnedFd {
     #[inline]
     fn drop(&mut self) {
@@ -163,14 +165,14 @@ impl Drop for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl fmt::Debug for BorrowedFd<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("BorrowedFd").field("fd", &self.fd).finish()
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl fmt::Debug for OwnedFd {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("OwnedFd").field("fd", &self.fd).finish()
@@ -182,14 +184,13 @@ impl fmt::Debug for OwnedFd {
 /// This is only available on unix platforms and must be imported in order to
 /// call the method. Windows platforms have a corresponding `AsHandle` and
 /// `AsSocket` set of traits.
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub trait AsFd {
     /// Borrows the file descriptor.
     ///
     /// # Example
     ///
     /// ```rust,no_run
-    /// # #![feature(io_safety)]
     /// use std::fs::File;
     /// # use std::io;
     /// # #[cfg(target_os = "wasi")]
@@ -202,11 +203,11 @@ pub trait AsFd {
     /// let borrowed_fd: BorrowedFd<'_> = f.as_fd();
     /// # Ok::<(), io::Error>(())
     /// ```
-    #[unstable(feature = "io_safety", issue = "87074")]
+    #[stable(feature = "io_safety", since = "1.63.0")]
     fn as_fd(&self) -> BorrowedFd<'_>;
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<T: AsFd> AsFd for &T {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -214,7 +215,7 @@ impl<T: AsFd> AsFd for &T {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<T: AsFd> AsFd for &mut T {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -222,7 +223,7 @@ impl<T: AsFd> AsFd for &mut T {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for BorrowedFd<'_> {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -230,7 +231,7 @@ impl AsFd for BorrowedFd<'_> {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for OwnedFd {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -241,7 +242,7 @@ impl AsFd for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for fs::File {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -249,7 +250,7 @@ impl AsFd for fs::File {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<fs::File> for OwnedFd {
     #[inline]
     fn from(file: fs::File) -> OwnedFd {
@@ -257,7 +258,7 @@ impl From<fs::File> for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedFd> for fs::File {
     #[inline]
     fn from(owned_fd: OwnedFd) -> Self {
@@ -265,7 +266,7 @@ impl From<OwnedFd> for fs::File {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for crate::net::TcpStream {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -273,7 +274,7 @@ impl AsFd for crate::net::TcpStream {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::net::TcpStream> for OwnedFd {
     #[inline]
     fn from(tcp_stream: crate::net::TcpStream) -> OwnedFd {
@@ -281,7 +282,7 @@ impl From<crate::net::TcpStream> for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedFd> for crate::net::TcpStream {
     #[inline]
     fn from(owned_fd: OwnedFd) -> Self {
@@ -291,7 +292,7 @@ impl From<OwnedFd> for crate::net::TcpStream {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for crate::net::TcpListener {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -299,7 +300,7 @@ impl AsFd for crate::net::TcpListener {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::net::TcpListener> for OwnedFd {
     #[inline]
     fn from(tcp_listener: crate::net::TcpListener) -> OwnedFd {
@@ -307,7 +308,7 @@ impl From<crate::net::TcpListener> for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedFd> for crate::net::TcpListener {
     #[inline]
     fn from(owned_fd: OwnedFd) -> Self {
@@ -317,7 +318,7 @@ impl From<OwnedFd> for crate::net::TcpListener {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for crate::net::UdpSocket {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -325,7 +326,7 @@ impl AsFd for crate::net::UdpSocket {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::net::UdpSocket> for OwnedFd {
     #[inline]
     fn from(udp_socket: crate::net::UdpSocket) -> OwnedFd {
@@ -333,7 +334,7 @@ impl From<crate::net::UdpSocket> for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedFd> for crate::net::UdpSocket {
     #[inline]
     fn from(owned_fd: OwnedFd) -> Self {
diff --git a/library/std/src/os/unix/io/fd.rs b/library/std/src/os/unix/io/fd.rs
index 7795db7abc0..d4cb696459b 100644
--- a/library/std/src/os/unix/io/fd.rs
+++ b/library/std/src/os/unix/io/fd.rs
@@ -1,9 +1,8 @@
 //! Owned and borrowed file descriptors.
 
-#![unstable(feature = "io_safety", issue = "87074")]
-
 // Tests for this module
 #[cfg(test)]
 mod tests;
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub use crate::os::fd::owned::*;
diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs
index 0fd9591b016..e3a7cfc8d2a 100644
--- a/library/std/src/os/unix/io/mod.rs
+++ b/library/std/src/os/unix/io/mod.rs
@@ -51,7 +51,7 @@
 mod fd;
 mod raw;
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub use fd::*;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use raw::*;
diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs
index 0b1d9b07132..8008acfd1c9 100644
--- a/library/std/src/os/unix/net/datagram.rs
+++ b/library/std/src/os/unix/net/datagram.rs
@@ -962,7 +962,7 @@ impl IntoRawFd for UnixDatagram {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for UnixDatagram {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -970,7 +970,7 @@ impl AsFd for UnixDatagram {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<UnixDatagram> for OwnedFd {
     #[inline]
     fn from(unix_datagram: UnixDatagram) -> OwnedFd {
@@ -978,7 +978,7 @@ impl From<UnixDatagram> for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedFd> for UnixDatagram {
     #[inline]
     fn from(owned: OwnedFd) -> Self {
diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs
index 8e11d32f130..7c0d539504d 100644
--- a/library/std/src/os/unix/net/listener.rs
+++ b/library/std/src/os/unix/net/listener.rs
@@ -300,7 +300,7 @@ impl IntoRawFd for UnixListener {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for UnixListener {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -308,7 +308,7 @@ impl AsFd for UnixListener {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedFd> for UnixListener {
     #[inline]
     fn from(fd: OwnedFd) -> UnixListener {
@@ -316,7 +316,7 @@ impl From<OwnedFd> for UnixListener {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<UnixListener> for OwnedFd {
     #[inline]
     fn from(listener: UnixListener) -> OwnedFd {
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index 2a5790e9d5c..1d6083e66e1 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -683,7 +683,7 @@ impl IntoRawFd for UnixStream {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for UnixStream {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -691,7 +691,7 @@ impl AsFd for UnixStream {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<UnixStream> for OwnedFd {
     #[inline]
     fn from(unix_stream: UnixStream) -> OwnedFd {
@@ -699,7 +699,7 @@ impl From<UnixStream> for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedFd> for UnixStream {
     #[inline]
     fn from(owned: OwnedFd) -> Self {
diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs
index 9dca9b4a4a3..3e989c85db9 100644
--- a/library/std/src/os/unix/process.rs
+++ b/library/std/src/os/unix/process.rs
@@ -339,7 +339,7 @@ impl FromRawFd for process::Stdio {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedFd> for process::Stdio {
     #[inline]
     fn from(fd: OwnedFd) -> process::Stdio {
@@ -397,7 +397,7 @@ impl IntoRawFd for process::ChildStderr {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for crate::process::ChildStdin {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -405,7 +405,7 @@ impl AsFd for crate::process::ChildStdin {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::process::ChildStdin> for OwnedFd {
     #[inline]
     fn from(child_stdin: crate::process::ChildStdin) -> OwnedFd {
@@ -413,7 +413,7 @@ impl From<crate::process::ChildStdin> for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for crate::process::ChildStdout {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -421,7 +421,7 @@ impl AsFd for crate::process::ChildStdout {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::process::ChildStdout> for OwnedFd {
     #[inline]
     fn from(child_stdout: crate::process::ChildStdout) -> OwnedFd {
@@ -429,7 +429,7 @@ impl From<crate::process::ChildStdout> for OwnedFd {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for crate::process::ChildStderr {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -437,7 +437,7 @@ impl AsFd for crate::process::ChildStderr {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::process::ChildStderr> for OwnedFd {
     #[inline]
     fn from(child_stderr: crate::process::ChildStderr) -> OwnedFd {
diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index 90a5b7466fe..2f7c07c7910 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -1,6 +1,6 @@
 //! Owned and borrowed OS handles.
 
-#![unstable(feature = "io_safety", issue = "87074")]
+#![stable(feature = "io_safety", since = "1.63.0")]
 
 use super::raw::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
 use crate::fmt;
@@ -38,7 +38,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
 /// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
 #[derive(Copy, Clone)]
 #[repr(transparent)]
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub struct BorrowedHandle<'handle> {
     handle: RawHandle,
     _phantom: PhantomData<&'handle OwnedHandle>,
@@ -66,7 +66,7 @@ pub struct BorrowedHandle<'handle> {
 /// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
 /// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
 #[repr(transparent)]
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub struct OwnedHandle {
     handle: RawHandle,
 }
@@ -89,7 +89,7 @@ pub struct OwnedHandle {
 ///
 /// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
 #[repr(transparent)]
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 #[derive(Debug)]
 pub struct HandleOrNull(OwnedHandle);
 
@@ -108,7 +108,7 @@ pub struct HandleOrNull(OwnedHandle);
 ///
 /// If holds a handle other than `INVALID_HANDLE_VALUE`, it will close the handle on drop.
 #[repr(transparent)]
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 #[derive(Debug)]
 pub struct HandleOrInvalid(OwnedHandle);
 
@@ -117,13 +117,21 @@ pub struct HandleOrInvalid(OwnedHandle);
 // `Send` or `Sync`).
 //
 // [`HANDLE`]: std::os::windows::raw::HANDLE
+#[stable(feature = "io_safety", since = "1.63.0")]
 unsafe impl Send for OwnedHandle {}
+#[stable(feature = "io_safety", since = "1.63.0")]
 unsafe impl Send for HandleOrNull {}
+#[stable(feature = "io_safety", since = "1.63.0")]
 unsafe impl Send for HandleOrInvalid {}
+#[stable(feature = "io_safety", since = "1.63.0")]
 unsafe impl Send for BorrowedHandle<'_> {}
+#[stable(feature = "io_safety", since = "1.63.0")]
 unsafe impl Sync for OwnedHandle {}
+#[stable(feature = "io_safety", since = "1.63.0")]
 unsafe impl Sync for HandleOrNull {}
+#[stable(feature = "io_safety", since = "1.63.0")]
 unsafe impl Sync for HandleOrInvalid {}
+#[stable(feature = "io_safety", since = "1.63.0")]
 unsafe impl Sync for BorrowedHandle<'_> {}
 
 impl BorrowedHandle<'_> {
@@ -142,12 +150,14 @@ impl BorrowedHandle<'_> {
     ///
     /// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
     #[inline]
-    #[unstable(feature = "io_safety", issue = "87074")]
+    #[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
+    #[stable(feature = "io_safety", since = "1.63.0")]
     pub const unsafe fn borrow_raw(handle: RawHandle) -> Self {
         Self { handle, _phantom: PhantomData }
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl TryFrom<HandleOrNull> for OwnedHandle {
     type Error = NullHandleError;
 
@@ -169,6 +179,7 @@ impl TryFrom<HandleOrNull> for OwnedHandle {
 impl OwnedHandle {
     /// Creates a new `OwnedHandle` instance that shares the same underlying file handle
     /// as the existing `OwnedHandle` instance.
+    #[stable(feature = "io_safety", since = "1.63.0")]
     pub fn try_clone(&self) -> crate::io::Result<Self> {
         self.duplicate(0, false, c::DUPLICATE_SAME_ACCESS)
     }
@@ -206,6 +217,7 @@ impl OwnedHandle {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl TryFrom<HandleOrInvalid> for OwnedHandle {
     type Error = InvalidHandleError;
 
@@ -227,29 +239,29 @@ impl TryFrom<HandleOrInvalid> for OwnedHandle {
 /// This is the error type used by [`HandleOrNull`] when attempting to convert
 /// into a handle, to indicate that the value is null.
 // The empty field prevents constructing this, and allows extending it in the future.
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct NullHandleError(());
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl fmt::Display for NullHandleError {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         "A HandleOrNull could not be converted to a handle because it was null".fmt(fmt)
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl crate::error::Error for NullHandleError {}
 
 /// This is the error type used by [`HandleOrInvalid`] when attempting to
 /// convert into a handle, to indicate that the value is
 /// `INVALID_HANDLE_VALUE`.
 // The empty field prevents constructing this, and allows extending it in the future.
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct InvalidHandleError(());
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl fmt::Display for InvalidHandleError {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         "A HandleOrInvalid could not be converted to a handle because it was INVALID_HANDLE_VALUE"
@@ -257,9 +269,10 @@ impl fmt::Display for InvalidHandleError {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl crate::error::Error for InvalidHandleError {}
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsRawHandle for BorrowedHandle<'_> {
     #[inline]
     fn as_raw_handle(&self) -> RawHandle {
@@ -267,6 +280,7 @@ impl AsRawHandle for BorrowedHandle<'_> {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsRawHandle for OwnedHandle {
     #[inline]
     fn as_raw_handle(&self) -> RawHandle {
@@ -274,6 +288,7 @@ impl AsRawHandle for OwnedHandle {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl IntoRawHandle for OwnedHandle {
     #[inline]
     fn into_raw_handle(self) -> RawHandle {
@@ -283,6 +298,7 @@ impl IntoRawHandle for OwnedHandle {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl FromRawHandle for OwnedHandle {
     #[inline]
     unsafe fn from_raw_handle(handle: RawHandle) -> Self {
@@ -305,6 +321,7 @@ impl HandleOrNull {
     /// Windows APIs use null for errors; see [here] for the full story.
     ///
     /// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
+    #[stable(feature = "io_safety", since = "1.63.0")]
     #[inline]
     pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
         Self(OwnedHandle::from_raw_handle(handle))
@@ -327,12 +344,14 @@ impl HandleOrInvalid {
     /// `INVALID_HANDLE_VALUE` for errors; see [here] for the full story.
     ///
     /// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
+    #[stable(feature = "io_safety", since = "1.63.0")]
     #[inline]
     pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
         Self(OwnedHandle::from_raw_handle(handle))
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl Drop for OwnedHandle {
     #[inline]
     fn drop(&mut self) {
@@ -342,12 +361,14 @@ impl Drop for OwnedHandle {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl fmt::Debug for BorrowedHandle<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("BorrowedHandle").field("handle", &self.handle).finish()
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl fmt::Debug for OwnedHandle {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("OwnedHandle").field("handle", &self.handle).finish()
@@ -355,14 +376,13 @@ impl fmt::Debug for OwnedHandle {
 }
 
 /// A trait to borrow the handle from an underlying object.
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub trait AsHandle {
     /// Borrows the handle.
     ///
     /// # Example
     ///
     /// ```rust,no_run
-    /// # #![feature(io_safety)]
     /// use std::fs::File;
     /// # use std::io;
     /// use std::os::windows::io::{AsHandle, BorrowedHandle};
@@ -371,10 +391,11 @@ pub trait AsHandle {
     /// let borrowed_handle: BorrowedHandle<'_> = f.as_handle();
     /// # Ok::<(), io::Error>(())
     /// ```
+    #[stable(feature = "io_safety", since = "1.63.0")]
     fn as_handle(&self) -> BorrowedHandle<'_>;
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<T: AsHandle> AsHandle for &T {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -382,7 +403,7 @@ impl<T: AsHandle> AsHandle for &T {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<T: AsHandle> AsHandle for &mut T {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -390,6 +411,7 @@ impl<T: AsHandle> AsHandle for &mut T {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsHandle for BorrowedHandle<'_> {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -397,6 +419,7 @@ impl AsHandle for BorrowedHandle<'_> {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsHandle for OwnedHandle {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -407,6 +430,7 @@ impl AsHandle for OwnedHandle {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsHandle for fs::File {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -414,6 +438,7 @@ impl AsHandle for fs::File {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<fs::File> for OwnedHandle {
     #[inline]
     fn from(file: fs::File) -> OwnedHandle {
@@ -421,6 +446,7 @@ impl From<fs::File> for OwnedHandle {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedHandle> for fs::File {
     #[inline]
     fn from(owned: OwnedHandle) -> Self {
@@ -428,6 +454,7 @@ impl From<OwnedHandle> for fs::File {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsHandle for crate::io::Stdin {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -435,6 +462,7 @@ impl AsHandle for crate::io::Stdin {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<'a> AsHandle for crate::io::StdinLock<'a> {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -442,6 +470,7 @@ impl<'a> AsHandle for crate::io::StdinLock<'a> {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsHandle for crate::io::Stdout {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -449,6 +478,7 @@ impl AsHandle for crate::io::Stdout {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<'a> AsHandle for crate::io::StdoutLock<'a> {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -456,6 +486,7 @@ impl<'a> AsHandle for crate::io::StdoutLock<'a> {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsHandle for crate::io::Stderr {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -463,6 +494,7 @@ impl AsHandle for crate::io::Stderr {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<'a> AsHandle for crate::io::StderrLock<'a> {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -470,6 +502,7 @@ impl<'a> AsHandle for crate::io::StderrLock<'a> {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsHandle for crate::process::ChildStdin {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -477,6 +510,7 @@ impl AsHandle for crate::process::ChildStdin {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::process::ChildStdin> for OwnedHandle {
     #[inline]
     fn from(child_stdin: crate::process::ChildStdin) -> OwnedHandle {
@@ -484,6 +518,7 @@ impl From<crate::process::ChildStdin> for OwnedHandle {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsHandle for crate::process::ChildStdout {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -491,6 +526,7 @@ impl AsHandle for crate::process::ChildStdout {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::process::ChildStdout> for OwnedHandle {
     #[inline]
     fn from(child_stdout: crate::process::ChildStdout) -> OwnedHandle {
@@ -498,6 +534,7 @@ impl From<crate::process::ChildStdout> for OwnedHandle {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsHandle for crate::process::ChildStderr {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -505,6 +542,7 @@ impl AsHandle for crate::process::ChildStderr {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::process::ChildStderr> for OwnedHandle {
     #[inline]
     fn from(child_stderr: crate::process::ChildStderr) -> OwnedHandle {
@@ -512,6 +550,7 @@ impl From<crate::process::ChildStderr> for OwnedHandle {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<T> AsHandle for crate::thread::JoinHandle<T> {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -519,6 +558,7 @@ impl<T> AsHandle for crate::thread::JoinHandle<T> {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<T> From<crate::thread::JoinHandle<T>> for OwnedHandle {
     #[inline]
     fn from(join_handle: crate::thread::JoinHandle<T>) -> OwnedHandle {
diff --git a/library/std/src/os/windows/io/mod.rs b/library/std/src/os/windows/io/mod.rs
index 3325688e661..31545059707 100644
--- a/library/std/src/os/windows/io/mod.rs
+++ b/library/std/src/os/windows/io/mod.rs
@@ -48,11 +48,11 @@ mod handle;
 mod raw;
 mod socket;
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub use handle::*;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use raw::*;
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub use socket::*;
 
 #[cfg(test)]
diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs
index e23e1cf8cee..c5a381c40d2 100644
--- a/library/std/src/os/windows/io/socket.rs
+++ b/library/std/src/os/windows/io/socket.rs
@@ -1,6 +1,6 @@
 //! Owned and borrowed OS sockets.
 
-#![unstable(feature = "io_safety", issue = "87074")]
+#![stable(feature = "io_safety", since = "1.63.0")]
 
 use super::raw::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
 use crate::fmt;
@@ -36,7 +36,7 @@ use crate::sys::cvt;
     rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
 )]
 #[rustc_nonnull_optimization_guaranteed]
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub struct BorrowedSocket<'socket> {
     socket: RawSocket,
     _phantom: PhantomData<&'socket OwnedSocket>,
@@ -59,7 +59,7 @@ pub struct BorrowedSocket<'socket> {
     rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
 )]
 #[rustc_nonnull_optimization_guaranteed]
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub struct OwnedSocket {
     socket: RawSocket,
 }
@@ -73,7 +73,8 @@ impl BorrowedSocket<'_> {
     /// the returned `BorrowedSocket`, and it must not have the value
     /// `INVALID_SOCKET`.
     #[inline]
-    #[unstable(feature = "io_safety", issue = "87074")]
+    #[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
+    #[stable(feature = "io_safety", since = "1.63.0")]
     pub const unsafe fn borrow_raw(socket: RawSocket) -> Self {
         assert!(socket != c::INVALID_SOCKET as RawSocket);
         Self { socket, _phantom: PhantomData }
@@ -83,6 +84,7 @@ impl BorrowedSocket<'_> {
 impl OwnedSocket {
     /// Creates a new `OwnedSocket` instance that shares the same underlying socket
     /// as the existing `OwnedSocket` instance.
+    #[stable(feature = "io_safety", since = "1.63.0")]
     pub fn try_clone(&self) -> io::Result<Self> {
         let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFO>() };
         let result = unsafe {
@@ -152,6 +154,7 @@ fn last_error() -> io::Error {
     io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsRawSocket for BorrowedSocket<'_> {
     #[inline]
     fn as_raw_socket(&self) -> RawSocket {
@@ -159,6 +162,7 @@ impl AsRawSocket for BorrowedSocket<'_> {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsRawSocket for OwnedSocket {
     #[inline]
     fn as_raw_socket(&self) -> RawSocket {
@@ -166,6 +170,7 @@ impl AsRawSocket for OwnedSocket {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl IntoRawSocket for OwnedSocket {
     #[inline]
     fn into_raw_socket(self) -> RawSocket {
@@ -175,6 +180,7 @@ impl IntoRawSocket for OwnedSocket {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl FromRawSocket for OwnedSocket {
     #[inline]
     unsafe fn from_raw_socket(socket: RawSocket) -> Self {
@@ -183,6 +189,7 @@ impl FromRawSocket for OwnedSocket {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl Drop for OwnedSocket {
     #[inline]
     fn drop(&mut self) {
@@ -192,12 +199,14 @@ impl Drop for OwnedSocket {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl fmt::Debug for BorrowedSocket<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("BorrowedSocket").field("socket", &self.socket).finish()
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl fmt::Debug for OwnedSocket {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("OwnedSocket").field("socket", &self.socket).finish()
@@ -205,13 +214,14 @@ impl fmt::Debug for OwnedSocket {
 }
 
 /// A trait to borrow the socket from an underlying object.
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 pub trait AsSocket {
     /// Borrows the socket.
+    #[stable(feature = "io_safety", since = "1.63.0")]
     fn as_socket(&self) -> BorrowedSocket<'_>;
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<T: AsSocket> AsSocket for &T {
     #[inline]
     fn as_socket(&self) -> BorrowedSocket<'_> {
@@ -219,7 +229,7 @@ impl<T: AsSocket> AsSocket for &T {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<T: AsSocket> AsSocket for &mut T {
     #[inline]
     fn as_socket(&self) -> BorrowedSocket<'_> {
@@ -227,6 +237,7 @@ impl<T: AsSocket> AsSocket for &mut T {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsSocket for BorrowedSocket<'_> {
     #[inline]
     fn as_socket(&self) -> BorrowedSocket<'_> {
@@ -234,6 +245,7 @@ impl AsSocket for BorrowedSocket<'_> {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsSocket for OwnedSocket {
     #[inline]
     fn as_socket(&self) -> BorrowedSocket<'_> {
@@ -244,6 +256,7 @@ impl AsSocket for OwnedSocket {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsSocket for crate::net::TcpStream {
     #[inline]
     fn as_socket(&self) -> BorrowedSocket<'_> {
@@ -251,6 +264,7 @@ impl AsSocket for crate::net::TcpStream {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::net::TcpStream> for OwnedSocket {
     #[inline]
     fn from(tcp_stream: crate::net::TcpStream) -> OwnedSocket {
@@ -258,6 +272,7 @@ impl From<crate::net::TcpStream> for OwnedSocket {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedSocket> for crate::net::TcpStream {
     #[inline]
     fn from(owned: OwnedSocket) -> Self {
@@ -265,6 +280,7 @@ impl From<OwnedSocket> for crate::net::TcpStream {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsSocket for crate::net::TcpListener {
     #[inline]
     fn as_socket(&self) -> BorrowedSocket<'_> {
@@ -272,6 +288,7 @@ impl AsSocket for crate::net::TcpListener {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::net::TcpListener> for OwnedSocket {
     #[inline]
     fn from(tcp_listener: crate::net::TcpListener) -> OwnedSocket {
@@ -279,6 +296,7 @@ impl From<crate::net::TcpListener> for OwnedSocket {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedSocket> for crate::net::TcpListener {
     #[inline]
     fn from(owned: OwnedSocket) -> Self {
@@ -286,6 +304,7 @@ impl From<OwnedSocket> for crate::net::TcpListener {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsSocket for crate::net::UdpSocket {
     #[inline]
     fn as_socket(&self) -> BorrowedSocket<'_> {
@@ -293,6 +312,7 @@ impl AsSocket for crate::net::UdpSocket {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<crate::net::UdpSocket> for OwnedSocket {
     #[inline]
     fn from(udp_socket: crate::net::UdpSocket) -> OwnedSocket {
@@ -300,6 +320,7 @@ impl From<crate::net::UdpSocket> for OwnedSocket {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedSocket> for crate::net::UdpSocket {
     #[inline]
     fn from(owned: OwnedSocket) -> Self {
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs
index 1c7e361c2a4..24b0888b112 100644
--- a/library/std/src/os/windows/process.rs
+++ b/library/std/src/os/windows/process.rs
@@ -22,7 +22,7 @@ impl FromRawHandle for process::Stdio {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<OwnedHandle> for process::Stdio {
     fn from(handle: OwnedHandle) -> process::Stdio {
         let handle = sys::handle::Handle::from_inner(handle);
@@ -39,7 +39,7 @@ impl AsRawHandle for process::Child {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsHandle for process::Child {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -54,7 +54,7 @@ impl IntoRawHandle for process::Child {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl From<process::Child> for OwnedHandle {
     fn from(child: process::Child) -> OwnedHandle {
         child.into_inner().into_handle().into_inner()
diff --git a/library/std/src/sys/unix/stdio.rs b/library/std/src/sys/unix/stdio.rs
index e4d83ba0ffd..329f9433dba 100644
--- a/library/std/src/sys/unix/stdio.rs
+++ b/library/std/src/sys/unix/stdio.rs
@@ -92,7 +92,7 @@ pub fn panic_output() -> Option<impl io::Write> {
     Some(Stderr::new())
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for io::Stdin {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -100,7 +100,7 @@ impl AsFd for io::Stdin {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<'a> AsFd for io::StdinLock<'a> {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -108,7 +108,7 @@ impl<'a> AsFd for io::StdinLock<'a> {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for io::Stdout {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -116,7 +116,7 @@ impl AsFd for io::Stdout {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<'a> AsFd for io::StdoutLock<'a> {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -124,7 +124,7 @@ impl<'a> AsFd for io::StdoutLock<'a> {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for io::Stderr {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -132,7 +132,7 @@ impl AsFd for io::Stderr {
     }
 }
 
-#[unstable(feature = "io_safety", issue = "87074")]
+#[stable(feature = "io_safety", since = "1.63.0")]
 impl<'a> AsFd for io::StderrLock<'a> {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {