diff options
| author | Dan Gohman <dev@sunfishcode.online> | 2022-05-11 07:17:52 -0700 |
|---|---|---|
| committer | Dan Gohman <dev@sunfishcode.online> | 2022-05-11 07:26:49 -0700 |
| commit | 90ff6fcd4ec4a91b9d0a4956d3fd8459931f2de4 (patch) | |
| tree | 1658c667bcc8a8245c9d24d591cbc4c74e35fb11 | |
| parent | ecd44958e0a21110d09862ee080d95a4ca6c52f8 (diff) | |
| download | rust-90ff6fcd4ec4a91b9d0a4956d3fd8459931f2de4.tar.gz rust-90ff6fcd4ec4a91b9d0a4956d3fd8459931f2de4.zip | |
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<OwnedFd>`, `Option<BorrowedFd>`, `Option<OwnedSocket>`, and `Option<BorrowedSocket>` 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
| -rw-r--r-- | library/std/src/os/fd/owned.rs | 2 | ||||
| -rw-r--r-- | library/std/src/os/fd/tests.rs | 19 | ||||
| -rw-r--r-- | library/std/src/os/windows/io/mod.rs | 3 | ||||
| -rw-r--r-- | library/std/src/os/windows/io/socket.rs | 2 | ||||
| -rw-r--r-- | library/std/src/os/windows/io/tests.rs | 22 |
5 files changed, 48 insertions, 0 deletions
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index bfc5ce01564..53433823fbd 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 26ef93e3d71..b39863644f1 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::<OwnedFd>::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::<Option<OwnedFd>>(), size_of::<RawFd>()); + assert_eq!(size_of::<Option<BorrowedFd<'static>>>(), size_of::<RawFd>()); + 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 2f6f0769548..3325688e661 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 c14a1d6192f..baae92c19f2 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 00000000000..54175473707 --- /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::<Option<OwnedSocket>>(), size_of::<RawSocket>()); + assert_eq!(size_of::<Option<BorrowedSocket<'static>>>(), size_of::<RawSocket>(),); + 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 + ); + } +} |
