Update for TyCtxt<'a, 'gcx, 'tcx> -> TyCtxt<'tcx>.

This commit is contained in:
Eduard-Mihai Burtescu 2019-06-14 19:17:23 +03:00 committed by Who? Me?!
parent c15c60938a
commit f675e36941
9 changed files with 27 additions and 76 deletions

View File

@ -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

View File

@ -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".

View File

@ -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

View File

@ -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`.

View File

@ -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>,
... ...
} }
``` ```

View File

@ -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) [...]
``` ```

View File

@ -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

View File

@ -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`

View File

@ -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