From 90ff6fcd4ec4a91b9d0a4956d3fd8459931f2de4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 11 May 2022 07:17:52 -0700 Subject: [PATCH] Add rustc_nonnull_optimization_guaranteed to Owned/Borrowed Fd/Socket PR #94586 added support for using `rustc_nonnull_optimization_guaranteed` on values where the "null" value is the all-ones bitpattern. Now that #94586 has made it to the stage0 compiler, add `rustc_nonnull_optimization_guaranteed` to `OwnedFd`, `BorrowedFd`, `OwnedSocket`, and `BorrowedSocket`, since these types all exclude all-ones bitpatterns. This allows `Option`, `Option`, `Option`, and `Option` to be used in FFI declarations, as described in the [I/O safety RFC]. [I/O safety RFC]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md#ownedfd-and-borrowedfdfd-1 --- library/std/src/os/fd/owned.rs | 2 ++ library/std/src/os/fd/tests.rs | 19 +++++++++++++++++++ library/std/src/os/windows/io/mod.rs | 3 +++ library/std/src/os/windows/io/socket.rs | 2 ++ library/std/src/os/windows/io/tests.rs | 22 ++++++++++++++++++++++ 5 files changed, 48 insertions(+) create mode 100644 library/std/src/os/windows/io/tests.rs diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index bfc5ce015641..53433823fbd3 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -32,6 +32,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; // 32-bit c_int. Below is -2, in two's complement, but that only works out // 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")] pub struct BorrowedFd<'fd> { fd: RawFd, @@ -52,6 +53,7 @@ pub struct BorrowedFd<'fd> { // 32-bit c_int. Below is -2, in two's complement, but that only works out // 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")] pub struct OwnedFd { fd: RawFd, diff --git a/library/std/src/os/fd/tests.rs b/library/std/src/os/fd/tests.rs index 26ef93e3d711..b39863644f11 100644 --- a/library/std/src/os/fd/tests.rs +++ b/library/std/src/os/fd/tests.rs @@ -32,3 +32,22 @@ fn test_fd() { assert_eq!(stdin_as_file.as_fd().as_raw_fd(), raw_fd); assert_eq!(Into::::into(stdin_as_file).into_raw_fd(), raw_fd); } + +#[cfg(any(unix, target_os = "wasi"))] +#[test] +fn test_niche_optimizations() { + use crate::mem::size_of; + #[cfg(unix)] + use crate::os::unix::io::{BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; + #[cfg(target_os = "wasi")] + use crate::os::wasi::io::{BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; + + assert_eq!(size_of::>(), size_of::()); + assert_eq!(size_of::>>(), size_of::()); + unsafe { + assert_eq!(OwnedFd::from_raw_fd(RawFd::MIN).into_raw_fd(), RawFd::MIN); + assert_eq!(OwnedFd::from_raw_fd(RawFd::MAX).into_raw_fd(), RawFd::MAX); + assert_eq!(Some(OwnedFd::from_raw_fd(RawFd::MIN)).unwrap().into_raw_fd(), RawFd::MIN); + assert_eq!(Some(OwnedFd::from_raw_fd(RawFd::MAX)).unwrap().into_raw_fd(), RawFd::MAX); + } +} diff --git a/library/std/src/os/windows/io/mod.rs b/library/std/src/os/windows/io/mod.rs index 2f6f07695480..3325688e661e 100644 --- a/library/std/src/os/windows/io/mod.rs +++ b/library/std/src/os/windows/io/mod.rs @@ -54,3 +54,6 @@ pub use handle::*; pub use raw::*; #[unstable(feature = "io_safety", issue = "87074")] pub use socket::*; + +#[cfg(test)] +mod tests; diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs index c14a1d6192fa..baae92c19f20 100644 --- a/library/std/src/os/windows/io/socket.rs +++ b/library/std/src/os/windows/io/socket.rs @@ -34,6 +34,7 @@ use crate::sys::cvt; target_pointer_width = "64", rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) )] +#[rustc_nonnull_optimization_guaranteed] #[unstable(feature = "io_safety", issue = "87074")] pub struct BorrowedSocket<'socket> { socket: RawSocket, @@ -56,6 +57,7 @@ pub struct BorrowedSocket<'socket> { target_pointer_width = "64", rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) )] +#[rustc_nonnull_optimization_guaranteed] #[unstable(feature = "io_safety", issue = "87074")] pub struct OwnedSocket { socket: RawSocket, diff --git a/library/std/src/os/windows/io/tests.rs b/library/std/src/os/windows/io/tests.rs new file mode 100644 index 000000000000..541754737070 --- /dev/null +++ b/library/std/src/os/windows/io/tests.rs @@ -0,0 +1,22 @@ +#[test] +fn test_niche_optimizations_socket() { + use crate::mem::size_of; + use crate::os::windows::io::{ + BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, OwnedSocket, RawSocket, + }; + + assert_eq!(size_of::>(), size_of::()); + assert_eq!(size_of::>>(), size_of::(),); + unsafe { + assert_eq!(OwnedSocket::from_raw_socket(RawSocket::MIN).into_raw_socket(), RawSocket::MIN); + assert_eq!(OwnedSocket::from_raw_socket(RawSocket::MAX).into_raw_socket(), RawSocket::MAX); + assert_eq!( + Some(OwnedSocket::from_raw_socket(RawSocket::MIN)).unwrap().into_raw_socket(), + RawSocket::MIN + ); + assert_eq!( + Some(OwnedSocket::from_raw_socket(RawSocket::MAX)).unwrap().into_raw_socket(), + RawSocket::MAX + ); + } +}