diff --git a/README.md b/README.md index 3db3d3c..0a97bed 100644 --- a/README.md +++ b/README.md @@ -95,37 +95,16 @@ is what motivates having `BorrowedFd` instead of just using `&OwnedFd`. Note the use of `Option` as the return value of `open`, representing the fact that it can either succeed or fail. -## I/O Safety in Rust Nightly +## I/O Safety in Rust -The I/O Safety -[implementation PR](https://github.com/rust-lang/rust/pull/87329) has now -landed and is available on Rust Nightly. It can be used directly, or through -io-lifetimes: when `io_lifetimes_use_std` mode is enabled, io-lifetimes uses -the std's `OwnedFd`, `BorrowedFd`, and `AsFd` instead of defining its own. - -To enable `io_lifetimes_use_std` mode: - - Set the environment variable `RUSTFLAGS=--cfg=io_lifetimes_use_std`, and - - add `#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]` to your - lib.rs or main.rs. - -Note that, unfortunately, `io_lifetimes_use_std` mode doesn't support the -optional impls for third-party crates. - -The code in `std` uses `From` and `Into` instead of `FromFd` -and `IntoFd`. io-lifetimes is unable to provide impls for these for third-party -types, so it continues to provide `FromFd` and `IntoFd` for now, with default -impls that forward to `From` and `Into` in -`io_lifetimes_use_std` mode. +I/O Safety feature is stablized in Rust 1.63. With this version or later, +io-lifetimes will use and re-export the standard-library types and traits. With +older versions, io-lifetimes defines its own copy of these types and traits. io-lifetimes also includes several features which are not (yet?) in std, including the portability traits `AsFilelike`/`AsSocketlike`/etc., the `from_into_*` functions in the `From*` traits, and [views]. -If you test a crate with the std I/O safety types and traits, or io-lifetimes -in `io_lifetimes_use_std` mode, please post a note about it in the -[I/O safety tracking issue] as an example of usage. - -[I/O safety tracking issue]: https://github.com/rust-lang/rust/issues/87074 [views]: https://docs.rs/io-lifetimes/*/io_lifetimes/views/index.html ## Prior Art diff --git a/build.rs b/build.rs index 8102686..39c114a 100644 --- a/build.rs +++ b/build.rs @@ -2,6 +2,11 @@ use std::env::var; 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") + } + // 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"); @@ -65,3 +70,36 @@ fn has_panic_in_const_fn() -> bool { child.wait().unwrap().success() } + +/// Test whether the rustc at `var("RUSTC")` supports the I/O safety feature. +fn has_io_safety() -> bool { + let out_dir = var("OUT_DIR").unwrap(); + let rustc = var("RUSTC").unwrap(); + + let mut child = std::process::Command::new(rustc) + .arg("--crate-type=rlib") // Don't require `main`. + .arg("--emit=metadata") // Do as little as possible but still parse. + .arg("--out-dir") + .arg(out_dir) // Put the output somewhere inconsequential. + .arg("-") // Read from stdin. + .stdin(std::process::Stdio::piped()) // Stdin is a pipe. + .spawn() + .unwrap(); + + writeln!( + child.stdin.take().unwrap(), + "\ + #[cfg(unix)]\n\ + use std::os::unix::io::OwnedFd as Owned;\n\ + #[cfg(target_os = \"wasi\")]\n\ + use std::os::wasi::io::OwnedFd as Owned;\n\ + #[cfg(windows)]\n\ + use std::os::windows::io::OwnedHandle as Owned;\n\ + \n\ + pub type Success = Owned;\n\ + " + ) + .unwrap(); + + child.wait().unwrap().success() +} diff --git a/examples/easy-conversions.rs b/examples/easy-conversions.rs index 87481c1..56c7a24 100644 --- a/examples/easy-conversions.rs +++ b/examples/easy-conversions.rs @@ -2,8 +2,6 @@ //! implementing `IntoFilelike` and `FromSocketlike` to types implementing //! `FromFilelike` and `IntoSocketlike`, respectively. -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] - use io_lifetimes::FromFilelike; use std::fs::File; use std::io::{self, Read}; diff --git a/examples/flexible-apis.rs b/examples/flexible-apis.rs index 8eb19a2..214fac0 100644 --- a/examples/flexible-apis.rs +++ b/examples/flexible-apis.rs @@ -4,10 +4,8 @@ //! The following uses the POSIX-ish `Fd` types; similar considerations //! apply to the Windows and portable types. -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] - #[cfg(all(feature = "close", not(windows)))] -use io_lifetimes::{AsFd, BorrowedFd, IntoFd, OwnedFd}; +use io_lifetimes::{AsFd, BorrowedFd, OwnedFd}; /// The simplest way to accept a borrowed I/O resource is to simply use a /// `BorrwedFd` as an argument. This doesn't require the function to have any @@ -53,14 +51,14 @@ fn consume_fd_a(fd: OwnedFd) { /// has the advantage of allowing users to pass in any type implementing /// `IntoFd` directly. #[cfg(all(feature = "close", not(windows)))] -fn consume_fd_b(fd: Fd) { - let _ = fd.into_fd(); +fn consume_fd_b>(fd: Fd) { + let _: OwnedFd = fd.into(); } /// Another way to do this is to use an `impl IntoFd` parameter. #[cfg(all(feature = "close", not(windows)))] -fn consume_fd_c(fd: impl IntoFd) { - let _ = fd.into_fd(); +fn consume_fd_c(fd: impl Into) { + let _: OwnedFd = fd.into(); } /// Now let's see how the APIs look for users. @@ -87,13 +85,13 @@ fn main() { let b = std::fs::File::open("Cargo.toml").unwrap(); let c = std::fs::File::open("Cargo.toml").unwrap(); - // The simple option requires an `.into_fd()` at the callsite. - consume_fd_a(a.into_fd()); + // The simple option requires an `.into()` at the callsite. + consume_fd_a(a.into()); - // Another option can take any `IntoFd` type directly. + // Another option can take any `Into` type directly. consume_fd_b(b); - // The other option can take any `IntoFd` type directly. + // The other option can take any `Into` type directly. consume_fd_c(c); } diff --git a/examples/hello.rs b/examples/hello.rs index 4f6b1a4..95ed436 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -2,7 +2,6 @@ //! the io-lifetimes API. #![cfg_attr(not(rustc_attrs), allow(unused_imports))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] #[cfg(feature = "close")] use io_lifetimes::example_ffi::*; @@ -13,7 +12,7 @@ use std::{ }; #[cfg(all(unix, feature = "close"))] -use io_lifetimes::{AsFd, FromFd, OwnedFd}; +use io_lifetimes::{AsFd, OwnedFd}; #[cfg(windows)] use io_lifetimes::{AsHandle, FromHandle, OwnedHandle}; @@ -40,7 +39,7 @@ fn main() -> io::Result<()> { }; // Convert into a `File`. No `unsafe` here! - let mut file = File::from_fd(fd); + let mut file = File::from(fd); writeln!(&mut file, "greetings, y'all")?; // We can borrow a `BorrowedFd` from a `File`. @@ -95,7 +94,7 @@ fn main() -> io::Result<()> { }; // Convert into a `File`. No `unsafe` here! - let mut file = File::from_handle(handle); + let mut file = File::from(handle); writeln!(&mut file, "greetings, y'all")?; // We can borrow a `BorrowedHandle` from a `File`. diff --git a/examples/owning-wrapper.rs b/examples/owning-wrapper.rs index 74a05b2..873436c 100644 --- a/examples/owning-wrapper.rs +++ b/examples/owning-wrapper.rs @@ -1,12 +1,22 @@ //! A simple example implementing the main traits for a type. -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] - +#[cfg(not(windows))] +#[cfg(any(feature = "close", not(io_lifetimes_use_std)))] +use io_lifetimes::FromFd; +#[cfg(windows)] +#[cfg(any(feature = "close", not(io_lifetimes_use_std)))] +use io_lifetimes::FromHandle; +#[cfg(not(windows))] +#[cfg(not(io_lifetimes_use_std))] +use io_lifetimes::IntoFd; +#[cfg(windows)] +#[cfg(not(io_lifetimes_use_std))] +use io_lifetimes::IntoHandle; use io_lifetimes::OwnedFilelike; #[cfg(not(windows))] -use io_lifetimes::{AsFd, BorrowedFd, FromFd, IntoFd, OwnedFd}; +use io_lifetimes::{AsFd, BorrowedFd, OwnedFd}; #[cfg(windows)] -use io_lifetimes::{AsHandle, BorrowedHandle, FromHandle, IntoHandle, OwnedHandle}; +use io_lifetimes::{AsHandle, BorrowedHandle, OwnedHandle}; /// A wrapper around a file descriptor. /// @@ -33,6 +43,7 @@ impl AsFd for Thing { } } +#[cfg(not(io_lifetimes_use_std))] #[cfg(not(windows))] impl IntoFd for Thing { #[inline] @@ -41,7 +52,6 @@ impl IntoFd for Thing { } } -#[cfg(not(io_lifetimes_use_std))] #[cfg(not(windows))] impl From for OwnedFd { #[inline] @@ -50,6 +60,7 @@ impl From for OwnedFd { } } +#[cfg(not(io_lifetimes_use_std))] #[cfg(not(windows))] impl FromFd for Thing { #[inline] @@ -58,7 +69,6 @@ impl FromFd for Thing { } } -#[cfg(not(io_lifetimes_use_std))] #[cfg(not(windows))] impl From for Thing { #[inline] @@ -75,6 +85,7 @@ impl AsHandle for Thing { } } +#[cfg(not(io_lifetimes_use_std))] #[cfg(windows)] impl IntoHandle for Thing { #[inline] @@ -83,7 +94,6 @@ impl IntoHandle for Thing { } } -#[cfg(not(io_lifetimes_use_std))] #[cfg(windows)] impl From for OwnedHandle { #[inline] @@ -92,6 +102,7 @@ impl From for OwnedHandle { } } +#[cfg(not(io_lifetimes_use_std))] #[cfg(windows)] impl FromHandle for Thing { #[inline] @@ -100,7 +111,6 @@ impl FromHandle for Thing { } } -#[cfg(not(io_lifetimes_use_std))] #[cfg(windows)] impl From for Thing { #[inline] @@ -119,7 +129,7 @@ fn main() { let file = std::fs::File::open("Cargo.toml").unwrap(); let thing = Thing::from_into_fd(file); let _ = thing.as_fd(); - let _ = thing.into_fd(); + let _: OwnedFd = thing.into(); } // Minimally exercise `Thing`'s Windows API. @@ -128,7 +138,7 @@ fn main() { let file = std::fs::File::open("Cargo.toml").unwrap(); let thing = Thing::from_into_handle(file); let _ = thing.as_handle(); - let _ = thing.into_handle(); + let _: OwnedHandle = thing.into(); } // Implementing the above traits makes the blanket impls for the portable diff --git a/examples/portable-views.rs b/examples/portable-views.rs index 410b4c2..074cd99 100644 --- a/examples/portable-views.rs +++ b/examples/portable-views.rs @@ -1,8 +1,6 @@ //! io-lifetimes provides safe, convenient, and portable ways to temporarily //! view an I/O resource as a `File`, `Socket`, or other types. -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] - use io_lifetimes::AsFilelike; use std::fs::File; use std::io::{self, stdout}; diff --git a/src/lib.rs b/src/lib.rs index 5e2a9d1..2b3f1fd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,6 @@ #![deny(missing_docs)] #![cfg_attr(rustc_attrs, feature(rustc_attrs))] #![cfg_attr(all(io_lifetimes_use_std, target_os = "wasi"), feature(wasi_ext))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] mod portability; mod traits; @@ -48,8 +47,10 @@ pub use traits::AsFd; #[cfg(windows)] pub use traits::{AsHandle, AsSocket}; #[cfg(any(unix, target_os = "wasi"))] +#[allow(deprecated)] pub use traits::{FromFd, IntoFd}; #[cfg(windows)] +#[allow(deprecated)] pub use traits::{FromHandle, FromSocket, IntoHandle, IntoSocket}; #[cfg(not(io_lifetimes_use_std))] @@ -88,6 +89,7 @@ pub use std::os::windows::io::{ // `From`/`Into`, #[cfg(io_lifetimes_use_std)] #[cfg(any(unix, target_os = "wasi"))] +#[allow(deprecated)] impl> FromFd for T { #[inline] fn from_fd(owned_fd: OwnedFd) -> Self { @@ -96,6 +98,7 @@ impl> FromFd for T { } #[cfg(io_lifetimes_use_std)] #[cfg(any(unix, target_os = "wasi"))] +#[allow(deprecated)] impl IntoFd for T where OwnedFd: From, @@ -108,6 +111,7 @@ where #[cfg(io_lifetimes_use_std)] #[cfg(windows)] +#[allow(deprecated)] impl> FromHandle for T { #[inline] fn from_handle(owned_handle: OwnedHandle) -> Self { @@ -116,6 +120,7 @@ impl> FromHandle for T { } #[cfg(io_lifetimes_use_std)] #[cfg(windows)] +#[allow(deprecated)] impl IntoHandle for T where OwnedHandle: From, @@ -128,6 +133,7 @@ where #[cfg(io_lifetimes_use_std)] #[cfg(windows)] +#[allow(deprecated)] impl> FromSocket for T { #[inline] fn from_socket(owned_socket: OwnedSocket) -> Self { @@ -136,6 +142,7 @@ impl> FromSocket for T { } #[cfg(io_lifetimes_use_std)] #[cfg(windows)] +#[allow(deprecated)] impl IntoSocket for T where OwnedSocket: From, diff --git a/src/portability.rs b/src/portability.rs index ee90575..eb630ce 100644 --- a/src/portability.rs +++ b/src/portability.rs @@ -6,12 +6,9 @@ use crate::views::{FilelikeView, FilelikeViewType, SocketlikeView, SocketlikeViewType}; #[cfg(any(unix, target_os = "wasi"))] -use crate::{AsFd, BorrowedFd, FromFd, IntoFd, OwnedFd}; +use crate::{AsFd, BorrowedFd, OwnedFd}; #[cfg(windows)] -use crate::{ - AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, FromHandle, FromSocket, IntoHandle, - IntoSocket, OwnedHandle, OwnedSocket, -}; +use crate::{AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, OwnedHandle, OwnedSocket}; /// A reference to a filelike object. /// @@ -104,6 +101,8 @@ pub trait AsFilelike: AsFd { /// ``` /// /// [`File`]: std::fs::File + /// [`Read`]: std::io::Read + /// [`Write`]: std::io::Write fn as_filelike_view(&self) -> FilelikeView<'_, Target>; } @@ -155,6 +154,8 @@ pub trait AsFilelike: AsHandle { /// ``` /// /// [`File`]: std::fs::File + /// [`Read`]: std::io::Read + /// [`Write`]: std::io::Write fn as_filelike_view(&self) -> FilelikeView<'_, Target>; } @@ -195,6 +196,8 @@ pub trait AsSocketlike: AsFd { /// ``` /// /// [`TcpStream`]: std::net::TcpStream + /// [`Read`]: std::io::Read + /// [`Write`]: std::io::Write fn as_socketlike_view(&self) -> SocketlikeView<'_, Target>; } @@ -254,10 +257,10 @@ impl AsSocketlike for T { /// A portable trait to express the ability to consume an object and acquire /// ownership of its filelike object. /// -/// This is a portability abstraction over Unix-like [`IntoFd`] and Windows' -/// `IntoHandle`. +/// This is a portability abstraction over Unix-like [`Into`] and Windows' +/// `Into`. #[cfg(any(unix, target_os = "wasi"))] -pub trait IntoFilelike: IntoFd { +pub trait IntoFilelike: Into { /// Consumes this object, returning the underlying filelike object. /// /// # Example @@ -275,58 +278,58 @@ pub trait IntoFilelike: IntoFd { } #[cfg(any(unix, target_os = "wasi"))] -impl IntoFilelike for T { +impl> IntoFilelike for T { #[inline] fn into_filelike(self) -> OwnedFilelike { - self.into_fd() + self.into() } } /// A portable trait to express the ability to consume an object and acquire /// ownership of its filelike object. /// -/// This is a portability abstraction over Unix-like `IntoFd` and Windows' -/// [`IntoHandle`]. +/// This is a portability abstraction over Unix-like `Into` and Windows' +/// [`Into`]. #[cfg(windows)] -pub trait IntoFilelike: IntoHandle { +pub trait IntoFilelike: Into { /// Consumes this object, returning the underlying filelike object. fn into_filelike(self) -> OwnedFilelike; } #[cfg(windows)] -impl IntoFilelike for T { +impl> IntoFilelike for T { #[inline] fn into_filelike(self) -> OwnedFilelike { - self.into_handle() + self.into() } } /// A portable trait to express the ability to consume an object and acquire /// ownership of its socketlike object. /// -/// This is a portability abstraction over Unix-like [`IntoFd`] and Windows' -/// `IntoSocket`. +/// This is a portability abstraction over Unix-like [`Into`] and Windows' +/// `Into`. #[cfg(any(unix, target_os = "wasi"))] -pub trait IntoSocketlike: IntoFd { +pub trait IntoSocketlike: Into { /// Consumes this object, returning the underlying socketlike object. fn into_socketlike(self) -> OwnedSocketlike; } #[cfg(any(unix, target_os = "wasi"))] -impl IntoSocketlike for T { +impl> IntoSocketlike for T { #[inline] fn into_socketlike(self) -> OwnedSocketlike { - self.into_fd() + self.into() } } /// A portable trait to express the ability to consume an object and acquire /// ownership of its socketlike object. /// -/// This is a portability abstraction over Unix-like `IntoFd` and Windows' -/// [`IntoSocket`]. +/// This is a portability abstraction over Unix-like `Into` and Windows' +/// [`Into`]. #[cfg(windows)] -pub trait IntoSocketlike: IntoSocket { +pub trait IntoSocketlike: Into { /// Consumes this object, returning the underlying socketlike object. /// /// # Example @@ -344,21 +347,21 @@ pub trait IntoSocketlike: IntoSocket { } #[cfg(windows)] -impl IntoSocketlike for T { +impl> IntoSocketlike for T { #[inline] fn into_socketlike(self) -> OwnedSocketlike { - self.into_socket() + self.into() } } /// A portable trait to express the ability to construct an object from a /// filelike object. /// -/// This is a portability abstraction over Unix-like [`FromFd`] and Windows' -/// `FromHandle`. It also provides the `from_into_filelike` convenience +/// This is a portability abstraction over Unix-like [`From`] and Windows' +/// `From`. It also provides the `from_into_filelike` convenience /// function providing simplified from+into conversions. #[cfg(any(unix, target_os = "wasi"))] -pub trait FromFilelike: FromFd { +pub trait FromFilelike: From { /// Constructs a new instance of `Self` from the given filelike object. /// /// # Example @@ -393,10 +396,10 @@ pub trait FromFilelike: FromFd { } #[cfg(any(unix, target_os = "wasi"))] -impl FromFilelike for T { +impl> FromFilelike for T { #[inline] fn from_filelike(owned: OwnedFilelike) -> Self { - Self::from_fd(owned) + Self::from(owned) } #[inline] @@ -408,11 +411,11 @@ impl FromFilelike for T { /// A portable trait to express the ability to construct an object from a /// filelike object. /// -/// This is a portability abstraction over Unix-like `FromFd` and Windows' -/// [`FromHandle`]. It also provides the `from_into_filelike` convenience +/// This is a portability abstraction over Unix-like `From` and Windows' +/// [`From`]. It also provides the `from_into_filelike` convenience /// function providing simplified from+into conversions. #[cfg(windows)] -pub trait FromFilelike: FromHandle { +pub trait FromFilelike: From { /// Constructs a new instance of `Self` from the given filelike object. /// /// # Example @@ -447,10 +450,10 @@ pub trait FromFilelike: FromHandle { } #[cfg(windows)] -impl FromFilelike for T { +impl> FromFilelike for T { #[inline] fn from_filelike(owned: OwnedFilelike) -> Self { - Self::from_handle(owned) + Self::from(owned) } #[inline] @@ -462,11 +465,11 @@ impl FromFilelike for T { /// A portable trait to express the ability to construct an object from a /// socketlike object. /// -/// This is a portability abstraction over Unix-like [`FromFd`] and Windows' -/// `FromSocket`. It also provides the `from_into_socketlike` convenience +/// This is a portability abstraction over Unix-like [`From`] and Windows' +/// `From It also provides the `from_into_socketlike` convenience /// function providing simplified from+into conversions. #[cfg(any(unix, target_os = "wasi"))] -pub trait FromSocketlike: FromFd { +pub trait FromSocketlike: From { /// Constructs a new instance of `Self` from the given socketlike object. fn from_socketlike(owned: OwnedSocketlike) -> Self; @@ -476,10 +479,10 @@ pub trait FromSocketlike: FromFd { } #[cfg(any(unix, target_os = "wasi"))] -impl FromSocketlike for T { +impl> FromSocketlike for T { #[inline] fn from_socketlike(owned: OwnedSocketlike) -> Self { - Self::from_fd(owned) + Self::from(owned) } #[inline] @@ -491,11 +494,11 @@ impl FromSocketlike for T { /// A portable trait to express the ability to construct an object from a /// socketlike object. /// -/// This is a portability abstraction over Unix-like `FromFd` and Windows' -/// [`FromSocket`]. It also provides the `from_into_socketlike` convenience +/// This is a portability abstraction over Unix-like `From` and Windows' +/// [`From`]. It also provides the `from_into_socketlike` convenience /// function providing simplified from+into conversions. #[cfg(windows)] -pub trait FromSocketlike: FromSocket { +pub trait FromSocketlike: From { /// Constructs a new instance of `Self` from the given socketlike object. fn from_socketlike(owned: OwnedSocketlike) -> Self; @@ -505,10 +508,10 @@ pub trait FromSocketlike: FromSocket { } #[cfg(windows)] -impl FromSocketlike for T { +impl> FromSocketlike for T { #[inline] fn from_socketlike(owned: OwnedSocketlike) -> Self { - Self::from_socket(owned) + Self::from(owned) } #[inline] diff --git a/src/traits.rs b/src/traits.rs index 7880452..5e80b75 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -22,7 +22,6 @@ pub trait AsFd { /// # Example /// /// ```rust,no_run - /// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))] /// use std::fs::File; /// # use std::io; /// use io_lifetimes::{AsFd, BorrowedFd}; @@ -43,7 +42,6 @@ pub trait AsHandle { /// # Example /// /// ```rust,no_run - /// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))] /// use std::fs::File; /// # use std::io; /// use io_lifetimes::{AsHandle, BorrowedHandle}; @@ -66,13 +64,16 @@ pub trait AsSocket { /// A trait to express the ability to consume an object and acquire ownership /// of its file descriptor. #[cfg(any(unix, target_os = "wasi"))] +#[deprecated( + since = "1.0.0", + note = "`IntoFd` is replaced by `From<...> for OwnedFd` or `Into`" +)] pub trait IntoFd { /// Consumes this object, returning the underlying file descriptor. /// /// # Example /// /// ```rust,no_run - /// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))] /// use std::fs::File; /// # use std::io; /// use io_lifetimes::{IntoFd, OwnedFd}; @@ -87,13 +88,16 @@ pub trait IntoFd { /// A trait to express the ability to consume an object and acquire ownership /// of its handle. #[cfg(windows)] +#[deprecated( + since = "1.0.0", + note = "`IntoHandle` is replaced by `From<...> for OwnedHandle` or `Into`" +)] pub trait IntoHandle { /// Consumes this object, returning the underlying handle. /// /// # Example /// /// ```rust,no_run - /// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))] /// use std::fs::File; /// # use std::io; /// use io_lifetimes::{IntoHandle, OwnedHandle}; @@ -108,6 +112,10 @@ pub trait IntoHandle { /// A trait to express the ability to consume an object and acquire ownership /// of its socket. #[cfg(windows)] +#[deprecated( + since = "1.0.0", + note = "`IntoSocket` is replaced by `From<...> for OwnedSocket` or `Into`" +)] pub trait IntoSocket { /// Consumes this object, returning the underlying socket. fn into_socket(self) -> OwnedSocket; @@ -122,7 +130,6 @@ pub trait FromFd { /// # Example /// /// ```rust,no_run - /// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))] /// use std::fs::File; /// # use std::io; /// use io_lifetimes::{FromFd, IntoFd, OwnedFd}; @@ -132,6 +139,10 @@ pub trait FromFd { /// let f = File::from_fd(owned_fd); /// # Ok::<(), io::Error>(()) /// ``` + #[deprecated( + since = "1.0.0", + note = "`FromFd::from_fd` is replaced by `From::from`" + )] fn from_fd(owned: OwnedFd) -> Self; /// Constructs a new instance of `Self` from the given file descriptor @@ -140,7 +151,6 @@ pub trait FromFd { /// # Example /// /// ```rust,no_run - /// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))] /// use std::fs::File; /// # use std::io; /// use io_lifetimes::{FromFd, IntoFd}; @@ -150,11 +160,11 @@ pub trait FromFd { /// # Ok::<(), io::Error>(()) /// ``` #[inline] - fn from_into_fd(into_owned: Owned) -> Self + fn from_into_fd>(into_owned: Owned) -> Self where - Self: Sized, + Self: Sized + From, { - Self::from_fd(into_owned.into_fd()) + Self::from(into_owned.into()) } } @@ -166,7 +176,6 @@ pub trait FromHandle { /// # Example /// /// ```rust,no_run - /// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))] /// use std::fs::File; /// # use std::io; /// use io_lifetimes::{FromHandle, IntoHandle, OwnedHandle}; @@ -176,6 +185,10 @@ pub trait FromHandle { /// let f = File::from_handle(owned_handle); /// # Ok::<(), io::Error>(()) /// ``` + #[deprecated( + since = "1.0.0", + note = "`FromHandle::from_handle` is replaced by `From::from`" + )] fn from_handle(owned: OwnedHandle) -> Self; /// Constructs a new instance of `Self` from the given handle converted @@ -184,7 +197,6 @@ pub trait FromHandle { /// # Example /// /// ```rust,no_run - /// # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))] /// use std::fs::File; /// # use std::io; /// use io_lifetimes::{FromHandle, IntoHandle}; @@ -194,11 +206,11 @@ pub trait FromHandle { /// # Ok::<(), io::Error>(()) /// ``` #[inline] - fn from_into_handle(into_owned: Owned) -> Self + fn from_into_handle>(into_owned: Owned) -> Self where - Self: Sized, + Self: Sized + From, { - Self::from_handle(into_owned.into_handle()) + Self::from(into_owned.into()) } } @@ -206,16 +218,20 @@ pub trait FromHandle { #[cfg(windows)] pub trait FromSocket { /// Constructs a new instance of `Self` from the given socket. + #[deprecated( + since = "1.0.0", + note = "`FromSocket::from_socket` is replaced by `From::from`" + )] fn from_socket(owned: OwnedSocket) -> Self; /// Constructs a new instance of `Self` from the given socket converted /// from `into_owned`. #[inline] - fn from_into_socket(into_owned: Owned) -> Self + fn from_into_socket>(into_owned: Owned) -> Self where - Self: Sized, + Self: Sized + From, { - Self::from_socket(into_owned.into_socket()) + Self::from(into_owned.into()) } } diff --git a/tests/api.rs b/tests/api.rs index 19f65c4..8a31707 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -1,6 +1,5 @@ #![cfg_attr(target_os = "wasi", feature(wasi_ext))] #![cfg(feature = "close")] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] use io_lifetimes::raw::{AsRawFilelike, AsRawSocketlike}; use io_lifetimes::views::{FilelikeView, SocketlikeView}; diff --git a/tests/ffi.rs b/tests/ffi.rs index af03efe..2e3ce6d 100644 --- a/tests/ffi.rs +++ b/tests/ffi.rs @@ -1,6 +1,5 @@ #![cfg_attr(not(rustc_attrs), allow(unused_imports))] #![cfg(feature = "close")] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] #[cfg(any(unix, windows))] use io_lifetimes::example_ffi::*; diff --git a/tests/niche-optimizations.rs b/tests/niche-optimizations.rs index 89316d5..e234e54 100644 --- a/tests/niche-optimizations.rs +++ b/tests/niche-optimizations.rs @@ -1,6 +1,5 @@ #![cfg_attr(not(rustc_attrs), allow(unused_imports))] #![cfg_attr(target_os = "wasi", feature(wasi_ext))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] use std::mem::size_of;