Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can't use private derive macros #339

Closed
Freax13 opened this issue Apr 17, 2023 · 6 comments
Closed

can't use private derive macros #339

Freax13 opened this issue Apr 17, 2023 · 6 comments

Comments

@Freax13
Copy link

Freax13 commented Apr 17, 2023

Starting with version 2 the generated type is a thin wrapper around an internal InternalBitFlags type that contains all the actual implementations. #[derive(...)] attributes can only be attached to the external type and not the internal type. This leads to problems for most derive macros because they require the macro to be applied to the internal type as well.
One strategy to solve this is to create a cargo feature for each crate that provides such macros and then derive its derive macros on the inner type if the feature is enabled (see #311, #312, #325). Unfortunately this is inherently limited to public crates: This solution does not work for non-public crates that use their own derive macros. I'd like to be able to use my custom derive macros on the internal type without having to publish the derive macro and adding it as a dependency on bitflags.

@KodrAus
Copy link
Member

KodrAus commented Apr 17, 2023

This is a bit of an unfortunate regression. There isn't really a solution to exposing a way to derive traits and add methods on that internal type that doesn't come with the risk of breakage as features are added to bitflags. In general, I don't think we'll support exposing it.

I think your best option is to implement the trait manually. It's an ergonomic hit for those cases where you can't add derive support to bitflags, but there are other strategies available to reduce boilerplate, like regular macro_rules macros, or attributes on your custom derive traits that alter code generation.

I would be open though to exploring some way to improve this story in a way that didn't also erode our ability to safely evolve the library.

@paul-hansen
Copy link

This prevents me from upgrading a personal project to 2.0 because I want to be able to use it with bevy_reflect like so:

bitflags! {
    #[derive(Reflect, FromReflect)]
    pub struct MyEnum: u8 {

This allows being able to see the values in bevy_egui_inspector and replicating the value over the network using bevy_replicion.

My project isn't important, it's just an exercise for myself, but I thought you might want to know about this use case.

@KodrAus
Copy link
Member

KodrAus commented May 1, 2023

@paul-hansen Since bevy_reflect is public we can add support for it in bitflags. We need to do some additional work to support libraries that require custom derives, but have a policy for unstable dependencies in #329 that should cover bevy_reflect.

@KodrAus
Copy link
Member

KodrAus commented May 1, 2023

Looking at bevy_reflect specifically, I might put together an external library for a start like bitflags_bevy_reflect and see if we can take better advantage of the fact that the underlying type is a flags type than the derive will.

@KodrAus
Copy link
Member

KodrAus commented May 4, 2023

I think I've got a solution for this that lets you add custom derives without bitflags needing to be directly aware of them, and without losing all the code generation that bitflags gives you.

@KodrAus
Copy link
Member

KodrAus commented May 17, 2023

With #348 merged, the 2.3.0 release of bitflags will support using your own custom derives again. I've added an example that demonstrates how to do this.

@KodrAus KodrAus closed this as completed May 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants