From c2b919724ff0a0f47a2276cad953d2174c46c378 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 6 Jun 2023 17:36:15 -0700 Subject: [PATCH] Disable the `BorrowedFd` layout optimization on Haiku On Haiku (and apparently only Haiku), the platform `AT_FDCWD` has the value `-1`. However, `BorrowedFd` currently has layout optimizations that assume the value is not `-1`, and it's useful to be able to store `AT_FDCWD` in a `BorrowedFd`. For example, rustix has [a function which returns a `BorrowedFd` containing `AT_FDCWD`]. To support this on Haiku, disable the layout optimizations for `BorrowedFd` on Haiku and allow it to store the value `-1`. This is technically a breaking change for Haiku users, as they could theoretically be depending on `Option` having the same layout as `RawFd`, however this is not a common idiom, and Haiku support is [Tier 3] in Rust. [a function which returns a `BorrowedFd` containing `AT_FDCWD`]: https://docs.rs/rustix/latest/rustix/fs/fn.cwd.html [Tier 3]: https://doc.rust-lang.org/nightly/rustc/platform-support.html#tier-3 --- library/std/src/os/fd/owned.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 2180d2974d5ae..c192d71069531 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -20,20 +20,25 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; /// /// This uses `repr(transparent)` and has the representation of a host file /// descriptor, so it can be used in FFI in places where a file descriptor is -/// passed as an argument, it is not captured or consumed, and it never has the -/// value `-1`. +/// passed as an argument, it is not captured or consumed. +/// +/// On all platforms except Haiku, it never has the value `-1`. /// /// This type's `.to_owned()` implementation returns another `BorrowedFd` /// rather than an `OwnedFd`. It just makes a trivial copy of the raw file /// descriptor, which is then borrowed under the same lifetime. #[derive(Copy, Clone)] #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] +// On Haiku, the `-1` is the value of `AT_FDCWD`, which should be valid to store +// in a `BorrowedFd`, so Haiku can't participate in the layout optimization for +// `BorrowedFd`. It can still participate in the layout optimization for +// `OwnedFd`, as APIs where `AT_FDCWD` is accepted don't take ownership of it. +#[cfg_attr(not(target_os = "haiku"), rustc_layout_scalar_valid_range_start(0))] // libstd/os/raw/mod.rs assures me that every libstd-supported platform has a // 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] +#[cfg_attr(not(target_os = "haiku"), rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] +#[cfg_attr(not(target_os = "haiku"), rustc_nonnull_optimization_guaranteed)] #[stable(feature = "io_safety", since = "1.63.0")] pub struct BorrowedFd<'fd> { fd: RawFd, @@ -66,12 +71,15 @@ impl BorrowedFd<'_> { /// # Safety /// /// The resource pointed to by `fd` must remain open for the duration of - /// the returned `BorrowedFd`, and it must not have the value `-1`. + /// the returned `BorrowedFd`. And on all platforms except Haiku, it must + /// not have the value `-1`. #[inline] #[rustc_const_stable(feature = "io_safety", since = "1.63.0")] #[stable(feature = "io_safety", since = "1.63.0")] pub const unsafe fn borrow_raw(fd: RawFd) -> Self { + #[cfg(not(target_os = "haiku"))] assert!(fd != u32::MAX as RawFd); + // SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) unsafe { Self { fd, _phantom: PhantomData } } }