Skip to content

Commit d1390f9

Browse files
committed
Adjust some doc for Query System
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
1 parent a7220f3 commit d1390f9

File tree

1 file changed

+46
-39
lines changed

1 file changed

+46
-39
lines changed

src/doc/rustc-dev-guide/src/query.md

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,15 @@ are cheaply cloneable; insert an `Rc` if necessary).
6767
### Providers
6868

6969
If, however, the query is *not* in the cache, then the compiler will
70-
try to find a suitable **provider**. A provider is a function that has
71-
been defined and linked into the compiler somewhere that contains the
72-
code to compute the result of the query.
70+
call the corresponding **provider** function. A provider is a function
71+
implemented in a specific module and **manually registered** into the
72+
[`Providers`][providers_struct] struct during compiler initialization.
73+
The macro system generates the [`Providers`][providers_struct] struct,
74+
which acts as a function table for all query implementations, where each
75+
field is a function pointer to the actual provider.
76+
77+
**Note:** The `Providers` struct is generated by macros and acts as a function table for all query implementations.
78+
It is **not** a Rust trait, but a plain struct with function pointer fields.
7379

7480
**Providers are defined per-crate.** The compiler maintains,
7581
internally, a table of providers for every crate, at least
@@ -97,7 +103,18 @@ fn provider<'tcx>(
97103
Providers take two arguments: the `tcx` and the query key.
98104
They return the result of the query.
99105

100-
### How providers are setup
106+
N.B. Most of the `rustc_*` crates only provide **local
107+
providers**. Almost all **extern providers** wind up going through the
108+
[`rustc_metadata` crate][rustc_metadata], which loads the information
109+
from the crate metadata. But in some cases there are crates that
110+
provide queries for *both* local and external crates, in which case
111+
they define both a `provide` and a `provide_extern` function, through
112+
[`wasm_import_module_map`][wasm_import_module_map], that `rustc_driver` can invoke.
113+
114+
[rustc_metadata]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/index.html
115+
[wasm_import_module_map]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/back/symbol_export/fn.wasm_import_module_map.html
116+
117+
### How providers are set up
101118

102119
When the tcx is created, it is given the providers by its creator using
103120
the [`Providers`][providers_struct] struct. This struct is generated by
@@ -108,61 +125,51 @@ the macros here, but it is basically a big list of function pointers:
108125
```rust,ignore
109126
struct Providers {
110127
type_of: for<'tcx> fn(TyCtxt<'tcx>, DefId) -> Ty<'tcx>,
111-
...
128+
// ... one field for each query
112129
}
113130
```
114131

115-
At present, we have one copy of the struct for local crates, and one
116-
for external crates, though the plan is that we may eventually have
117-
one per crate.
132+
#### How are providers registered?
133+
134+
The `Providers` struct is filled in during compiler initialization, mainly by the `rustc_driver` crate.
135+
But the actual provider functions are implemented in various `rustc_*` crates (like `rustc_middle`, `rustc_hir_analysis`, etc).
118136

119-
These `Providers` structs are ultimately created and populated by
120-
`rustc_driver`, but it does this by distributing the work
121-
throughout the other `rustc_*` crates. This is done by invoking
122-
various [`provide`][provide_fn] functions. These functions tend to look
123-
something like this:
137+
To register providers, each crate exposes a [`provide`][provide_fn] function that looks like this:
124138

125139
[provide_fn]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/fn.provide.html
126140

127141
```rust,ignore
128142
pub fn provide(providers: &mut Providers) {
129143
*providers = Providers {
130144
type_of,
145+
// ... add more providers here
131146
..*providers
132147
};
133148
}
134149
```
135150

136-
That is, they take an `&mut Providers` and mutate it in place. Usually
137-
we use the formulation above just because it looks nice, but you could
138-
as well do `providers.type_of = type_of`, which would be equivalent.
139-
(Here, `type_of` would be a top-level function, defined as we saw
140-
before.) So, if we want to add a provider for some other query,
141-
let's call it `fubar`, into the crate above, we might modify the `provide()`
142-
function like so:
151+
- This function takes a mutable reference to the `Providers` struct and sets the fields to point to the correct provider functions.
152+
- You can also assign fields individually, e.g. `providers.type_of = type_of;`.
143153

144-
```rust,ignore
145-
pub fn provide(providers: &mut Providers) {
146-
*providers = Providers {
147-
type_of,
148-
fubar,
149-
..*providers
150-
};
151-
}
154+
#### Adding a new provider
152155

153-
fn fubar<'tcx>(tcx: TyCtxt<'tcx>, key: DefId) -> Fubar<'tcx> { ... }
154-
```
156+
Suppose you want to add a new query called `fubar`. You would:
155157

156-
N.B. Most of the `rustc_*` crates only provide **local
157-
providers**. Almost all **extern providers** wind up going through the
158-
[`rustc_metadata` crate][rustc_metadata], which loads the information
159-
from the crate metadata. But in some cases there are crates that
160-
provide queries for *both* local and external crates, in which case
161-
they define both a `provide` and a `provide_extern` function, through
162-
[`wasm_import_module_map`][wasm_import_module_map], that `rustc_driver` can invoke.
158+
1. Implement the provider function:
159+
```rust,ignore
160+
fn fubar<'tcx>(tcx: TyCtxt<'tcx>, key: DefId) -> Fubar<'tcx> { ... }
161+
```
162+
2. Register it in the `provide` function:
163+
```rust,ignore
164+
pub fn provide(providers: &mut Providers) {
165+
*providers = Providers {
166+
fubar,
167+
..*providers
168+
};
169+
}
170+
```
163171
164-
[rustc_metadata]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/index.html
165-
[wasm_import_module_map]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/back/symbol_export/fn.wasm_import_module_map.html
172+
---
166173
167174
## Adding a new query
168175

0 commit comments

Comments
 (0)