about summary refs log tree commit diff
path: root/library/std/src/os/windows
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 /library/std/src/os/windows
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
Diffstat (limited to 'library/std/src/os/windows')
-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
4 files changed, 89 insertions, 28 deletions
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()