Skip to content

Commit c99f6fb

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

File tree

1 file changed

+46
-39
lines changed

1 file changed

+46
-39
lines changed

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy