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

Expand derive invocations in left-to-right order #84023

Merged
merged 1 commit into from
Apr 11, 2021

Conversation

Aaron1011
Copy link
Member

While derives were being collected in left-to-order order, the
corresponding Invocations were being pushed in the wrong order.

@rust-highfive
Copy link
Collaborator

r? @lcnr

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 9, 2021
@petrochenkov
Copy link
Contributor

r? @petrochenkov

let (fragment, collected_invocations) =
self.collect_invocations(fragment, &derive_placeholders);
// Any derive invocations associated with this macro invocation should be
// expanded *before* any macro invocations collected from the output fragment
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand this.

The order of entries in the top level invocations vector is non-significant, it's a job queue - entries can return to it if they are not ready to be resolved or expanded so the exact expansion order is unspecified in general.
So this PR changes one unpredictable order to another?

Once #[derive(Trait1, Trait2)] ITEM produced ITEM, placeholder(Trait1) and placeholder(Trait2) these three items part their ways from each other and can be expanded independently in any order (you don't need any specific order to expand them correctly).
The existing code chooses the tentative order ITEM -> placeholder(Trait2) -> placeholder(Trait1), but it may change later if invocations in ITEM are not yet ready.
The new code chooses the tentative order placeholder(Trait1) -> placeholder(Trait2) -> ITEM (which may also change, but only inside ITEM because the two placeholders here are always ready by construction).

Am I missing anything?

Copy link
Member Author

Choose a reason for hiding this comment

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

My reasoning was that we should be treating #[derive] like a normal macro as much as possible. While the special delayed-resolution behavior of multiple #[derive] attributes (compared to normal attributes) means that we can't guarantee this, I think it makes sense to expand derives left-to-right when possible.

By doing so, we'll make the order of messages printed by derive macros more comprehensible in some cases. Even though the order is unspecified, I don't think we should intentionally pick an order (when everything can be resolved immediately) that's inconsistent with how users normally expect attribute macros to work.

Copy link
Contributor

Choose a reason for hiding this comment

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

You can see the "FIXME: Consider using the derive resolutions ..." near the changed code.
I've just realized that if it's fully implemented, then we'll stop enqueuing derives entirely, just expand them immediately in place (we have all the data necessary to do that).
In that case it'll indeed match the new order implemented in this PR.

I also agree the new order is more intuitive even if it's not specified, so it seems fine to change it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you change the "should be expanded before" comment to something less prescriptive? (The new order is a choice, not necessity.)

Copy link
Contributor

Choose a reason for hiding this comment

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

#82907 was merged so addressing the FIXME is actually pretty close to the top of my work queue.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 10, 2021
@petrochenkov
Copy link
Contributor

r=me with the comment tweaked (#84023 (comment)).

While derives were being collected in left-to-order order, the
corresponding `Invocation`s were being pushed in the wrong order.
@Aaron1011
Copy link
Member Author

@bors r=petrochenkov

@bors
Copy link
Contributor

bors commented Apr 10, 2021

📌 Commit 21e6cc1 has been approved by petrochenkov

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 10, 2021
@bors
Copy link
Contributor

bors commented Apr 10, 2021

⌛ Testing commit 21e6cc1 with merge 25ea6be...

@bors
Copy link
Contributor

bors commented Apr 11, 2021

☀️ Test successful - checks-actions
Approved by: petrochenkov
Pushing 25ea6be to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Apr 11, 2021
@bors bors merged commit 25ea6be into rust-lang:master Apr 11, 2021
@rustbot rustbot added this to the 1.53.0 milestone Apr 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants