diff --git a/src/hir/lowering.md b/src/hir/lowering.md index c0057a69c1..b7d0293bed 100644 --- a/src/hir/lowering.md +++ b/src/hir/lowering.md @@ -15,8 +15,26 @@ of such structures include but are not limited to * Existential `impl Trait` * Converted to a virtual `existential type` declaration +The implementation of AST lowering is in the [`rustc_ast_lowering`] crate. +The entry point is [`lower_to_hir`], which retrieves the post-expansion AST +and resolver data from [`TyCtxt`] and builds the [`hir::Crate`] for the whole crate. + +Lowering is organized around HIR owners. [`lower_to_hir`] first indexes the +crate and then [`ItemLowerer::lower_node`] lowers each crate, item, associated +item, and foreign item. + +Most of the lowering logic lives on [`LoweringContext`]. The implementation is +split across multiple files in the [`rustc_ast_lowering`] crate such as `item.rs`, +`expr.rs`, `pat.rs`, `path.rs`, and others, but they all share the same [`LoweringContext`] +state and ID‑lowering machinery. + +Each owner is lowered in its own [`with_hir_id_owner`] scope. This is why the +`HirId` invariants below matter: `lower_node_id` maps AST `NodeId`s into the +current owner, while `next_id` creates fresh HIR-only nodes introduced during +desugaring. + Lowering needs to uphold several invariants in order to not trigger the -sanity checks in `compiler/rustc_passes/src/hir_id_validator.rs`: +sanity checks in [`compiler/rustc_passes/src/hir_id_validator.rs`][hir_id_validator]: 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 @@ -33,6 +51,15 @@ sanity checks in `compiler/rustc_passes/src/hir_id_validator.rs`: which produces both a new `NodeId` as well as automatically lowering it for you so you also get the `HirId`. +[`rustc_ast_lowering`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/index.html +[`lower_to_hir`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/fn.lower_to_hir.html +[`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html +[`hir::Crate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Crate.html +[`ItemLowerer::lower_node`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/item/struct.ItemLowerer.html +[`LoweringContext`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/struct.LoweringContext.html +[`with_hir_id_owner`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/struct.LoweringContext.html#method.with_hir_id_owner +[hir_id_validator]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_passes/src/hir_id_validator.rs + If you are creating new `DefId`s, since each `DefId` needs to have a corresponding `NodeId`, it is advisable to add these `NodeId`s to the `AST` so you don't have to generate new ones during lowering. This has