]> git.proxmox.com Git - rustc.git/blame - src/doc/rustc-dev-guide/src/lowering.md
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / src / doc / rustc-dev-guide / src / lowering.md
CommitLineData
a1dfa0c6
XL
1# Lowering
2
3The lowering step converts AST to [HIR](hir.html).
4This means many structures are removed if they are irrelevant
5for type analysis or similar syntax agnostic analyses. Examples
6of such structures include but are not limited to
7
8* Parenthesis
9 * Removed without replacement, the tree structure makes order explicit
10* `for` loops and `while (let)` loops
11 * Converted to `loop` + `match` and some `let` bindings
12* `if let`
13 * Converted to `match`
14* Universal `impl Trait`
15 * Converted to generic arguments
16 (but with some flags, to know that the user didn't write them)
17* Existential `impl Trait`
18 * Converted to a virtual `existential type` declaration
19
20Lowering needs to uphold several invariants in order to not trigger the
6a06907d 21sanity checks in `compiler/rustc_middle/src/hir/map/hir_id_validator.rs`:
a1dfa0c6
XL
22
231. A `HirId` must be used if created. So if you use the `lower_node_id`,
24 you *must* use the resulting `NodeId` or `HirId` (either is fine, since
25 any `NodeId`s in the `HIR` are checked for existing `HirId`s)
262. Lowering a `HirId` must be done in the scope of the *owning* item.
27 This means you need to use `with_hir_id_owner` if you are creating parts
28 of an item other than the one being currently lowered. This happens for
29 example during the lowering of existential `impl Trait`
303. A `NodeId` that will be placed into a HIR structure must be lowered,
31 even if its `HirId` is unused. Calling
32 `let _ = self.lower_node_id(node_id);` is perfectly legitimate.
334. If you are creating new nodes that didn't exist in the `AST`, you *must*
34 create new ids for them. This is done by calling the `next_id` method,
35 which produces both a new `NodeId` as well as automatically lowering it
36 for you so you also get the `HirId`.
37
38If you are creating new `DefId`s, since each `DefId` needs to have a
39corresponding `NodeId`, it is advisable to add these `NodeId`s to the
40`AST` so you don't have to generate new ones during lowering. This has
41the advantage of creating a way to find the `DefId` of something via its
42`NodeId`. If lowering needs this `DefId` in multiple places, you can't
43generate a new `NodeId` in all those places because you'd also get a new
44`DefId` then. With a `NodeId` from the `AST` this is not an issue.
45
46Having the `NodeId` also allows the `DefCollector` to generate the `DefId`s
47instead of lowering having to do it on the fly. Centralizing the `DefId`
48generation in one place makes it easier to refactor and reason about.