Lymia / enumset

A library for compact bit sets containing enums.
Apache License 2.0
91 stars 35 forks source link

Allow deriving `EnumSetType` without `Clone + Copy + Eq + PartialEq` #31

Closed ahcodedthat closed 2 years ago

ahcodedthat commented 2 years ago

This PR adds a derive attribute #[enumset(no_super_impls)]. When this is used, deriving EnumSetType does not also implement Clone, Copy, Eq, or PartialEq. These traits must then be implemented some other way instead.

My use case is deriving EnumSetType for an enum generated by the prost crate, which allows extra derives to be added but always derives Clone, Copy, Eq, or PartialEq (among others). Without this no_super_impls option, this results in a compile error due to conflicting implementations of these traits.


I had also tried simply dropping the Copy + Eq requirement entirely, but that turned out to be impossible because:

  1. #[derive(Eq)] on EnumSet<T> sets a bound of T: Eq on the generated Eq implementation (and likewise for PartialEq). Therefore, Eq and PartialEq must be implemented manually on EnumSet. This problem probably won't be solved any time soon.
  2. EnumSet constants cannot be used in patterns if they use a non-derived Eq implementation:
error: to use a constant of type `enumset::EnumSet` in a pattern, `enumset::EnumSet` must be annotated with `#[derive(PartialEq, Eq)]`
   --> enumset/tests/ops.rs:286:17
    |
286 |                 CONST_SET => { /* ok */ }
    |                 ^^^^^^^^^

😞