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

Attribute Macros on Items #528

Merged
merged 10 commits into from
Jun 4, 2023
Merged

Attribute Macros on Items #528

merged 10 commits into from
Jun 4, 2023

Conversation

ModProg
Copy link
Contributor

@ModProg ModProg commented May 26, 2023

  • tests
  • rune::attribute_macro

@ModProg ModProg force-pushed the attribute-macros branch from 768779f to 3b336d6 Compare May 26, 2023 12:03
@udoprog
Copy link
Collaborator

udoprog commented May 27, 2023

It looks good to me, I've merged your changes onto main after merging #526 since they both touch on the same stuff.

In the end I'll squash everything as it's merged anyways, so history doesn't matter. I'm just keeping it so we can reference it.

@udoprog udoprog added the enhancement New feature or request label May 27, 2023
Copy link
Collaborator

@udoprog udoprog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Some missing pieces and possible meta conflict, but all the infrastructure to run the macros seem to be there. Good job!

@ModProg ModProg changed the title Implement attribute macros Attribute Macros on Items May 29, 2023
@ModProg ModProg marked this pull request as ready for review May 29, 2023 11:40
@ModProg
Copy link
Contributor Author

ModProg commented May 29, 2023

well this broke builtin attributes such as #[test].

Would it be possible to actually impllement them as attribute macros? Or should we somehow skip them and keep them arround though I'm not sure how that would work best.

@udoprog
Copy link
Collaborator

udoprog commented May 29, 2023

Skip over attributes you can't process until the end, then error if any unprocessed attributes remain?

@ModProg
Copy link
Contributor Author

ModProg commented May 29, 2023

Skip over attributes you can't process until the end, then error if any unprocessed attributes remain?

So I don't error on unknown attributes, but just ignore them so that the item handler would error later.

@udoprog
Copy link
Collaborator

udoprog commented May 29, 2023

Hm, I'm not entirely following. What is the problem right now? I'll also look over the PR later, so maybe I'll better understand what's going on then 😅

@ModProg
Copy link
Contributor Author

ModProg commented May 29, 2023

So I'm really not sure how to best implement this, e.g. in this:

#[some_macro]
#[test]
#[another_macro]
fn foobar() {}

This should expand some_macro and another_macro and remove both, but keep test so this function is a test.

Currently I use remove_first_attribute which will pop the first attribute (some_macro) and resolve + expand it, afterwards it would pop test, but cannot resolve it and needs to somehow preserve it in a way where the next call to remove_first_attribute would remove another_macro.

In my current setup this is actually reasonably possible, that is, because I haven't implemented lenient import resolution i.e.:

#[attribute] fn smth() {}
use ::module::attribute;

is currently an error.

To support the order agnostic usage, I would need to:

  1. expand macros until one is unknown
  2. enqueue annotated item and continue expanding other items
  3. when there are no expandable macros and no imports left, skip the first macro and try to expand again, repeating until all items with unresolved attributes are finished.

It is not possible to skip the top attribute if unknown and expand the ones below, because an unknown attribute might remove said attributes which would have been erroneously expanded.

From that, I think it would be best to filter built-in attributes directly, (maybe directly in remove_first_attribute) or if possible implement them as actual macros.

I can as an MVP support attributes that are resolved in order, i.e., only if the import was before the attribute, and just skip unknown attributes and leave dealing with them to item_fn.

@udoprog
Copy link
Collaborator

udoprog commented May 29, 2023

Currently I use remove_first_attribute which will pop the first attribute (some_macro) and resolve + expand it, afterwards it would pop test, but cannot resolve it and needs to somehow preserve it in a way where the next call to remove_first_attribute would remove another_macro.

This shouldn't be an issue if you keep any attributes which you can't expand and hand it to downstream steps, which will then either process them or error. But due note that #[some_macro] would be fed #[test] #[another_macro] fn foobar() {} as input, so it's up to that macro handler what exactly to produce. But whatever it produces would be recursively expanded - if more attributes are found.

Let's say #[test] #[another_macro] fn foobar() {} is produced next, then #[test] is ignored (no macro handlers found), and simply prepended as attributes to whatever #[another_macro] fn foobar() {} produces.

Does this make sense?

lenient import resolution

The type of import resolution currently implemented simply means that macros are "evaluated last". So what you need to do is look over available items once - and if they contain attributes that could be expanded by a macro put them in the queue to be expanded after all other items. That way uses (which are not production of macros) are always expanded first. And the rest of evaluation is order-dependent from top-to bottom as they are added to the queue.

So to determine whether something should be deferred or not, I think some kind of first pass needs to be performed to test if there are attributes that need to be expanded.

@ModProg
Copy link
Contributor Author

ModProg commented May 29, 2023

that does make it more easily achievable. I'll look into it!

@ModProg ModProg requested a review from udoprog May 30, 2023 22:47
@udoprog
Copy link
Collaborator

udoprog commented May 31, 2023

I'm nursing a cold right now, will get into it when I'm 100% again!

Copy link
Collaborator

@udoprog udoprog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, this is a great start. Only the Name issue (I think).

@udoprog udoprog merged commit feeb29d into rune-rs:main Jun 4, 2023
@udoprog
Copy link
Collaborator

udoprog commented Jun 4, 2023

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants