Implement AsFd for &T and &mut T.

Add implementations of `AsFd` for `&T` and `&mut T`, so that users can
write code like this:

```rust
pub fn fchown<F: AsFd>(fd: F, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
```

with `fd: F` rather than `fd: &F`.

And similar for `AsHandle` and `AsSocket` on Windows.

Also, adjust the `fchown` example to pass the file by reference. The
code can work either way now, but passing by reference is more likely
to be what users will want to do.

This is an alternative to #93869, and is a simpler way to achieve the
same goals: users don't need to pass borrowed-`BorrowedFd` arguments,
and it prevents a pitfall in the case where users write `fd: F` instead
of `fd: &F`.
This commit is contained in:
Dan Gohman 2022-02-10 18:26:12 -08:00
parent 502d6aa47b
commit 1f98ef7793
4 changed files with 49 additions and 1 deletions

View File

@ -200,6 +200,22 @@ pub trait AsFd {
fn as_fd(&self) -> BorrowedFd<'_>; fn as_fd(&self) -> BorrowedFd<'_>;
} }
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsFd> AsFd for &T {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
T::as_fd(self)
}
}
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsFd> AsFd for &mut T {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
T::as_fd(self)
}
}
#[unstable(feature = "io_safety", issue = "87074")] #[unstable(feature = "io_safety", issue = "87074")]
impl AsFd for BorrowedFd<'_> { impl AsFd for BorrowedFd<'_> {
#[inline] #[inline]

View File

@ -966,7 +966,7 @@ pub fn chown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::
/// ///
/// fn main() -> std::io::Result<()> { /// fn main() -> std::io::Result<()> {
/// let f = std::fs::File::open("/file")?; /// let f = std::fs::File::open("/file")?;
/// fs::fchown(f, Some(0), Some(0))?; /// fs::fchown(&f, Some(0), Some(0))?;
/// Ok(()) /// Ok(())
/// } /// }
/// ``` /// ```

View File

@ -316,6 +316,22 @@ pub trait AsHandle {
fn as_handle(&self) -> BorrowedHandle<'_>; fn as_handle(&self) -> BorrowedHandle<'_>;
} }
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsHandle> AsHandle for &T {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
T::as_handle(self)
}
}
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsHandle> AsHandle for &mut T {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
T::as_handle(self)
}
}
impl AsHandle for BorrowedHandle<'_> { impl AsHandle for BorrowedHandle<'_> {
#[inline] #[inline]
fn as_handle(&self) -> BorrowedHandle<'_> { fn as_handle(&self) -> BorrowedHandle<'_> {

View File

@ -210,6 +210,22 @@ pub trait AsSocket {
fn as_socket(&self) -> BorrowedSocket<'_>; fn as_socket(&self) -> BorrowedSocket<'_>;
} }
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsSocket> AsSocket for &T {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
T::as_socket(self)
}
}
#[unstable(feature = "io_safety", issue = "87074")]
impl<T: AsSocket> AsSocket for &mut T {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
T::as_socket(self)
}
}
impl AsSocket for BorrowedSocket<'_> { impl AsSocket for BorrowedSocket<'_> {
#[inline] #[inline]
fn as_socket(&self) -> BorrowedSocket<'_> { fn as_socket(&self) -> BorrowedSocket<'_> {