Add some explanation of lowering ids
This commit is contained in:
parent
769b33c7e3
commit
edae077f8f
|
|
@ -105,7 +105,7 @@ take:
|
|||
3. **Lowering to HIR**
|
||||
- Once name resolution completes, we convert the AST into the HIR,
|
||||
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
|
||||
than the AST and more suitable for the analyses that follow.
|
||||
It is **not** required to match the syntax of the Rust language.
|
||||
|
|
@ -139,3 +139,4 @@ take:
|
|||
|
||||
[query model]: query.html
|
||||
[high-level intermediate representation]: hir.html
|
||||
[lowering]: lowering.html
|
||||
|
|
@ -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`.
|
||||
Loading…
Reference in New Issue