Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 110076d

Browse files
committed
Refinement of Providers into Providers and ExternProviders
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
1 parent 5975693 commit 110076d

File tree

1 file changed

+37
-34
lines changed

1 file changed

+37
-34
lines changed

‎src/query.md‎

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,24 @@ are cheaply cloneable; insert an `Rc` if necessary).
7171

7272
If, however, the query is *not* in the cache, then the compiler will
7373
call the corresponding **provider** function. A provider is a function
74-
implemented in a specific module and **manually registered** into the
75-
[`Providers`][providers_struct] struct during compiler initialization.
76-
The macro system generates the [`Providers`][providers_struct] struct,
77-
which acts as a function table for all query implementations, where each
74+
implemented in a specific module and **manually registered** into either
75+
the [`Providers`][providers_struct] struct (for local crate queries) or
76+
the [`ExternProviders`][extern_providers_struct] struct (for external crate queries)
77+
during compiler initialization. The macro system generates both structs,
78+
which act as function tables for all query implementations, where each
7879
field is a function pointer to the actual provider.
7980

80-
**Note:** The `Providers` struct is generated by macros and acts as a function table for all query implementations.
81-
It is **not** a Rust trait, but a plain struct with function pointer fields.
81+
**Note:** Both the `Providers` and `ExternProviders` structs are generated by macros and act as function tables for all query implementations.
82+
They are **not** Rust traits, but plain structs with function pointer fields.
8283

8384
**Providers are defined per-crate.** The compiler maintains,
8485
internally, a table of providers for every crate, at least
85-
conceptually. Right now, there are really two sets: the providers for
86-
queries about the **local crate** (that is, the one being compiled)
87-
and providers for queries about **external crates** (that is,
88-
dependencies of the local crate). Note that what determines the crate
89-
that a query is targeting is not the *kind* of query, but the *key*.
86+
conceptually. There are two sets of providers:
87+
- The `Providers` struct for queries about the **local crate** (that is, the one being compiled)
88+
- The `ExternProviders` struct for queries about **external crates** (that is,
89+
dependencies of the local crate)
90+
91+
Note that what determines the crate that a query is targeting is not the *kind* of query, but the *key*.
9092
For example, when you invoke `tcx.type_of(def_id)`, that could be a
9193
local query or an external query, depending on what crate the `def_id`
9294
is referring to (see the [`self::keys::Key`][Key] trait for more
@@ -119,40 +121,43 @@ they define both a `provide` and a `provide_extern` function, through
119121

120122
### How providers are set up
121123

122-
When the tcx is created, it is given the providers by its creator using
123-
the [`Providers`][providers_struct] struct. This struct is generated by
124-
the macros here, but it is basically a big list of function pointers:
125-
126-
[providers_struct]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/struct.Providers.html
124+
When the tcx is created, it is given both the local and external providers by its creator using
125+
the `Providers` struct from `rustc_middle::util`. This struct contains both the local and external providers:
127126

128127
```rust,ignore
129-
struct Providers {
130-
type_of: for<'tcx> fn(TyCtxt<'tcx>, DefId) -> Ty<'tcx>,
131-
// ... one field for each query
128+
pub struct Providers {
129+
pub queries: crate::query::Providers, // Local crate providers
130+
pub extern_queries: crate::query::ExternProviders, // External crate providers
131+
pub hooks: crate::hooks::Providers,
132132
}
133133
```
134134

135+
Each of these provider structs is generated by the macros and contains function pointers for their respective queries.
136+
135137
#### How are providers registered?
136138

137-
The `Providers` struct is filled in during compiler initialization, mainly by the `rustc_driver` crate.
139+
The provider structs are filled in during compiler initialization, mainly by the `rustc_driver` crate.
138140
But the actual provider functions are implemented in various `rustc_*` crates (like `rustc_middle`, `rustc_hir_analysis`, etc).
139141

140142
To register providers, each crate exposes a [`provide`][provide_fn] function that looks like this:
141143

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

144146
```rust,ignore
145-
pub fn provide(providers: &mut Providers) {
146-
*providers = Providers {
147-
type_of,
148-
// ... add more providers here
149-
..*providers
150-
};
147+
pub fn provide(providers: &mut rustc_middle::util::Providers) {
148+
providers.queries.type_of = type_of;
149+
// ... add more local providers here
150+
151+
providers.extern_queries.type_of = extern_type_of;
152+
// ... add more external providers here
153+
154+
providers.hooks.some_hook = some_hook;
155+
// ... add more hooks here
151156
}
152157
```
153158

154159
- This function takes a mutable reference to the `Providers` struct and sets the fields to point to the correct provider functions.
155-
- You can also assign fields individually, e.g. `providers.type_of = type_of;`.
160+
- You can assign fields individually for each provider type (local, external, and hooks).
156161

157162
#### Adding a new provider
158163

@@ -164,11 +169,10 @@ Suppose you want to add a new query called `fubar`. You would:
164169
```
165170
2. Register it in the `provide` function:
166171
```rust,ignore
167-
pub fn provide(providers: &mut Providers) {
168-
*providers = Providers {
169-
fubar,
170-
..*providers
171-
};
172+
pub fn provide(providers: &mut rustc_middle::util::Providers) {
173+
providers.queries.fubar = fubar;
174+
// If you need an external provider:
175+
providers.extern_queries.fubar = extern_fubar;
172176
}
173177
```
174178
@@ -264,5 +268,4 @@ More discussion and issues:
264268
["Red/Green" dependency tracking in compiler]: https://github.com/rust-lang/rust/issues/42293
265269
[GitHub issue #42633]: https://github.com/rust-lang/rust/issues/42633
266270
[Incremental Compilation Beta]: https://internals.rust-lang.org/t/incremental-compilation-beta/4721
267-
[Incremental Compilation Announcement]: https://blog.rust-lang.org/2016/09/08/incremental.html
268-
271+
[Incremental Compilation Announcement]: https://blog.rust-lang.org/2016/09/08/incremental.html

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /