Add links to the rustc docs (#578)

This commit is contained in:
LORIS INTERGALACTIQUE 2020-02-15 01:35:11 +01:00 committed by GitHub
parent 7e862e9ebf
commit 4525b72263
1 changed files with 31 additions and 19 deletions

View File

@ -76,8 +76,8 @@ dependencies of the local crate). Note that what determines the crate
that a query is targeting is not the *kind* of query, but the *key*. that a query is targeting is not the *kind* of query, but the *key*.
For example, when you invoke `tcx.type_of(def_id)`, that could be a For example, when you invoke `tcx.type_of(def_id)`, that could be a
local query or an external query, depending on what crate the `def_id` local query or an external query, depending on what crate the `def_id`
is referring to (see the `self::keys::Key` trait for more information is referring to (see the [`self::keys::Key`][Key] trait for more
on how that works). information on how that works).
Providers always have the same signature: Providers always have the same signature:
@ -96,8 +96,10 @@ They return the result of the query.
#### How providers are setup #### How providers are setup
When the tcx is created, it is given the providers by its creator using When the tcx is created, it is given the providers by its creator using
the `Providers` struct. This struct is generated by the macros here, but it the [`Providers`][providers_struct] struct. This struct is generated by
is basically a big list of function pointers: the macros here, but it is basically a big list of function pointers:
[providers_struct]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/query/struct.Providers.html
```rust,ignore ```rust,ignore
struct Providers { struct Providers {
@ -110,11 +112,13 @@ At present, we have one copy of the struct for local crates, and one
for external crates, though the plan is that we may eventually have for external crates, though the plan is that we may eventually have
one per crate. one per crate.
These `Provider` structs are ultimately created and populated by These `Providers` structs are ultimately created and populated by
`librustc_driver`, but it does this by distributing the work `librustc_driver`, but it does this by distributing the work
throughout the other `rustc_*` crates. This is done by invoking throughout the other `rustc_*` crates. This is done by invoking
various `provide` functions. These functions tend to look something various [`provide`][provide_fn] functions. These functions tend to look
like this: something like this:
[provide_fn]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/hir/fn.provide.html
```rust,ignore ```rust,ignore
pub fn provide(providers: &mut Providers) { pub fn provide(providers: &mut Providers) {
@ -147,13 +151,16 @@ fn fubar<'tcx>(tcx: TyCtxt<'tcx>, key: DefId) -> Fubar<'tcx> { ... }
N.B. Most of the `rustc_*` crates only provide **local N.B. Most of the `rustc_*` crates only provide **local
providers**. Almost all **extern providers** wind up going through the providers**. Almost all **extern providers** wind up going through the
[`rustc_metadata` crate][rustc_metadata], which loads the information from the [`rustc_metadata` crate][rustc_metadata], which loads the information
crate metadata. But in some cases there are crates that provide queries for from the crate metadata. But in some cases there are crates that
*both* local and external crates, in which case they define both a provide queries for *both* local and external crates, in which case
`provide` and a `provide_extern` function that `rustc_driver` can they define both a [`provide`][ext_provide] and a
invoke. [`provide_extern`][ext_provide_extern] function that `rustc_driver`
can invoke.
[rustc_metadata]: https://github.com/rust-lang/rust/tree/master/src/librustc_metadata [rustc_metadata]: https://github.com/rust-lang/rust/tree/master/src/librustc_metadata
[ext_provide]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_llvm/attributes/fn.provide.html
[ext_provide_extern]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_llvm/attributes/fn.provide_extern.html
### Adding a new kind of query ### Adding a new kind of query
@ -205,7 +212,7 @@ Let's go over them one by one:
(`ty::queries::type_of`) that will be generated to represent (`ty::queries::type_of`) that will be generated to represent
this query. this query.
- **Query key type:** the type of the argument to this query. - **Query key type:** the type of the argument to this query.
This type must implement the `ty::query::keys::Key` trait, which This type must implement the [`ty::query::keys::Key`][Key] trait, which
defines (for example) how to map it to a crate, and so forth. defines (for example) how to map it to a crate, and so forth.
- **Result type of query:** the type produced by this query. This type - **Result type of query:** the type produced by this query. This type
should (a) not use `RefCell` or other interior mutability and (b) be should (a) not use `RefCell` or other interior mutability and (b) be
@ -218,6 +225,8 @@ Let's go over them one by one:
- **Query modifiers:** various flags and options that customize how the - **Query modifiers:** various flags and options that customize how the
query is processed. query is processed.
[Key]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/query/keys/trait.Key.html
So, to add a query: So, to add a query:
- Add an entry to `rustc_queries!` using the format above. - Add an entry to `rustc_queries!` using the format above.
@ -229,7 +238,7 @@ So, to add a query:
For each kind, the `rustc_queries` macro will generate a "query struct" For each kind, the `rustc_queries` macro will generate a "query struct"
named after the query. This struct is a kind of a place-holder named after the query. This struct is a kind of a place-holder
describing the query. Each such struct implements the describing the query. Each such struct implements the
`self::config::QueryConfig` trait, which has associated types for the [`self::config::QueryConfig`][QueryConfig] trait, which has associated types for the
key/value of that particular query. Basically the code generated looks something key/value of that particular query. Basically the code generated looks something
like this: like this:
@ -247,13 +256,16 @@ impl<'tcx> QueryConfig for type_of<'tcx> {
``` ```
There is an additional trait that you may wish to implement called There is an additional trait that you may wish to implement called
`self::config::QueryDescription`. This trait is used during cycle [`self::config::QueryDescription`][QueryDescription]. This trait is
errors to give a "human readable" name for the query, so that we can used during cycle errors to give a "human readable" name for the query,
summarize what was happening when the cycle occurred. Implementing so that we can summarize what was happening when the cycle occurred.
this trait is optional if the query key is `DefId`, but if you *don't* Implementing this trait is optional if the query key is `DefId`, but
implement it, you get a pretty generic error ("processing `foo`..."). if you *don't* implement it, you get a pretty generic error ("processing `foo`...").
You can put new impls into the `config` module. They look something like this: You can put new impls into the `config` module. They look something like this:
[QueryConfig]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/query/trait.QueryConfig.html
[QueryDescription]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/query/config/trait.QueryDescription.html
```rust,ignore ```rust,ignore
impl<'tcx> QueryDescription for queries::type_of<'tcx> { impl<'tcx> QueryDescription for queries::type_of<'tcx> {
fn describe(tcx: TyCtxt, key: DefId) -> String { fn describe(tcx: TyCtxt, key: DefId) -> String {