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 07e05bb

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

File tree

1 file changed

+39
-32
lines changed

1 file changed

+39
-32
lines changed

‎src/query.md

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,27 @@ 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+
[providers_struct]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/struct.Providers.html
82+
[extern_providers_struct]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/struct.ExternProviders.html
83+
84+
**Note:** Both the `Providers` and `ExternProviders` structs are generated by macros and act as function tables for all query implementations.
85+
They are **not** Rust traits, but plain structs with function pointer fields.
8286

8387
**Providers are defined per-crate.** The compiler maintains,
8488
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*.
89+
conceptually. There are two sets of providers:
90+
- The `Providers` struct for queries about the **local crate** (that is, the one being compiled)
91+
- The `ExternProviders` struct for queries about **external crates** (that is,
92+
dependencies of the local crate)
93+
94+
Note that what determines the crate that a query is targeting is not the *kind* of query, but the *key*.
9095
For example, when you invoke `tcx.type_of(def_id)`, that could be a
9196
local query or an external query, depending on what crate the `def_id`
9297
is referring to (see the [`self::keys::Key`][Key] trait for more
@@ -119,40 +124,43 @@ they define both a `provide` and a `provide_extern` function, through
119124

120125
### How providers are set up
121126

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
127+
When the tcx is created, it is given both the local and external providers by its creator using
128+
the `Providers` struct from `rustc_middle::util`. This struct contains both the local and external providers:
127129

128130
```rust,ignore
129-
struct Providers {
130-
type_of: for<'tcx> fn(TyCtxt<'tcx>, DefId) -> Ty<'tcx>,
131-
// ... one field for each query
131+
pub struct Providers {
132+
pub queries: crate::query::Providers, // Local crate providers
133+
pub extern_queries: crate::query::ExternProviders, // External crate providers
134+
pub hooks: crate::hooks::Providers,
132135
}
133136
```
134137

138+
Each of these provider structs is generated by the macros and contains function pointers for their respective queries.
139+
135140
#### How are providers registered?
136141

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

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

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

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

154162
- 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;`.
163+
- You can assign fields individually for each provider type (local, external, and hooks).
156164

157165
#### Adding a new provider
158166

@@ -164,11 +172,10 @@ Suppose you want to add a new query called `fubar`. You would:
164172
```
165173
2. Register it in the `provide` function:
166174
```rust,ignore
167-
pub fn provide(providers: &mut Providers) {
168-
*providers = Providers {
169-
fubar,
170-
..*providers
171-
};
175+
pub fn provide(providers: &mut rustc_middle::util::Providers) {
176+
providers.queries.fubar = fubar;
177+
// If you need an external provider:
178+
providers.extern_queries.fubar = extern_fubar;
172179
}
173180
```
174181

0 commit comments

Comments
(0)

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