about summary refs log tree commit diff
path: root/src/doc/rustc-dev-guide
diff options
context:
space:
mode:
authorOliver Schneider <github35764891676564198441@oli-obk.de>2018-06-01 17:34:45 +0200
committerWho? Me?! <mark-i-m@users.noreply.github.com>2018-07-08 17:41:12 -0500
commit86d807ba75462ce468b6a68fc485f53b6676357e (patch)
tree22844551ad886d60dc8775330111752a40566704 /src/doc/rustc-dev-guide
parent7efa4132cba3eac54004e95a46657fcb1b0d0a16 (diff)
downloadrust-86d807ba75462ce468b6a68fc485f53b6676357e.tar.gz
rust-86d807ba75462ce468b6a68fc485f53b6676357e.zip
Add some explanation of lowering ids
Diffstat (limited to 'src/doc/rustc-dev-guide')
-rw-r--r--src/doc/rustc-dev-guide/src/high-level-overview.md3
-rw-r--r--src/doc/rustc-dev-guide/src/lowering.md35
2 files changed, 37 insertions, 1 deletions
diff --git a/src/doc/rustc-dev-guide/src/high-level-overview.md b/src/doc/rustc-dev-guide/src/high-level-overview.md
index 60b9e80ea23..733c523c90e 100644
--- a/src/doc/rustc-dev-guide/src/high-level-overview.md
+++ b/src/doc/rustc-dev-guide/src/high-level-overview.md
@@ -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
\ No newline at end of file
diff --git a/src/doc/rustc-dev-guide/src/lowering.md b/src/doc/rustc-dev-guide/src/lowering.md
new file mode 100644
index 00000000000..335513342c4
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/lowering.md
@@ -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`.
\ No newline at end of file