Skip to content

Commit

Permalink
Rollup merge of rust-lang#97437 - jyn514:impl-asrawfd-arc, r=dtolnay
Browse files Browse the repository at this point in the history
`impl<T: AsRawFd> AsRawFd for {Arc,Box}<T>`

This allows implementing traits that require a raw FD on Arc and Box.

Previously, you'd have to add the function to the trait itself:

```rust
trait MyTrait {
    fn as_raw_fd(&self) -> RawFd;
}

impl<T: MyTrait> MyTrait for Arc<T> {
    fn as_raw_fd(&self) -> RawFd {
        (**self).as_raw_fd()
    }
}
```

In particular, this leads to lots of "multiple applicable items in scope" errors because you have to disambiguate `MyTrait::as_raw_fd` from `AsRawFd::as_raw_fd` at each call site. In generic contexts, when passing the type to a function that takes `impl AsRawFd` it's also sometimes required to use `T: MyTrait + AsRawFd`, which wouldn't be necessary if I could write `MyTrait: AsRawFd`.

After this PR, the code can be simpler:
```rust
trait MyTrait: AsRawFd {}

impl<T: MyTrait> MyTrait for Arc<T> {}
```
  • Loading branch information
matthiaskrgr authored Jun 18, 2022
2 parents 2cec687 + 86f979b commit 15faca8
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
31 changes: 31 additions & 0 deletions library/std/src/os/fd/owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,3 +355,34 @@ impl From<OwnedFd> for crate::net::UdpSocket {
))))
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
/// This impl allows implementing traits that require `AsFd` on Arc.
/// ```
/// # #[cfg(any(unix, target_os = "wasi"))] mod group_cfg {
/// # #[cfg(target_os = "wasi")]
/// # use std::os::wasi::io::AsFd;
/// # #[cfg(unix)]
/// # use std::os::unix::io::AsFd;
/// use std::net::UdpSocket;
/// use std::sync::Arc;
///
/// trait MyTrait: AsFd {}
/// impl MyTrait for Arc<UdpSocket> {}
/// impl MyTrait for Box<UdpSocket> {}
/// # }
/// ```
impl<T: AsFd> AsFd for crate::sync::Arc<T> {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
(**self).as_fd()
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl<T: AsFd> AsFd for Box<T> {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
(**self).as_fd()
}
}
26 changes: 26 additions & 0 deletions library/std/src/os/fd/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,29 @@ impl<'a> AsRawFd for io::StderrLock<'a> {
libc::STDERR_FILENO
}
}

#[stable(feature = "asrawfd_ptrs", since = "1.63.0")]
/// This impl allows implementing traits that require `AsRawFd` on Arc.
/// ```
/// use std::net::UdpSocket;
/// use std::sync::Arc;
/// use std::os::unix::prelude::AsRawFd;
/// trait MyTrait: AsRawFd {
/// }
/// impl MyTrait for Arc<UdpSocket> {}
/// impl MyTrait for Box<UdpSocket> {}
/// ```
impl<T: AsRawFd> AsRawFd for crate::sync::Arc<T> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
(**self).as_raw_fd()
}
}

#[stable(feature = "asrawfd_ptrs", since = "1.63.0")]
impl<T: AsRawFd> AsRawFd for Box<T> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
(**self).as_raw_fd()
}
}

0 comments on commit 15faca8

Please sign in to comment.