Why? What are the benefits of that approach?
Is this state of affairs by design? Or am I waving my arms around over a bug? If it is by design then how do we ensure a reasonable set of derives will behave together?
It is by design, although it is a part of the design that is controversial and I’m not 100% is the right approach. I think that any responsible set of derives should behave - as far as I can see, the only way derives don’t combine well is if one of the derives either assumes too much about its input or does something unexpected to its output.
A key point is that you cannot assume the input to your derive will be as written in the source code - it is always possible for it to be transformed by some other macro before you get it. From your point of view, it doesn’t matter whether it was affected by another macro, another custom derive, or the user wrote ‘weird’ (possibly non-compiling) code - your derive ought to handle this gracefully.
The motivation for letting custom derives modify their input is:
- simplicity - all macros are basically the same whether they are custom derive or not. This makes it easy to change a macro to be custom derive or not, to share code between custom derives and regular macros, makes them easier to learn, and simplifies the implementation.
- it is actually desirable - removing attributes is the common case, adding attributes also seems reasonable. It also seems possible that a derive that adds doc comments or other decoration are legitimate use cases.
On the other add, allowing custom derive to only add code fits better with user expectations. So, I think the trade-off is between that expectation and the above. In particular, we must (I believe) at least allow a way for derive to remove attributes. My feeling has been that it is better to allow general purpose modification, rather than provide a special case mechanism for removing attributes. In particular, it is not at all clear what a special case mechanism for removing attributes should look like.