-
-
Notifications
You must be signed in to change notification settings - Fork 14.9k
rustc_queries! is very complicated #153064
Copy link
Copy link
Closed
Labels
A-query-systemArea: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html)Area: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html)A-technical-debtArea: Internal cleanup workArea: Internal cleanup workC-cleanupCategory: PRs that clean code up or issues documenting cleanup.Category: PRs that clean code up or issues documenting cleanup.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Metadata
Metadata
Assignees
Labels
A-query-systemArea: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html)Area: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html)A-technical-debtArea: Internal cleanup workArea: Internal cleanup workC-cleanupCategory: PRs that clean code up or issues documenting cleanup.Category: PRs that clean code up or issues documenting cleanup.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Type
Fields
Give feedbackNo fields configured for issues without a type.
rustc_queries!is a proc macro at the heart of the compiler's query system. The call to it incompiler/rustc_middle/src/queries.rsdefines all the queries. It's also really complicated. Until very recently, it produced five different things as output.macro_rules! rustc_with_all_queries { .. }This is a higher-order macro. You can call it, passing it another macro which processes entries like this:
macro_rules! rustc_feedable_queries { .. }Another higher-order macro, very similar to
rustc_with_all_queries, but only including entries for feedable queries.This was removed in #153009, hooray.
mod _description_fnsA module containing one generated description function per query.
The body comes from the
descmodifier. E.g. this modifier:gets turned into this function:
mod _cache_on_disk_if_fnsA module containing one generated cache check function per
cache_on_disk_ifquery.The body comes from the
cache_on_disk_ifmodifier, e.g. this modifier:gets turned into this function:
mod _analyzer_hintsThis is a weird module that exists purely to help rust-analyzer users find query definitions. It contains one never-executed function per query. E.g.
The exact spans on the various identifiers are very important to get right.
Summary
This one proc macro is doing a lot. It is incredibly hard to understand. I gained my understanding by
println!ing the token stream and reading through things carefully. I don't know how else you could possibly understand it fully. It's clear that in the past people have modified it with only a partial understanding, leading to inconsistencies and weirdnesses, e.g. the inconsistenttcxbinding syntax that was fixed in #152958.The good news is that a lot of this functionality can be extracted from the proc macro and done instead in the declarative macros (e.g.
define_callbacks!). Declarative macros are also not easy to read and understand, but they are much easier than proc macros. I think it should be possible to reduce the output from 2 macros + 3 mods down to 1 macro. (Though I'm not 100% sure about removingmod _analyzer_hints.) #153009 was a good start.