rust-lang / rust-lang/rust-analyzer

Revisit how eager macros are handled

Open
#17,717 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-macro A-nameres C-enhancement E-unknown
Dominant language
Rust
Stars
16.9k
Forks
2.2k
Avg merge
1d 12h
Merged PRs (30d)
72

Description

Right now we do a weird dance:

  • We create a macro call for the argument site, immediately expand that into the argument syntax tree
  • Then we do what rustc usually does with macro expansion, we walk the tree, expand all macro calls we find and inline those expansion into the tree
  • Finally we create a new macro call with a special payload added to it which is this fully expanded tree, which we then intern. This is the actual input to eager macro, its fully expanded input.

For one interning something that changes like this means we'll re-intern on every change, leaking it, but this also feels somewhat weird. In general this is not really how the eager macros in rustc work, they expand their inputs on demand, it is by sheer luck that this tends to be always the full input (except for format_args but there we get around it by using a special custom syntax). It would be nice if we could avoid this weirdness somehow, though the one beneift of this intermediate tracked expansion is that IDE features will simply work for the expanded argument tree. So really the main thing to solve here would be the payload being interned, but salsa doesn't really give us a way to stash this away aside from interning. We could store it within the def-map that computes it, but then we would likely need to eagerly expand the actual invocation as the expand query would then need to access the def map while we are computing the def map forming a cycle

https://github.com/rust-lang/rust-analyzer/blob/9fcaab3704f813415c78eb81296dc254e2599514/crates/hir-expand/src/eager.rs#L44-L110

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with crates/hir-expand/src/eager.rs, especially lines 44-110, and trace how eager macro inputs are created, expanded, and interned. Read the surrounding expansion and def-map code to understand the possible cycle described in the issue. Done means the eager-macro handling no longer relies on the problematic changing interned payload while preserving the noted IDE behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.