Skip to content

Commit f8832c2

Browse files
authored
Rollup merge of rust-lang#96947 - sunfishcode:sunfishcode/rustc-nonnull-optimization-guaranteed, r=joshtriplett
Add rustc_nonnull_optimization_guaranteed to Owned/Borrowed Fd/Socket PR rust-lang#94586 added support for using `rustc_nonnull_optimization_guaranteed` on values where the "null" value is the all-ones bitpattern. Now that rust-lang#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
2 parents a170f2b + 5c60951 commit f8832c2

File tree

5 files changed

+47
-0
lines changed

5 files changed

+47
-0
lines changed

library/std/src/os/fd/owned.rs

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
3232
// 32-bit c_int. Below is -2, in two's complement, but that only works out
3333
// because c_int is 32 bits.
3434
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
35+
#[rustc_nonnull_optimization_guaranteed]
3536
#[unstable(feature = "io_safety", issue = "87074")]
3637
pub struct BorrowedFd<'fd> {
3738
fd: RawFd,
@@ -52,6 +53,7 @@ pub struct BorrowedFd<'fd> {
5253
// 32-bit c_int. Below is -2, in two's complement, but that only works out
5354
// because c_int is 32 bits.
5455
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
56+
#[rustc_nonnull_optimization_guaranteed]
5557
#[unstable(feature = "io_safety", issue = "87074")]
5658
pub struct OwnedFd {
5759
fd: RawFd,

library/std/src/os/fd/tests.rs

+19
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,22 @@ fn test_fd() {
3232
assert_eq!(stdin_as_file.as_fd().as_raw_fd(), raw_fd);
3333
assert_eq!(Into::<OwnedFd>::into(stdin_as_file).into_raw_fd(), raw_fd);
3434
}
35+
36+
#[cfg(any(unix, target_os = "wasi"))]
37+
#[test]
38+
fn test_niche_optimizations() {
39+
use crate::mem::size_of;
40+
#[cfg(unix)]
41+
use crate::os::unix::io::{BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
42+
#[cfg(target_os = "wasi")]
43+
use crate::os::wasi::io::{BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
44+
45+
assert_eq!(size_of::<Option<OwnedFd>>(), size_of::<RawFd>());
46+
assert_eq!(size_of::<Option<BorrowedFd<'static>>>(), size_of::<RawFd>());
47+
unsafe {
48+
assert_eq!(OwnedFd::from_raw_fd(RawFd::MIN).into_raw_fd(), RawFd::MIN);
49+
assert_eq!(OwnedFd::from_raw_fd(RawFd::MAX).into_raw_fd(), RawFd::MAX);
50+
assert_eq!(Some(OwnedFd::from_raw_fd(RawFd::MIN)).unwrap().into_raw_fd(), RawFd::MIN);
51+
assert_eq!(Some(OwnedFd::from_raw_fd(RawFd::MAX)).unwrap().into_raw_fd(), RawFd::MAX);
52+
}
53+
}

library/std/src/os/windows/io/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,6 @@ pub use handle::*;
5454
pub use raw::*;
5555
#[unstable(feature = "io_safety", issue = "87074")]
5656
pub use socket::*;
57+
58+
#[cfg(test)]
59+
mod tests;

library/std/src/os/windows/io/socket.rs

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use crate::sys::cvt;
3434
target_pointer_width = "64",
3535
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
3636
)]
37+
#[rustc_nonnull_optimization_guaranteed]
3738
#[unstable(feature = "io_safety", issue = "87074")]
3839
pub struct BorrowedSocket<'socket> {
3940
socket: RawSocket,
@@ -56,6 +57,7 @@ pub struct BorrowedSocket<'socket> {
5657
target_pointer_width = "64",
5758
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
5859
)]
60+
#[rustc_nonnull_optimization_guaranteed]
5961
#[unstable(feature = "io_safety", issue = "87074")]
6062
pub struct OwnedSocket {
6163
socket: RawSocket,
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#[test]
2+
fn test_niche_optimizations_socket() {
3+
use crate::mem::size_of;
4+
use crate::os::windows::io::{
5+
BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
6+
};
7+
8+
assert_eq!(size_of::<Option<OwnedSocket>>(), size_of::<RawSocket>());
9+
assert_eq!(size_of::<Option<BorrowedSocket<'static>>>(), size_of::<RawSocket>(),);
10+
unsafe {
11+
#[cfg(target_pointer_width = "32")]
12+
let (min, max) = (i32::MIN as u32, i32::MAX as u32);
13+
#[cfg(target_pointer_width = "64")]
14+
let (min, max) = (i64::MIN as u64, i64::MAX as u64);
15+
16+
assert_eq!(OwnedSocket::from_raw_socket(min).into_raw_socket(), min);
17+
assert_eq!(OwnedSocket::from_raw_socket(max).into_raw_socket(), max);
18+
assert_eq!(Some(OwnedSocket::from_raw_socket(min)).unwrap().into_raw_socket(), min);
19+
assert_eq!(Some(OwnedSocket::from_raw_socket(max)).unwrap().into_raw_socket(), max);
20+
}
21+
}

0 commit comments

Comments
 (0)