-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Move def id collection and extern crate handling to before AST->HIR lowering #33089
Conversation
So, uhm, what about the elephant in the room? The AST changes during expansion, do you still plan on using IDs even with resolve-while-expanding? |
@eddyb - this stuff happens after expansion, but before lowering, not before expansion. This would allow us to use def ids in the HIR and name resolution as part of lowering. It isn't intended to directly allow def ids for use in name resolution in expansion. If we do want to use def ids for that, then I imagine we continue to collect def ids during expansion, in the same way that we do for lowering here. I think that works because def ids are monotonic - once we are able to assign a def id to a node, it will never change due to further expansion. |
@nrc I think this is relying way too much on there being IDs embedded in nodes to begin with. However, using name resolution during lowering (or rather, turning resolve into the lowering pass) is great, so I'm happy in that regard, just worried about tight coupling between One step at a time, I guess. |
What is the motivation for removing the IDs in AST nodes? We will need to compute scopes and resolve import and macro paths on the AST during expansion. Without embedded IDs, I believe we would have to come up with a node identification system that would not be invalidated by expansion. This is certainly doable, but it would add considerable complexity. |
@jseyfried The only reason the whole "assign IDs and build a map" thing works is because the AST (now HIR) is frozen at that point. |
☔ The latest upstream changes (presumably #33002) made this pull request unmergeable. Please resolve the merge conflicts. |
By relying on @nrc's monotonicity property. Since macro definitions and invocations are not monotonic, I plan on using a separate "id namespace" for them or assigning them normally and then reassigning ids after expansion to avoid unused ids (this would still be simpler than a custom identification system, imo). More specifically, I plan on keeping track of the next normal id and the next macro invocation id during expansion. After each expansion, we would assign all unassigned nodes appropriately and collect new def ids. |
@jseyfried So the "catch" is that you can waste IDs. What do you think about storing the entire AST in monotonic vectors instead of using pointers? An alternative which still allows random access would be a flattened stream of "commands" which form the AST, with positions in that stream as the pre-HIR/Ty identification. |
I don't think we would waste any ids if we use a separate "id namespace" for macro invocations and if we always remove unconfigured items before assigning new ids. |
I definitely like this idea, although it would be a massive plugin-[breaking-change], of course.
I think this would be possible, but I'm not sure it would be worth the complexity. Specifically, I think it would be a challenge to remain backwards compatible with the current macro system, in which the expansion order is significant. |
@jseyfried I thought the plan was to ditch expansion order? But I agree, none of what I said is trivial. The changes in this PR LGTM, although I can't wait to get rid of the AST/HIR embedded in crate metadata. |
…es for the HIR map.
And move extern crate reading earlier in the driver
So that we can work with inlined HIR from metadata.
It is, but we still need to support, for example: macro_rules! foo { () => {} }
foo! {} // resolves to ::foo
#[macro_use] mod bar {
macro_rules! foo { () => {} }
}
foo! {} // resolves to ::bar::foo Thinking about this some more, I don't think it would be too hard to support this with a "stream of commands" based AST since we should be able to perform all "old-style" resolutions during the first round of expansion if we expand "depth first" as we currently do (i.e. immediately re-expand macro-generated AST instead of waiting for the next expansion round). |
@jseyfried you kind of lost me a bit -- why do we need to have two namespaces to cope with macro expansion? |
@nikomatsakis Immediately after expanding a macro, I'm planning to remove unconfigured items and assign node ids. With the exception of macro invocations, all the assigned nodes will eventually become part of the HIR, so their ids won't be wasted. If we assigned ids for macro invocations independently of other nodes (i.e. we use a separate enum AstNodeId {
MacroInvocation(NodeId),
OtherNode(NodeId),
} We could also start the macro invocation id assigner at |
false, | ||
result_ident, | ||
match_expr, | ||
None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this doesn't need to be changed (unless you prefer the new formatting -- I usually prefer to save vertical space)
Reviewed, LGTM modulo optional comments. I wasn't very familiar with of def id collection before reviewing this, so I might not be the best qualified to approve -- r? @eddyb |
@bors r+ |
📌 Commit 0be3c8c has been approved by |
⌛ Testing commit 0be3c8c with merge 34886d6... |
💔 Test failed - auto-win-msvc-64-opt-mir |
@bors: retry On Thu, Apr 21, 2016 at 10:52 AM, bors notifications@github.com wrote:
|
Move def id collection and extern crate handling to before AST->HIR lowering r? @jseyfried, @eddyb, or @nikomatsakis
r? @jseyfried, @eddyb, or @nikomatsakis