Add some explanation of lowering ids

This commit is contained in:
Oliver Schneider 2018-06-01 17:34:45 +02:00 committed by Who? Me?!
parent 769b33c7e3
commit edae077f8f
2 changed files with 37 additions and 1 deletions

View File

@ -105,7 +105,7 @@ take:
3. **Lowering to HIR** 3. **Lowering to HIR**
- Once name resolution completes, we convert the AST into the HIR, - Once name resolution completes, we convert the AST into the HIR,
or "[high-level intermediate representation]". The HIR is defined in or "[high-level intermediate representation]". The HIR is defined in
`src/librustc/hir/`; that module also includes the lowering code. `src/librustc/hir/`; that module also includes the [lowering] code.
- The HIR is a lightly desugared variant of the AST. It is more processed - The HIR is a lightly desugared variant of the AST. It is more processed
than the AST and more suitable for the analyses that follow. than the AST and more suitable for the analyses that follow.
It is **not** required to match the syntax of the Rust language. It is **not** required to match the syntax of the Rust language.
@ -139,3 +139,4 @@ take:
[query model]: query.html [query model]: query.html
[high-level intermediate representation]: hir.html [high-level intermediate representation]: hir.html
[lowering]: lowering.html

35
src/lowering.md Normal file
View File

@ -0,0 +1,35 @@
# Lowering
The lowering step converts AST to [HIR](hir.html).
This means many structures are removed if they are irrelevant
for type analysis or similar syntax agnostic analyses. Examples
of such structures include but are not limited to
* Parenthesis
* Removed without replacement, the tree structure makes order explicit
* `for` loops and `while (let)` loops
* Converted to `loop` + `match` and some `let` bindings
* `if let`
* Converted to `match`
* Universal `impl Trait`
* Converted to generic arguments (but with some flags, to know that the user didn't write them)
* Existential `impl Trait`
* Converted to a virtual `existential type` declaration
Lowering needs to uphold several invariants in order to not trigger the
sanity checks in `src/librustc/hir/map/hir_id_validator.rs`:
1. A `HirId` must be used if created. So if you use the `lower_node_id`,
you *must* use the resulting `NodeId` or `HirId` (either is fine, since
any `NodeId`s in the `HIR` are checked for existing `HirId`s)
2. Lowering a `HirId` must be done in the scope of the *owning* item.
This means you need to use `with_hir_id_owner` if you are creating parts
of another item than the one being currently lowered. This happens for
example during the lowering of existential `impl Trait`
3. A `NodeId` that will be placed into a HIR structure must be lowered,
even if its `HirId` is unused. Calling
`let _ = self.lower_node_id(node_id);` is perfectly legitimate.
4. If you are creating new nodes that didn't exist in the `AST`, you *must*
create new ids for them. This is done by calling the `next_id` method,
which produces both a new `NodeId` as well as automatically lowering it
for you so you also get the `HirId`.