Skip to content

Commit

Permalink
Update for TyCtxt<'a, 'gcx, 'tcx> -> TyCtxt<'tcx>.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb authored and mark-i-m committed Jun 15, 2019
1 parent c15c609 commit f675e36
Show file tree
Hide file tree
Showing 9 changed files with 27 additions and 76 deletions.
2 changes: 1 addition & 1 deletion src/appendix/code-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
`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)
`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
[Identifiers in the HIR]: ../hir.html#hir-id
Expand Down
1 change: 0 additions & 1 deletion src/appendix/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ early-bound lifetime | a lifetime region that is substituted at its definiti
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".
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
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".
Expand Down
10 changes: 5 additions & 5 deletions src/compiler-debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ stack backtrace:

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

```text
Expand Down Expand Up @@ -129,11 +129,11 @@ note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose
backtrace.
stack backtrace:
(~~~ IRRELEVANT PART OF BACKTRACE REMOVED BY ME ~~~)
7: rustc::traits::error_reporting::<impl rustc::infer::InferCtxt<'a, 'gcx,
'tcx>>::report_selection_error
7: rustc::traits::error_reporting::<impl rustc::infer::InferCtxt<'a, 'tcx>>
::report_selection_error
at /home/user/rust/src/librustc/traits/error_reporting.rs:823
8: rustc::traits::error_reporting::<impl rustc::infer::InferCtxt<'a, 'gcx,
'tcx>>::report_fulfillment_errors
8: rustc::traits::error_reporting::<impl rustc::infer::InferCtxt<'a, 'tcx>>
::report_fulfillment_errors
at /home/user/rust/src/librustc/traits/error_reporting.rs:160
at /home/user/rust/src/librustc/traits/error_reporting.rs:112
9: rustc_typeck::check::FnCtxt::select_obligations_where_possible
Expand Down
3 changes: 1 addition & 2 deletions src/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,7 @@ to the compiler.
- `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].

- [`'tcx` and `'gcx`][tcx] are used as the lifetime names for the Typing
Context.
- [`'tcx`][tcx] is used as the lifetim names for the Typing Context.

- Because `crate` is a keyword, if you need a variable to represent something
crate-related, often the spelling is changed to `krate`.
Expand Down
2 changes: 1 addition & 1 deletion src/mir/visitor.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ state you will need while processing MIR:

```rust,ignore
struct MyVisitor<...> {
tcx: TyCtxt<'cx, 'tcx, 'tcx>,
tcx: TyCtxt<'tcx>,
...
}
```
Expand Down
6 changes: 3 additions & 3 deletions src/profiling/with_perf.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,9 @@ Tree
: : | rustc_mir::borrow_check::nll::type_check::type_check_internal (13% 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::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::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)
```

Expand Down Expand Up @@ -321,7 +321,7 @@ Tree
| matched `{do_mir_borrowck}` (100% 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::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) [...]
```

Expand Down
16 changes: 7 additions & 9 deletions src/query.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,15 @@ on how that works).
Providers always have the same signature:

```rust,ignore
fn provider<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx, 'tcx>,
key: QUERY_KEY)
-> QUERY_RESULT
{
fn provider<'tcx>(
tcx: TyCtxt<'tcx>,
key: QUERY_KEY,
) -> QUERY_RESULT {
...
}
```

Providers take two arguments: the `tcx` and the query key. Note also
that they take the *global* tcx (i.e. they use the `'tcx` lifetime
twice), rather than taking a tcx with some active inference context.
Providers take two arguments: the `tcx` and the query key.
They return the result of the query.

#### How providers are setup
Expand All @@ -103,7 +101,7 @@ is basically a big list of function pointers:

```rust,ignore
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>,
...
}
```
Expand Down Expand Up @@ -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
Expand Down
58 changes: 7 additions & 51 deletions src/ty.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

```rust,ignore
tcx: TyCtxt<'a, 'gcx, 'tcx>
// -- ---- ----
// | | |
// | | innermost arena lifetime (if any)
// | "global arena" lifetime
// lifetime of this reference
tcx: TyCtxt<'tcx>
// ----
// |
// arena lifetime
```

As you can see, the `TyCtxt` type takes three lifetime parameters.
These lifetimes are perhaps the most complex thing to understand about
the tcx. During Rust compilation, we allocate most of our memory in
As you can see, the `TyCtxt` type takes a lifetime parameter.
During Rust compilation, we allocate most of our memory in
**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
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

Rust types are represented using the `Ty<'tcx>` defined in the `ty`
Expand Down
5 changes: 2 additions & 3 deletions src/type-inference.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,8 @@ function and disposed of after it returns.

[ty-ch]: ty.html

Within the closure, `infcx` has the type `InferCtxt<'cx, 'gcx, 'tcx>`
for some fresh `'cx` and `'tcx` – the latter corresponds to the lifetime of
this temporary arena, and the `'cx` is the lifetime of the `InferCtxt` itself.
Within the closure, `infcx` has the type `InferCtxt<'cx, 'tcx>` for some
fresh `'cx`, while `'tcx` is the same as outside the inference context.
(Again, see the [`ty` chapter][ty-ch] for more details on this setup.)

The `tcx.infer_ctxt` method actually returns a builder, which means
Expand Down

0 comments on commit f675e36

Please sign in to comment.