|
| 1 | +- Feature Name: (libc_struct_traits) |
| 2 | +- Start Date: (2017-12-05) |
| 3 | +- RFC PR: (leave this empty) |
| 4 | +- Rust Issue: (leave this empty) |
| 5 | + |
| 6 | +# Summary |
| 7 | +[summary]: #summary |
| 8 | + |
| 9 | +Provide `Debug`, `Eq`, `Hash`, and `PartialEq` implementations for all structs within the `libc` crate. |
| 10 | + |
| 11 | +# Motivation |
| 12 | +[motivation]: #motivation |
| 13 | + |
| 14 | +This will allow downstream crates to easily support similar operations with any types they |
| 15 | +provide that contain `libc` structs. Additionally [The Rust API Guidelines](https://rust-lang-nursery.github.io/api-guidelines/checklist.html) specify that it is |
| 16 | +considered useful to expose as many traits as possible from the standard library. In order to facilitate the |
| 17 | +following of these guidelines, official Rust libraries should lead by example. |
| 18 | + |
| 19 | +For many of these traits, it is trivial for downstream crates to implement them for these types by using |
| 20 | +newtype wrappers. As a specific example, the `nix` crate offers the `TimeSpec` wrapper type around the `timespec` struct. This |
| 21 | +wrapper could easily implement `Eq` through comparing both fields in the struct. |
| 22 | + |
| 23 | +Unfortunately there are a great many structs that are large and vary widely between platforms. Some of these in use by `nix` |
| 24 | +are `dqblk`, `utsname`, and `statvfs`. These structs have fields and field types that vary across platforms. As `nix` aims to |
| 25 | +support as many platforms as `libc` does, this variation makes implementing these traits manually on wrapper types time consuming and |
| 26 | +error prone. |
| 27 | + |
| 28 | +# Guide-level explanation |
| 29 | +[guide-level-explanation]: #guide-level-explanation |
| 30 | + |
| 31 | +The `Debug`, `Eq`, `Hash`, and `PartialEq` traits will be implemented for all structs within `libc` if the user opts-in to the `all_traits` feature. |
| 32 | + |
| 33 | +# Reference-level explanation |
| 34 | +[reference-level-explanation]: #reference-level-explanation |
| 35 | + |
| 36 | +The `all_traits` feature will be added to `libc` that will enable the `Debug`, `Eq`, `Hash`, and `PartialEq` traits for all types (technically `Debug` |
| 37 | +was already allowed as part of the original `libc` RFC). Most types will use automatic derives within the `s!` macro in `src/macros.rs`, but this won't |
| 38 | +work for structs containing arrays larger than 32 elements. For these types the traits will be implemented manually. As a simple test, on |
| 39 | +`x86_64-unknown-linux-gnu`, I derived all the traits independently to show how many structs would need manual implementations: |
| 40 | + |
| 41 | + * `Debug` - 17 |
| 42 | + * `Eq` and `PartialEq` - 46 |
| 43 | + * `Hash` - 17 |
| 44 | + |
| 45 | +# Drawbacks |
| 46 | +[drawbacks]: #drawbacks |
| 47 | + |
| 48 | +For users that opt-in to the `all_traits` feature, this will impact compilation times, especially first build times. |
| 49 | + |
| 50 | +For the maintainers of `libc`, all new types added will require these implementations raising the barrier to entry for new contributors. This could be |
| 51 | +mitigated by working to improve the auto-derive situation such that it applies to more types. |
| 52 | + |
| 53 | +# Rationale and alternatives |
| 54 | +[alternatives]: #alternatives |
| 55 | + |
| 56 | +Alternatives considered were to not have a feature flag, but that raises the compilation time by 3x on the example test case I performed, which was |
| 57 | +considered to be too drastic of an increase in compilation time for a crate so low in the crate hierarchy for projects. |
| 58 | + |
| 59 | +There was consideration between opt-in or an opt-out flag. The opt-in flag is more conservative: it won't bring these new traits to users without their |
| 60 | +explicit permission, but it won't increase their compilation time either. Additionally, this can be later changed to opt-out or removed entirely as |
| 61 | +compilation times improve. |
| 62 | + |
| 63 | +The maintenance burden and barrier to entry increases for `libc` with manual implementations of these traits for the types that require it. Instead these |
| 64 | +traits could only be added for types that can auto-derive them. This was rejected as being too confusing for the users of `libc`. |
| 65 | + |
| 66 | +# Unresolved questions |
| 67 | +[unresolved]: #unresolved-questions |
0 commit comments