Rollup merge of #96947 - sunfishcode:sunfishcode/rustc-nonnull-optimization-guaranteed, r=joshtriplett

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
This commit is contained in:
Dylan DPC 2022-05-15 18:41:25 +02:00 committed by GitHub
commit f8832c23da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 0 deletions

View File

@ -32,6 +32,7 @@
// 32-bit c_int. Below is -2, in two's complement, but that only works out // 32-bit c_int. Below is -2, in two's complement, but that only works out
// because c_int is 32 bits. // because c_int is 32 bits.
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] #[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")] #[unstable(feature = "io_safety", issue = "87074")]
pub struct BorrowedFd<'fd> { pub struct BorrowedFd<'fd> {
fd: RawFd, 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 // 32-bit c_int. Below is -2, in two's complement, but that only works out
// because c_int is 32 bits. // because c_int is 32 bits.
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] #[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")] #[unstable(feature = "io_safety", issue = "87074")]
pub struct OwnedFd { pub struct OwnedFd {
fd: RawFd, fd: RawFd,

View File

@ -32,3 +32,22 @@ fn test_fd() {
assert_eq!(stdin_as_file.as_fd().as_raw_fd(), raw_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); 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);
}
}

View File

@ -54,3 +54,6 @@
pub use raw::*; pub use raw::*;
#[unstable(feature = "io_safety", issue = "87074")] #[unstable(feature = "io_safety", issue = "87074")]
pub use socket::*; pub use socket::*;
#[cfg(test)]
mod tests;

View File

@ -34,6 +34,7 @@
target_pointer_width = "64", target_pointer_width = "64",
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
)] )]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")] #[unstable(feature = "io_safety", issue = "87074")]
pub struct BorrowedSocket<'socket> { pub struct BorrowedSocket<'socket> {
socket: RawSocket, socket: RawSocket,
@ -56,6 +57,7 @@ pub struct BorrowedSocket<'socket> {
target_pointer_width = "64", target_pointer_width = "64",
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
)] )]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")] #[unstable(feature = "io_safety", issue = "87074")]
pub struct OwnedSocket { pub struct OwnedSocket {
socket: RawSocket, socket: RawSocket,

View File

@ -0,0 +1,21 @@
#[test]
fn test_niche_optimizations_socket() {
use crate::mem::size_of;
use crate::os::windows::io::{
BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
};
assert_eq!(size_of::<Option<OwnedSocket>>(), size_of::<RawSocket>());
assert_eq!(size_of::<Option<BorrowedSocket<'static>>>(), size_of::<RawSocket>(),);
unsafe {
#[cfg(target_pointer_width = "32")]
let (min, max) = (i32::MIN as u32, i32::MAX as u32);
#[cfg(target_pointer_width = "64")]
let (min, max) = (i64::MIN as u64, i64::MAX as u64);
assert_eq!(OwnedSocket::from_raw_socket(min).into_raw_socket(), min);
assert_eq!(OwnedSocket::from_raw_socket(max).into_raw_socket(), max);
assert_eq!(Some(OwnedSocket::from_raw_socket(min)).unwrap().into_raw_socket(), min);
assert_eq!(Some(OwnedSocket::from_raw_socket(max)).unwrap().into_raw_socket(), max);
}
}