Skip to content

StaticIndex: process tokens from include! expansions - #22902

Draft
nicolas-guichard wants to merge 8 commits into
rust-lang:masterfrom
nicolas-guichard:push-mklnyxyzttuq
Draft

StaticIndex: process tokens from include! expansions#22902
nicolas-guichard wants to merge 8 commits into
rust-lang:masterfrom
nicolas-guichard:push-mklnyxyzttuq

Conversation

@nicolas-guichard

@nicolas-guichard nicolas-guichard commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

This updates the static index indexer to traverse macro expansions, but only actually records tokens from include! expansions.

The reason for not recording tokens from all expansions is twofold:

  • I didn't find a way to reliably get the tokens' spelling location, original_node_file_range_rooted returns the macro call location.
  • That would register a huge amount of tokens at macro call sites.

Marking as draft because it depends on #22530 (not functionally, but it would conflict otherwise).

For context this was motivated by https://bugzilla.mozilla.org/show_bug.cgi?id=2053847.

@ChayimFriedman2

Copy link
Copy Markdown
Contributor

I didn't find a way to reliably get the tokens' spelling location, original_node_file_range_rooted returns the macro call location.

Only if it does not have a better span.

Generally macros are already descended, which means that tokens that have a direct mapping into tokens in the call will be included (with the semantics of the expansion). Tokens that are not we generally don't want to include (though I'm not an expert in SCIP and it might have different requirements). include!() might be special though because it doesn't have direct mapping but we might still want to include it, not sure. I also didn't look at the code yet.

@nicolas-guichard

Copy link
Copy Markdown
Contributor Author

My test was a simple:

macro_rules! define_struct {
  () => {
    struct Struct;
  };
}

define_struct!();

In that case calling original_node_file_range on the Struct token from the macro expansion returns the define_struct call.

@ChayimFriedman2

Copy link
Copy Markdown
Contributor

Indeed, because the span is associated with the macro definition and not anything inside the call. Such tokens we usually don't include in things, as I said.

When multi-threading StaticIndex::compute, each thread will get its own
Analysis clone.
When multi-threading StaticIndex::compute, we want the list of files to
be computed only once and the files to index to be split between
threads.
The analysis, db and def_map members of StaticIndex were only used for
building the index and are of no use once the index is built.

Instead of have an &mut self method which mutates those fields, we can
extract the FileId→StaticIndexedFile indexing into a free function and
keep the token_store and def_map as locals in StaticIndex::compute.

This will make multi-threading StaticIndex::compute easier.
Thanks to the previous commits, everything is in place to start
multiple threads in StaticIndex::compute.

Each thread takes care of the files whose index in the precomputed list
is congruent to the thread index modulo the thread count and generates
its StaticIndexedFile.

The Definition→TokenId and TokenId→TokenStaticData maps are shared
across all threads and are now DashMaps.

TokenStore now uses an AtomicUsize to generate new TokenIds.
These fields are only used by the LSIF indexer, and are quite costly to
compute when SCIP just throws them away.
In the next commit, we add support for include! macros, which can lead
to multiple symbols being defined or used at the same position.
This updates index_file to traverse macro expansions, but only actually
records tokens from include! expansions.

The reason for not recording tokens from all expansions is twofold:
- I didn't find a way to reliably get the tokens' spelling location,
  original_node_file_range_rooted returns the macro call location.
- That would register a huge amount of tokens at macro call sites.
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

Successfully merging this pull request may close these issues.

2 participants