Update for TyCtxt<'a, 'gcx, 'tcx> -> TyCtxt<'tcx>.
This commit is contained in:
parent
c15c60938a
commit
f675e36941
|
|
@ -29,7 +29,7 @@ Item | Kind | Short description | Chapter |
|
||||||
`TraitDef` | struct | This struct contains a trait's definition with type information | [The `ty` modules] | [src/librustc/ty/trait_def.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/trait_def/struct.TraitDef.html)
|
`TraitDef` | struct | This struct contains a trait's definition with type information | [The `ty` modules] | [src/librustc/ty/trait_def.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/trait_def/struct.TraitDef.html)
|
||||||
`TraitRef` | struct | The combination of a trait and its input types (e.g. `P0: Trait<P1...Pn>`) | [Trait Solving: Goals and Clauses], [Trait Solving: Lowering impls] | [src/librustc/ty/sty.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/struct.TraitRef.html)
|
`TraitRef` | struct | The combination of a trait and its input types (e.g. `P0: Trait<P1...Pn>`) | [Trait Solving: Goals and Clauses], [Trait Solving: Lowering impls] | [src/librustc/ty/sty.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/struct.TraitRef.html)
|
||||||
`Ty<'tcx>` | struct | This is the internal representation of a type used for type checking | [Type checking] | [src/librustc/ty/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/type.Ty.html)
|
`Ty<'tcx>` | struct | This is the internal representation of a type used for type checking | [Type checking] | [src/librustc/ty/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/type.Ty.html)
|
||||||
`TyCtxt<'cx, 'tcx, 'tcx>` | struct | The "typing context". This is the central data structure in the compiler. It is the context that you use to perform all manner of queries | [The `ty` modules] | [src/librustc/ty/context.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/struct.TyCtxt.html)
|
`TyCtxt<'tcx>` | struct | The "typing context". This is the central data structure in the compiler. It is the context that you use to perform all manner of queries | [The `ty` modules] | [src/librustc/ty/context.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/struct.TyCtxt.html)
|
||||||
|
|
||||||
[The HIR]: ../hir.html
|
[The HIR]: ../hir.html
|
||||||
[Identifiers in the HIR]: ../hir.html#hir-id
|
[Identifiers in the HIR]: ../hir.html#hir-id
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ early-bound lifetime | a lifetime region that is substituted at its definiti
|
||||||
empty type | see "uninhabited type".
|
empty type | see "uninhabited type".
|
||||||
Fat pointer | a two word value carrying the address of some value, along with some further information necessary to put the value to use. Rust includes two kinds of "fat pointers": references to slices, and trait objects. A reference to a slice carries the starting address of the slice and its length. A trait object carries a value's address and a pointer to the trait's implementation appropriate to that value. "Fat pointers" are also known as "wide pointers", and "double pointers".
|
Fat pointer | a two word value carrying the address of some value, along with some further information necessary to put the value to use. Rust includes two kinds of "fat pointers": references to slices, and trait objects. A reference to a slice carries the starting address of the slice and its length. A trait object carries a value's address and a pointer to the trait's implementation appropriate to that value. "Fat pointers" are also known as "wide pointers", and "double pointers".
|
||||||
free variable | a "free variable" is one that is not bound within an expression or term; see [the background chapter for more](./background.html#free-vs-bound)
|
free variable | a "free variable" is one that is not bound within an expression or term; see [the background chapter for more](./background.html#free-vs-bound)
|
||||||
'gcx | the lifetime of the global arena ([see more](../ty.html))
|
|
||||||
generics | the set of generic type parameters defined on a type or item
|
generics | the set of generic type parameters defined on a type or item
|
||||||
HIR | the High-level IR, created by lowering and desugaring the AST ([see more](../hir.html))
|
HIR | the High-level IR, created by lowering and desugaring the AST ([see more](../hir.html))
|
||||||
HirId | identifies a particular node in the HIR by combining a def-id with an "intra-definition offset".
|
HirId | identifies a particular node in the HIR by combining a def-id with an "intra-definition offset".
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ stack backtrace:
|
||||||
|
|
||||||
If you want line numbers for the stack trace, you can enable `debug = true` in
|
If you want line numbers for the stack trace, you can enable `debug = true` in
|
||||||
your config.toml and rebuild the compiler (`debuginfo-level = 1` will also add
|
your config.toml and rebuild the compiler (`debuginfo-level = 1` will also add
|
||||||
line numbers, but `debug = true` gives full debuginfo). Then the backtrace will
|
line numbers, but `debug = true` gives full debuginfo). Then the backtrace will
|
||||||
look like this:
|
look like this:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|
@ -129,11 +129,11 @@ note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose
|
||||||
backtrace.
|
backtrace.
|
||||||
stack backtrace:
|
stack backtrace:
|
||||||
(~~~ IRRELEVANT PART OF BACKTRACE REMOVED BY ME ~~~)
|
(~~~ IRRELEVANT PART OF BACKTRACE REMOVED BY ME ~~~)
|
||||||
7: rustc::traits::error_reporting::<impl rustc::infer::InferCtxt<'a, 'gcx,
|
7: rustc::traits::error_reporting::<impl rustc::infer::InferCtxt<'a, 'tcx>>
|
||||||
'tcx>>::report_selection_error
|
::report_selection_error
|
||||||
at /home/user/rust/src/librustc/traits/error_reporting.rs:823
|
at /home/user/rust/src/librustc/traits/error_reporting.rs:823
|
||||||
8: rustc::traits::error_reporting::<impl rustc::infer::InferCtxt<'a, 'gcx,
|
8: rustc::traits::error_reporting::<impl rustc::infer::InferCtxt<'a, 'tcx>>
|
||||||
'tcx>>::report_fulfillment_errors
|
::report_fulfillment_errors
|
||||||
at /home/user/rust/src/librustc/traits/error_reporting.rs:160
|
at /home/user/rust/src/librustc/traits/error_reporting.rs:160
|
||||||
at /home/user/rust/src/librustc/traits/error_reporting.rs:112
|
at /home/user/rust/src/librustc/traits/error_reporting.rs:112
|
||||||
9: rustc_typeck::check::FnCtxt::select_obligations_where_possible
|
9: rustc_typeck::check::FnCtxt::select_obligations_where_possible
|
||||||
|
|
|
||||||
|
|
@ -141,8 +141,7 @@ to the compiler.
|
||||||
- `cx` tends to be short for "context" and is often used as a suffix. For
|
- `cx` tends to be short for "context" and is often used as a suffix. For
|
||||||
example, `tcx` is a common name for the [Typing Context][tcx].
|
example, `tcx` is a common name for the [Typing Context][tcx].
|
||||||
|
|
||||||
- [`'tcx` and `'gcx`][tcx] are used as the lifetime names for the Typing
|
- [`'tcx`][tcx] is used as the lifetim names for the Typing Context.
|
||||||
Context.
|
|
||||||
|
|
||||||
- Because `crate` is a keyword, if you need a variable to represent something
|
- Because `crate` is a keyword, if you need a variable to represent something
|
||||||
crate-related, often the spelling is changed to `krate`.
|
crate-related, often the spelling is changed to `krate`.
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ state you will need while processing MIR:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
struct MyVisitor<...> {
|
struct MyVisitor<...> {
|
||||||
tcx: TyCtxt<'cx, 'tcx, 'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -272,9 +272,9 @@ Tree
|
||||||
: : | rustc_mir::borrow_check::nll::type_check::type_check_internal (13% total, 0% self)
|
: : | rustc_mir::borrow_check::nll::type_check::type_check_internal (13% total, 0% self)
|
||||||
: : : | core::ops::function::FnOnce::call_once (5% total, 0% self)
|
: : : | core::ops::function::FnOnce::call_once (5% total, 0% self)
|
||||||
: : : : | rustc_mir::borrow_check::nll::type_check::liveness::generate (5% total, 3% self)
|
: : : : | rustc_mir::borrow_check::nll::type_check::liveness::generate (5% total, 3% self)
|
||||||
: : : | <rustc_mir::borrow_check::nll::type_check::TypeVerifier<'a, 'b, 'gcx, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_mir (3% total, 0% self)
|
: : : | <rustc_mir::borrow_check::nll::type_check::TypeVerifier<'a, 'b, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_mir (3% total, 0% self)
|
||||||
: | rustc::mir::visit::Visitor::visit_mir (8% total, 6% self)
|
: | rustc::mir::visit::Visitor::visit_mir (8% total, 6% self)
|
||||||
: | <rustc_mir::borrow_check::MirBorrowckCtxt<'cx, 'gcx, 'tcx> as rustc_mir::dataflow::DataflowResultsConsumer<'cx, 'tcx>>::visit_statement_entry (5% total, 0% self)
|
: | <rustc_mir::borrow_check::MirBorrowckCtxt<'cx, 'tcx> as rustc_mir::dataflow::DataflowResultsConsumer<'cx, 'tcx>>::visit_statement_entry (5% total, 0% self)
|
||||||
: | rustc_mir::dataflow::do_dataflow (3% total, 0% self)
|
: | rustc_mir::dataflow::do_dataflow (3% total, 0% self)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -321,7 +321,7 @@ Tree
|
||||||
| matched `{do_mir_borrowck}` (100% total, 0% self)
|
| matched `{do_mir_borrowck}` (100% total, 0% self)
|
||||||
: | rustc_mir::borrow_check::nll::compute_regions (47% total, 0% self) [...]
|
: | rustc_mir::borrow_check::nll::compute_regions (47% total, 0% self) [...]
|
||||||
: | rustc::mir::visit::Visitor::visit_mir (19% total, 15% self) [...]
|
: | rustc::mir::visit::Visitor::visit_mir (19% total, 15% self) [...]
|
||||||
: | <rustc_mir::borrow_check::MirBorrowckCtxt<'cx, 'gcx, 'tcx> as rustc_mir::dataflow::DataflowResultsConsumer<'cx, 'tcx>>::visit_statement_entry (13% total, 0% self) [...]
|
: | <rustc_mir::borrow_check::MirBorrowckCtxt<'cx, 'tcx> as rustc_mir::dataflow::DataflowResultsConsumer<'cx, 'tcx>>::visit_statement_entry (13% total, 0% self) [...]
|
||||||
: | rustc_mir::dataflow::do_dataflow (8% total, 1% self) [...]
|
: | rustc_mir::dataflow::do_dataflow (8% total, 1% self) [...]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
16
src/query.md
16
src/query.md
|
|
@ -82,17 +82,15 @@ on how that works).
|
||||||
Providers always have the same signature:
|
Providers always have the same signature:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
fn provider<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx, 'tcx>,
|
fn provider<'tcx>(
|
||||||
key: QUERY_KEY)
|
tcx: TyCtxt<'tcx>,
|
||||||
-> QUERY_RESULT
|
key: QUERY_KEY,
|
||||||
{
|
) -> QUERY_RESULT {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Providers take two arguments: the `tcx` and the query key. Note also
|
Providers take two arguments: the `tcx` and the query key.
|
||||||
that they take the *global* tcx (i.e. they use the `'tcx` lifetime
|
|
||||||
twice), rather than taking a tcx with some active inference context.
|
|
||||||
They return the result of the query.
|
They return the result of the query.
|
||||||
|
|
||||||
#### How providers are setup
|
#### How providers are setup
|
||||||
|
|
@ -103,7 +101,7 @@ is basically a big list of function pointers:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
struct Providers {
|
struct Providers {
|
||||||
type_of: for<'cx, 'tcx> fn(TyCtxt<'cx, 'tcx, 'tcx>, DefId) -> Ty<'tcx>,
|
type_of: for<'tcx> fn(TyCtxt<'tcx>, DefId) -> Ty<'tcx>,
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -144,7 +142,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fubar<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx>, key: DefId) -> Fubar<'tcx> { ... }
|
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
|
||||||
|
|
|
||||||
58
src/ty.md
58
src/ty.md
|
|
@ -11,63 +11,19 @@ compiler. It is the context that you use to perform all manner of
|
||||||
queries. The struct `TyCtxt` defines a reference to this shared context:
|
queries. The struct `TyCtxt` defines a reference to this shared context:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>
|
tcx: TyCtxt<'tcx>
|
||||||
// -- ---- ----
|
// ----
|
||||||
// | | |
|
// |
|
||||||
// | | innermost arena lifetime (if any)
|
// arena lifetime
|
||||||
// | "global arena" lifetime
|
|
||||||
// lifetime of this reference
|
|
||||||
```
|
```
|
||||||
|
|
||||||
As you can see, the `TyCtxt` type takes three lifetime parameters.
|
As you can see, the `TyCtxt` type takes a lifetime parameter.
|
||||||
These lifetimes are perhaps the most complex thing to understand about
|
During Rust compilation, we allocate most of our memory in
|
||||||
the tcx. During Rust compilation, we allocate most of our memory in
|
|
||||||
**arenas**, which are basically pools of memory that get freed all at
|
**arenas**, which are basically pools of memory that get freed all at
|
||||||
once. When you see a reference with a lifetime like `'tcx` or `'gcx`,
|
once. When you see a reference with a lifetime like `'tcx`,
|
||||||
you know that it refers to arena-allocated data (or data that lives as
|
you know that it refers to arena-allocated data (or data that lives as
|
||||||
long as the arenas, anyhow).
|
long as the arenas, anyhow).
|
||||||
|
|
||||||
We use two distinct levels of arenas. The outer level is the "global
|
|
||||||
arena". This arena lasts for the entire compilation: so anything you
|
|
||||||
allocate in there is only freed once compilation is basically over
|
|
||||||
(actually, when we shift to executing LLVM).
|
|
||||||
|
|
||||||
To reduce peak memory usage, when we do type inference, we also use an
|
|
||||||
inner level of arena. These arenas get thrown away once type inference
|
|
||||||
is over. This is done because type inference generates a lot of
|
|
||||||
"throw-away" types that are not particularly interesting after type
|
|
||||||
inference completes, so keeping around those allocations would be
|
|
||||||
wasteful.
|
|
||||||
|
|
||||||
Often, we wish to write code that explicitly asserts that it is not
|
|
||||||
taking place during inference. In that case, there is no "local"
|
|
||||||
arena, and all the types that you can access are allocated in the
|
|
||||||
global arena. To express this, the idea is to use the same lifetime
|
|
||||||
for the `'gcx` and `'tcx` parameters of `TyCtxt`. Just to be a touch
|
|
||||||
confusing, we tend to use the name `'tcx` in such contexts. Here is an
|
|
||||||
example:
|
|
||||||
|
|
||||||
```rust,ignore
|
|
||||||
fn not_in_inference<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
|
|
||||||
// ---- ----
|
|
||||||
// Using the same lifetime here asserts
|
|
||||||
// that the innermost arena accessible through
|
|
||||||
// this reference *is* the global arena.
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In contrast, if we want to code that can be usable during type inference, then
|
|
||||||
you need to declare a distinct `'gcx` and `'tcx` lifetime parameter:
|
|
||||||
|
|
||||||
```rust,ignore
|
|
||||||
fn maybe_in_inference<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId) {
|
|
||||||
// ---- ----
|
|
||||||
// Using different lifetimes here means that
|
|
||||||
// the innermost arena *may* be distinct
|
|
||||||
// from the global arena (but doesn't have to be).
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Allocating and working with types
|
### Allocating and working with types
|
||||||
|
|
||||||
Rust types are represented using the `Ty<'tcx>` defined in the `ty`
|
Rust types are represented using the `Ty<'tcx>` defined in the `ty`
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,8 @@ function and disposed of after it returns.
|
||||||
|
|
||||||
[ty-ch]: ty.html
|
[ty-ch]: ty.html
|
||||||
|
|
||||||
Within the closure, `infcx` has the type `InferCtxt<'cx, 'gcx, 'tcx>`
|
Within the closure, `infcx` has the type `InferCtxt<'cx, 'tcx>` for some
|
||||||
for some fresh `'cx` and `'tcx` – the latter corresponds to the lifetime of
|
fresh `'cx`, while `'tcx` is the same as outside the inference context.
|
||||||
this temporary arena, and the `'cx` is the lifetime of the `InferCtxt` itself.
|
|
||||||
(Again, see the [`ty` chapter][ty-ch] for more details on this setup.)
|
(Again, see the [`ty` chapter][ty-ch] for more details on this setup.)
|
||||||
|
|
||||||
The `tcx.infer_ctxt` method actually returns a builder, which means
|
The `tcx.infer_ctxt` method actually returns a builder, which means
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue