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

Use derive macro instead of attribute macro #37

Closed
hellow554 opened this issue Sep 24, 2021 · 8 comments
Closed

Use derive macro instead of attribute macro #37

hellow554 opened this issue Sep 24, 2021 · 8 comments

Comments

@hellow554
Copy link

Using a Derive Macro has the "advantage" that it plays nicely with the #[derive] attribute, whereas in the current form if you use #[bitflags] in the wrong order you get the following error message:

error[E0658]: macro attributes in `#[derive]` output are unstable
 --> src/game_types.rs:7:3
  |
7 | #[bitflags]
  |   ^^^^^^^^
  |
  = note: see issue #81119 <https://github.com/rust-lang/rust/issues/81119> for more information
  = help: add `#![feature(macro_attributes_in_derive_output)]` to the crate attributes to enable

For more information about this error, try `rustc --explain E0658`.

You can still can have an attribute #[bitflags(default = B | C)] with the help of the attributes argument inside of the proc_macro_derive macro (https://doc.rust-lang.org/reference/procedural-macros.html#derive-macro-helper-attributes)


Was there a specific reason for not using #[derive(Bitflags)] in the first place?

Would you concider upgrading to the derive attribute? Would you accept a PR that does that?

@meithecatte
Copy link
Owner

meithecatte commented Sep 24, 2021

Earlier versions did use a derive macro. The advantage of the attribute macro is that it can automatically assign subsequent powers of two to the variants if the user so desires - before I switched to an attribute macro, you had to manually specify 1 << 0, 1 << 1, and so on. Granted, you have to do that anyway in some usecases (e.g. when you're using bitflags as part of an externally specified protocol).

How about I detect this situation in the macro and emit a friendlier error telling you to put the derives above the bitflags attribute?

@hellow554
Copy link
Author

hellow554 commented Sep 24, 2021

before I switched to an attribute macro, you had to manually specify 1 << 0, 1 << 1

If I read you post correctly you always have to specify a value to each enum variant? That would be a pita and I would see why you switched to the attribute macro.


How about I detect this situation in the macro and emit a friendlier error telling you to put the derives above the bitflags attribute?

Is that possible? If so, I really would like to see it, yes. I mean, at some time in the future the feature may become stable. I don't know if the meaning of

#[bitflags]
#[derive(Debug)]

differs to

#[derive(Debug)]
#[bitflags]

Do you know that?

@meithecatte
Copy link
Owner

The difference is that, if an attribute macro comes first, the tokens of the derive attribute are passed through the macro together with the definition of the enum itself, and the attribute macro is free to do whatever it wants with them before sending off its output through the rest of the compiler. The error you getting is saying that, even if the derive attribute passed through #[bitflags] unchanged, rustc doesn't want to process it.

@hellow554
Copy link
Author

I see. Thanks for the explanation!

What about this statement?

before I switched to an attribute macro, you had to manually specify 1 << 0, 1 << 1

If I read you post correctly you always have to specify a value to each enum variant? That would be a pita and I would see why you switched to the attribute macro.

@meithecatte
Copy link
Owner

meithecatte commented Sep 24, 2021 via email

@hellow554
Copy link
Author

Alright, I played with it and I see, that you can't replace or extend the variants of an enum with the derive.
Ok, then all it's left is the order of the attribute macro.

Thank you for your patience and I'm looking forward for a better error message :)

@meithecatte
Copy link
Owner

Ah. Now that I've looked into it more, I realize I've misunderstood the problem. It's not that attributes cannot output a #[derive] line. The part about the ordering of the attributes determining the order they get processed in is right, though. What's happening is, if #[derive] goes first, it's passed unexpanded input that contains the #[bitflags] attribute and it's not clear what should happen. Earlier rustc versions actually emitted a much better error for this.

The bottom line is, I can't control this error — I'll file an issue with rustc itself.

@meithecatte
Copy link
Owner

This now works on stable, so I'm closing the issue.

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

2 participants