Please allow to use the "internal" derives in the "custom-derive" case #395
Labels
No labels
bug
good first issue
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-bitflags/bitflags#395
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
In bitflags 1, it was possible to do something like
With bitflags 2, the equivalent is:
Unfortunately, that means
Debugis derived normally, not using the nicer implementation that bitflags provides. One can implement it manually, but that quickly becomes cumbersome. It would be more useful if bitflags allowed to use some or all of its internal derives.Hi @glandium 👋
It looks like you're using the impl-style
bitflags!because you also need support for other custom derives? It seems like there's more we can do to make that pattern nicer. Perhaps a proc-macro library that leveraged theFlagstrait to offer its own custom-derives forDebugetc:It wouldn't need to be a proc macro, it should be possible to make this work:
Both would work, although the proc-macro would feel better because it groups the derive in a single place, but I can understand that it's more stuff to compile.
My preference would be for a proc-macro, starting in an external library with the option to include in
bitflagsthrough a feature, but would never want to pull any proc-macros in tobitflagsby-default. The reason I'd like to avoidmacro_rules!for this is the macro logic inbitflags!is already quite complicated, and I'd like to avoid introducing any magic attributes wherever possible. Thebitflags! { struct Qux: u32 { .. } }case currently just uses a newtype to make plain#[derive()]s work, since many custom-derives treat newtypes differently.That's what bitflags 1 was doing. bitflags 2 is different in that matter, which is the reason for this issue in the first place. Specifically, it uses a newtype of an internal type that
#[derive()]s can't be applied to.bitflags1.xused a struct likestruct Flags { bits: u32 }, so you could#[derive]many things, but they would be based on that un-semanticu32so probably not what you actually want to implement.bitflags2.xuses a newtype likestruct Flags(FlagsInner)whereFlagsInnermanually implements traits semantically so you can add#[derive]s onFlagsand get something closer to what you want to implement, but has the (significant) drawback that only traits implemented byFlagsInnercan be#[derive]'d onFlags.In the time since this issue was opened we've changed a few things to make working with custom derives a bit nicer. You can now declare your flags type as a regular struct, and then implement flags functionality on it separately:
I've also created a proc macro library called
bitflags_derivethat is able to generate better flags-aware implementations of traits without needing direct support inbitflagsfor them:This is the place to add new flags-aware custom derive support going forwards.