diff --git a/Cargo.toml b/Cargo.toml index 0651fbb..50ae4f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ fs-err = { version = "2.6.0", optional = true } os_pipe = { version = "1.0.0", features = ["io_safety"], optional = true } # The following dependencies allow io-lifetimes to define impls for various -# third-party traits. This is only done in not(io_lifetimes_use_std) mode, +# third-party traits. This is only done in not(io_safety_is_in_std) mode, # because when we're using the std types and traits, we can't define impls # on third-party traits, due to the orphan rule. Work is ongoing to add # the needs impls upstream. diff --git a/README.md b/README.md index b8c9227..deca3b2 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,6 @@ This is associated with [RFC 3128], the I/O Safety RFC, which is now merged. Work is now underway to move the `OwnedFd` and `BorrowedFd` types and `AsFd` trait developed here into `std`. -Some features currently require nightly Rust, as they depend on `rustc_attrs` -to perform niche optimizations needed for FFI use cases. - For a quick taste, check out the code examples: - [hello], a basic demo of this API, doing low-level I/O manually, using the diff --git a/build.rs b/build.rs index 42c1eb8..fd3c6cc 100644 --- a/build.rs +++ b/build.rs @@ -4,13 +4,9 @@ use std::io::Write; fn main() { // I/O safety is stabilized in Rust 1.63. if has_io_safety() { - use_feature("io_lifetimes_use_std") + use_feature("io_safety_is_in_std") } - // Niche optimizations for `Borrowed*` and `Owned*` depend on `rustc_attrs` - // which, outside of `std`, are only available on nightly. - use_feature_or_nothing("rustc_attrs"); - // Work around // https://github.com/rust-lang/rust/issues/103306. use_feature_or_nothing("wasi_ext"); diff --git a/examples/hello.rs b/examples/hello.rs index 95ed436..ffa51c8 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -1,7 +1,7 @@ //! A simple testcase that prints a few messages to the console, demonstrating //! the io-lifetimes API. -#![cfg_attr(not(rustc_attrs), allow(unused_imports))] +#![cfg_attr(not(io_safety_is_in_std), allow(unused_imports))] #[cfg(feature = "close")] use io_lifetimes::example_ffi::*; @@ -14,12 +14,12 @@ use std::{ #[cfg(all(unix, feature = "close"))] use io_lifetimes::{AsFd, OwnedFd}; -#[cfg(windows)] -use io_lifetimes::{AsHandle, FromHandle, OwnedHandle}; -#[cfg(windows)] +#[cfg(all(windows, feature = "close"))] +use io_lifetimes::{AsHandle, OwnedHandle}; +#[cfg(all(windows, feature = "close"))] use std::{convert::TryInto, os::windows::io::RawHandle, ptr::null_mut}; -#[cfg(all(rustc_attrs, unix, feature = "close"))] +#[cfg(all(io_safety_is_in_std, unix, feature = "close"))] fn main() -> io::Result<()> { let fd = unsafe { // Open a file, which returns an `Option`, which we can @@ -120,9 +120,9 @@ fn main() -> io::Result<()> { } #[cfg(all( - not(all(rustc_attrs, unix, feature = "close")), + not(all(io_safety_is_in_std, unix, feature = "close")), not(all(windows, feature = "close")) ))] fn main() { - println!("On Unix, this example requires Rust nightly (for `rustc_attrs`) and the \"close\" feature."); + println!("On Unix, this example requires Rust nightly (for `io_safety_is_in_std`) and the \"close\" feature."); } diff --git a/examples/owning-wrapper.rs b/examples/owning-wrapper.rs index 873436c..fdabfaa 100644 --- a/examples/owning-wrapper.rs +++ b/examples/owning-wrapper.rs @@ -1,16 +1,16 @@ //! A simple example implementing the main traits for a type. #[cfg(not(windows))] -#[cfg(any(feature = "close", not(io_lifetimes_use_std)))] +#[cfg(any(feature = "close", not(io_safety_is_in_std)))] use io_lifetimes::FromFd; #[cfg(windows)] -#[cfg(any(feature = "close", not(io_lifetimes_use_std)))] +#[cfg(any(feature = "close", not(io_safety_is_in_std)))] use io_lifetimes::FromHandle; #[cfg(not(windows))] -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] use io_lifetimes::IntoFd; #[cfg(windows)] -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] use io_lifetimes::IntoHandle; use io_lifetimes::OwnedFilelike; #[cfg(not(windows))] @@ -43,7 +43,7 @@ impl AsFd for Thing { } } -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(not(windows))] impl IntoFd for Thing { #[inline] @@ -60,7 +60,7 @@ impl From for OwnedFd { } } -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(not(windows))] impl FromFd for Thing { #[inline] @@ -85,7 +85,7 @@ impl AsHandle for Thing { } } -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(windows)] impl IntoHandle for Thing { #[inline] @@ -102,7 +102,7 @@ impl From for OwnedHandle { } } -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(windows)] impl FromHandle for Thing { #[inline] diff --git a/src/example_ffi.rs b/src/example_ffi.rs index 8f7c238..0b31b9e 100644 --- a/src/example_ffi.rs +++ b/src/example_ffi.rs @@ -1,6 +1,6 @@ //! This is just a sample of what FFI using this crate can look like. -#![cfg_attr(not(rustc_attrs), allow(unused_imports))] +#![cfg_attr(not(io_safety_is_in_std), allow(unused_imports))] #![allow(missing_docs)] #[cfg(any(unix, target_os = "wasi"))] @@ -23,7 +23,7 @@ use { }; // Declare a few FFI functions ourselves, to show off the FFI ergonomics. -#[cfg(all(rustc_attrs, any(unix, target_os = "wasi")))] +#[cfg(all(io_safety_is_in_std, any(unix, target_os = "wasi")))] extern "C" { pub fn open(pathname: *const c_char, flags: c_int, ...) -> Option; } diff --git a/src/lib.rs b/src/lib.rs index af66ccd..da5e740 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,22 +28,21 @@ //! [from+into conversions]: FromFilelike::from_into_filelike #![deny(missing_docs)] -#![cfg_attr(rustc_attrs, feature(rustc_attrs))] // Work around https://github.com/rust-lang/rust/issues/103306. #![cfg_attr(all(wasi_ext, target_os = "wasi"), feature(wasi_ext))] mod portability; mod traits; -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] mod types; -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] mod impls_std; -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(any(unix, target_os = "wasi"))] pub use traits::AsFd; -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(windows)] pub use traits::{AsHandle, AsSocket}; #[cfg(any(unix, target_os = "wasi"))] @@ -53,23 +52,23 @@ pub use traits::{FromFd, IntoFd}; #[allow(deprecated)] pub use traits::{FromHandle, FromSocket, IntoHandle, IntoSocket}; -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(any(unix, target_os = "wasi"))] pub use types::{BorrowedFd, OwnedFd}; -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(windows)] pub use types::{ BorrowedHandle, BorrowedSocket, HandleOrInvalid, InvalidHandleError, NullHandleError, OwnedHandle, OwnedSocket, }; -#[cfg(io_lifetimes_use_std)] +#[cfg(io_safety_is_in_std)] #[cfg(unix)] pub use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; -#[cfg(io_lifetimes_use_std)] +#[cfg(io_safety_is_in_std)] #[cfg(target_os = "wasi")] pub use std::os::wasi::io::{AsFd, BorrowedFd, OwnedFd}; -#[cfg(io_lifetimes_use_std)] +#[cfg(io_safety_is_in_std)] #[cfg(windows)] pub use std::os::windows::io::{ AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, HandleOrInvalid, InvalidHandleError, @@ -87,7 +86,7 @@ pub use std::os::windows::io::{ // // So we define `FromFd`/`IntoFd` traits, and implement them in terms of // `From`/`Into`, -#[cfg(io_lifetimes_use_std)] +#[cfg(io_safety_is_in_std)] #[cfg(any(unix, target_os = "wasi"))] #[allow(deprecated)] impl> FromFd for T { @@ -96,7 +95,7 @@ impl> FromFd for T { owned_fd.into() } } -#[cfg(io_lifetimes_use_std)] +#[cfg(io_safety_is_in_std)] #[cfg(any(unix, target_os = "wasi"))] #[allow(deprecated)] impl IntoFd for T @@ -109,7 +108,7 @@ where } } -#[cfg(io_lifetimes_use_std)] +#[cfg(io_safety_is_in_std)] #[cfg(windows)] #[allow(deprecated)] impl> FromHandle for T { @@ -118,7 +117,7 @@ impl> FromHandle for T { owned_handle.into() } } -#[cfg(io_lifetimes_use_std)] +#[cfg(io_safety_is_in_std)] #[cfg(windows)] #[allow(deprecated)] impl IntoHandle for T @@ -131,7 +130,7 @@ where } } -#[cfg(io_lifetimes_use_std)] +#[cfg(io_safety_is_in_std)] #[cfg(windows)] #[allow(deprecated)] impl> FromSocket for T { @@ -140,7 +139,7 @@ impl> FromSocket for T { owned_socket.into() } } -#[cfg(io_lifetimes_use_std)] +#[cfg(io_safety_is_in_std)] #[cfg(windows)] #[allow(deprecated)] impl IntoSocket for T @@ -165,22 +164,22 @@ pub mod views; // Ideally, we'd want crates to implement our traits themselves. But for now, // while we're prototyping, we provide a few impls on foreign types. -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(feature = "async-std")] mod impls_async_std; -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(feature = "fs-err")] mod impls_fs_err; -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(feature = "mio")] mod impls_mio; #[cfg(not(target_os = "wasi"))] -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(feature = "os_pipe")] mod impls_os_pipe; -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(feature = "socket2")] mod impls_socket2; -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(feature = "tokio")] mod impls_tokio; diff --git a/src/traits.rs b/src/traits.rs index 5e80b75..7fb9a5b 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,9 +1,9 @@ -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(any(unix, target_os = "wasi"))] use crate::BorrowedFd; #[cfg(any(unix, target_os = "wasi"))] use crate::OwnedFd; -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(windows)] use crate::{BorrowedHandle, BorrowedSocket}; #[cfg(windows)] @@ -14,7 +14,7 @@ use crate::{OwnedHandle, OwnedSocket}; /// This is only available on unix platforms and must be imported in order to /// call the method. Windows platforms have a corresponding `AsHandle` and /// `AsSocket` set of traits. -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(any(unix, target_os = "wasi"))] pub trait AsFd { /// Borrows the file descriptor. @@ -34,7 +34,7 @@ pub trait AsFd { } /// A trait to borrow the handle from an underlying object. -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(windows)] pub trait AsHandle { /// Borrows the handle. @@ -54,7 +54,7 @@ pub trait AsHandle { } /// A trait to borrow the socket from an underlying object. -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(windows)] pub trait AsSocket { /// Borrows the socket. @@ -235,7 +235,7 @@ pub trait FromSocket { } } -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(any(unix, target_os = "wasi"))] impl AsFd for &T { #[inline] @@ -244,7 +244,7 @@ impl AsFd for &T { } } -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(any(unix, target_os = "wasi"))] impl AsFd for &mut T { #[inline] @@ -253,7 +253,7 @@ impl AsFd for &mut T { } } -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(windows)] impl AsHandle for &T { #[inline] @@ -262,7 +262,7 @@ impl AsHandle for &T { } } -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(windows)] impl AsHandle for &mut T { #[inline] @@ -271,7 +271,7 @@ impl AsHandle for &mut T { } } -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(windows)] impl AsSocket for &T { #[inline] @@ -280,7 +280,7 @@ impl AsSocket for &T { } } -#[cfg(not(io_lifetimes_use_std))] +#[cfg(not(io_safety_is_in_std))] #[cfg(windows)] impl AsSocket for &mut T { #[inline] diff --git a/src/types.rs b/src/types.rs index 695ae51..7f7809f 100644 --- a/src/types.rs +++ b/src/types.rs @@ -50,12 +50,6 @@ const INVALID_SOCKET: usize = !0 as _; #[cfg(any(unix, target_os = "wasi"))] #[derive(Copy, Clone)] #[repr(transparent)] -#[cfg_attr(rustc_attrs, rustc_nonnull_optimization_guaranteed)] -#[cfg_attr(rustc_attrs, 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. -#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] pub struct BorrowedFd<'fd> { fd: RawFd, _phantom: PhantomData<&'fd OwnedFd>, @@ -105,17 +99,6 @@ pub struct BorrowedHandle<'handle> { #[cfg(windows)] #[derive(Copy, Clone)] #[repr(transparent)] -#[cfg_attr(rustc_attrs, rustc_nonnull_optimization_guaranteed)] -#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_start(0))] -// This is -2, in two's complement. -1 is `INVALID_SOCKET`. -#[cfg_attr( - all(rustc_attrs, target_pointer_width = "32"), - rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE) -)] -#[cfg_attr( - all(rustc_attrs, target_pointer_width = "64"), - rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) -)] pub struct BorrowedSocket<'socket> { socket: RawSocket, _phantom: PhantomData<&'socket OwnedSocket>, @@ -131,12 +114,6 @@ pub struct BorrowedSocket<'socket> { /// has the value `-1`. #[cfg(any(unix, target_os = "wasi"))] #[repr(transparent)] -#[cfg_attr(rustc_attrs, rustc_nonnull_optimization_guaranteed)] -#[cfg_attr(rustc_attrs, 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. -#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] pub struct OwnedFd { fd: RawFd, } @@ -286,17 +263,6 @@ impl BorrowedHandle<'_> { /// [`INVALID_SOCKET`]. #[cfg(windows)] #[repr(transparent)] -#[cfg_attr(rustc_attrs, rustc_nonnull_optimization_guaranteed)] -#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_start(0))] -// This is -2, in two's complement. -1 is `INVALID_SOCKET`. -#[cfg_attr( - all(rustc_attrs, target_pointer_width = "32"), - rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE) -)] -#[cfg_attr( - all(rustc_attrs, target_pointer_width = "64"), - rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) -)] pub struct OwnedSocket { socket: RawSocket, } diff --git a/tests/ffi.rs b/tests/ffi.rs index 2e3ce6d..363cb4c 100644 --- a/tests/ffi.rs +++ b/tests/ffi.rs @@ -1,4 +1,4 @@ -#![cfg_attr(not(rustc_attrs), allow(unused_imports))] +#![cfg_attr(not(io_safety_is_in_std), allow(unused_imports))] #![cfg(feature = "close")] #[cfg(any(unix, windows))] @@ -12,7 +12,7 @@ use windows_sys::Win32::Storage::FileSystem::{ FILE_ATTRIBUTE_NORMAL, FILE_GENERIC_READ, OPEN_EXISTING, }; -#[cfg(all(rustc_attrs, unix))] +#[cfg(all(io_safety_is_in_std, unix))] #[test] fn test_file_not_found() { assert!(unsafe { @@ -50,7 +50,7 @@ fn test_file_not_found() { ); } -#[cfg(all(rustc_attrs, unix))] +#[cfg(all(io_safety_is_in_std, unix))] #[test] fn test_file_found() { assert!(unsafe { open("Cargo.toml\0".as_ptr() as *const _, O_RDONLY | O_CLOEXEC) }.is_some()); diff --git a/tests/niche-optimizations.rs b/tests/niche-optimizations.rs index 37f0437..b73cef2 100644 --- a/tests/niche-optimizations.rs +++ b/tests/niche-optimizations.rs @@ -1,4 +1,4 @@ -#![cfg_attr(not(rustc_attrs), allow(unused_imports))] +#![cfg_attr(not(io_safety_is_in_std), allow(unused_imports))] #![cfg_attr(target_os = "wasi", feature(wasi_ext))] use std::mem::size_of; @@ -15,7 +15,7 @@ use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd}; #[cfg(windows)] use std::os::windows::io::{FromRawSocket, IntoRawSocket, RawSocket}; -#[cfg(all(rustc_attrs, any(unix, target_os = "wasi")))] +#[cfg(all(io_safety_is_in_std, any(unix, target_os = "wasi")))] #[test] fn test_niche_optimizations() { assert_eq!(size_of::>(), size_of::()); @@ -38,7 +38,7 @@ fn test_niche_optimizations() { } } -#[cfg(all(rustc_attrs, windows))] +#[cfg(all(io_safety_is_in_std, windows))] #[test] fn test_niche_optimizations_socket() { assert_eq!(size_of::>(), size_of::());