From 307cc8865ce16949e030f06bb8d0d0c8ca999066 Mon Sep 17 00:00:00 2001 From: Redddy Date: Thu, 12 Mar 2026 17:41:14 +0900 Subject: [PATCH 1/2] Add reference link for HIR ID validator --- src/hir/lowering.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hir/lowering.md b/src/hir/lowering.md index c0057a69c1..b8c757fecc 100644 --- a/src/hir/lowering.md +++ b/src/hir/lowering.md @@ -16,7 +16,7 @@ of such structures include but are not limited to * Converted to a virtual `existential type` declaration 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 +33,8 @@ 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`. +[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 From 200d9390e43304c8a792dd0befd2ce16298b7e45 Mon Sep 17 00:00:00 2001 From: Redddy Date: Thu, 19 Mar 2026 11:20:57 +0900 Subject: [PATCH 2/2] Document AST lowering implementation --- src/hir/lowering.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/hir/lowering.md b/src/hir/lowering.md index b8c757fecc..b7d0293bed 100644 --- a/src/hir/lowering.md +++ b/src/hir/lowering.md @@ -15,6 +15,24 @@ 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`][hir_id_validator]: @@ -33,6 +51,13 @@ sanity checks in [`compiler/rustc_passes/src/hir_id_validator.rs`][hir_id_valida 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