From a48151a0dcaab283384b36296ed9a0538ab93fcd Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Mon, 8 Mar 2021 23:32:09 +0100 Subject: [PATCH 1/3] Add stub about the THIR --- src/SUMMARY.md | 3 ++- src/mir/construction.md | 22 ++++------------------ src/thir.md | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 src/thir.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 241178864..3f14c2642 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -84,8 +84,9 @@ - [The HIR (High-level IR)](./hir.md) - [Lowering AST to HIR](./lowering.md) - [Debugging](./hir-debugging.md) +- [The THIR (Typed High-level IR)](./thir.md) - [The MIR (Mid-level IR)](./mir/index.md) - - [THIR and MIR construction](./mir/construction.md) + - [MIR construction](./mir/construction.md) - [MIR visitor and traversal](./mir/visitor.md) - [MIR passes: getting the MIR for a function](./mir/passes.md) - [Identifiers in the Compiler](./identifiers.md) diff --git a/src/mir/construction.md b/src/mir/construction.md index d2c5a6f34..d9f99be03 100644 --- a/src/mir/construction.md +++ b/src/mir/construction.md @@ -1,4 +1,4 @@ -# THIR and MIR construction +# MIR construction @@ -13,23 +13,9 @@ list of items: * Drop code (the `Drop::drop` function is not called directly) * Drop implementations of types without an explicit `Drop` implementation -The lowering is triggered by calling the [`mir_built`] query. -There is an intermediate representation -between [HIR] and [MIR] called the [THIR] that is only used during lowering. -[THIR] means "Typed HIR" and used to be called "HAIR (High-level Abstract IR)". -The [THIR]'s most important feature is that the various adjustments (which happen -without explicit syntax) like coercions, autoderef, autoref and overloaded method -calls have become explicit casts, deref operations, reference expressions or -concrete function calls. - -The [THIR] is a shallow wrapper around [HIR], with datatypes that mirror the [HIR] datatypes. -For example, instead of `-x` being a `thir::ExprKind::Neg(thir::Expr)` -(a deep copy), it is a `thir::ExprKind::Neg(hir::Expr)` (a shallow copy). -This shallowness enables the [THIR] to represent all datatypes that [HIR] has, but -without having to create an in-memory copy of the entire [HIR]. -[MIR] lowering will first convert the topmost expression from -[HIR] to [THIR] (in [`rustc_mir_build::thir::cx::expr`]) and then process -the [THIR] expressions recursively. +The lowering is triggered by calling the [`mir_built`] query. The MIR builder does +not actually use the HIR but operates on the [THIR] instead, processing THIR +expressions recursively. The lowering creates local variables for every argument as specified in the signature. Next, it creates local variables for every binding specified (e.g. `(a, b): (i32, String)`) diff --git a/src/thir.md b/src/thir.md new file mode 100644 index 000000000..04bf635ce --- /dev/null +++ b/src/thir.md @@ -0,0 +1,39 @@ +# The THIR + + + +The THIR ("Typed High-Level Intermediate Representation"), previously HAIR for +"High-Level Abstract IR", is another IR used by rustc that is generated after +[type checking]. It is (as of March 2021) only used for +[MIR construction] and [exhaustiveness checking], but +[it may also soon be used for unsafety checking][thir-unsafeck] as a replacement +for the current MIR unsafety checker. + +[type checking]: ./type-checking.md +[MIR construction]: ./mir/construction.md +[exhaustiveness checking]: ./pat-exhaustive-checking.md +[thir-unsafeck]: https://github.com/rust-lang/compiler-team/issues/402 + +As the name might suggest, the THIR is a lowered version of the [HIR] where all +the types have been filled in, which is possible after type checking has completed. +But it has some other interesting features that distinguish it from HIR: +- like the MIR, the THIR only represents bodies, i.e. "executable code"; this includes + function bodies, but also `const` initializers, for example. Consequently, the THIR + has no representation for items like `struct`s or `trait`s. +- a body of THIR is only stored temporarily and is dropped as soon as it's no longer + needed, as opposed to being stored until the end of the compilation process (which + is what is done with the HIR). +- besides making the types of all nodes available, the THIR also has additional + desugaring compared to the HIR. For example, automatic references and dereferences + are made explicit, and method calls and overloaded operators are converted into + plain function calls. Destruction scopes are also made explicit. + +[HIR]: ./hir.md + +The THIR lives in [`rustc_mir_build::thir`][thir]. To construct a `thir::Expr`, +you can use the `build_thir` function, passing in the memory arena where the THIR +will be allocated. Dropping this arena will result in the THIR being destroyed: +this is useful to keep peak memory in check, as having a THIR representation of +all bodies of a crate in memory at the same time would be very heavy. + +[thir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/thir/index.html From f7bad139b137f651045ee8a4d506644ede760acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lanteri=20Thauvin?= Date: Tue, 9 Mar 2021 08:23:59 +0100 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Camelid --- src/thir.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/thir.md b/src/thir.md index 04bf635ce..efbc52849 100644 --- a/src/thir.md +++ b/src/thir.md @@ -2,7 +2,7 @@ -The THIR ("Typed High-Level Intermediate Representation"), previously HAIR for +The THIR ("Typed High-Level Intermediate Representation"), previously called HAIR for "High-Level Abstract IR", is another IR used by rustc that is generated after [type checking]. It is (as of March 2021) only used for [MIR construction] and [exhaustiveness checking], but @@ -16,14 +16,17 @@ for the current MIR unsafety checker. As the name might suggest, the THIR is a lowered version of the [HIR] where all the types have been filled in, which is possible after type checking has completed. -But it has some other interesting features that distinguish it from HIR: -- like the MIR, the THIR only represents bodies, i.e. "executable code"; this includes +But it has some other interesting features that distinguish it from the HIR: + +- Like the MIR, the THIR only represents bodies, i.e. "executable code"; this includes function bodies, but also `const` initializers, for example. Consequently, the THIR has no representation for items like `struct`s or `trait`s. -- a body of THIR is only stored temporarily and is dropped as soon as it's no longer + +- Each body of THIR is only stored temporarily and is dropped as soon as it's no longer needed, as opposed to being stored until the end of the compilation process (which is what is done with the HIR). -- besides making the types of all nodes available, the THIR also has additional + +- Besides making the types of all nodes available, the THIR also has additional desugaring compared to the HIR. For example, automatic references and dereferences are made explicit, and method calls and overloaded operators are converted into plain function calls. Destruction scopes are also made explicit. @@ -32,8 +35,8 @@ But it has some other interesting features that distinguish it from HIR: The THIR lives in [`rustc_mir_build::thir`][thir]. To construct a `thir::Expr`, you can use the `build_thir` function, passing in the memory arena where the THIR -will be allocated. Dropping this arena will result in the THIR being destroyed: -this is useful to keep peak memory in check, as having a THIR representation of +will be allocated. Dropping this arena will result in the THIR being destroyed, +which is useful to keep peak memory in check. Having a THIR representation of all bodies of a crate in memory at the same time would be very heavy. [thir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/thir/index.html From 838098f0910a04ccad0f084191b7158d9124d109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lanteri=20Thauvin?= Date: Tue, 9 Mar 2021 11:44:02 +0100 Subject: [PATCH 3/3] Update lins --- src/thir.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/thir.md b/src/thir.md index efbc52849..b023eb2e2 100644 --- a/src/thir.md +++ b/src/thir.md @@ -33,10 +33,12 @@ But it has some other interesting features that distinguish it from the HIR: [HIR]: ./hir.md -The THIR lives in [`rustc_mir_build::thir`][thir]. To construct a `thir::Expr`, -you can use the `build_thir` function, passing in the memory arena where the THIR +The THIR lives in [`rustc_mir_build::thir`][thir-docs]. To construct a [`thir::Expr`], +you can use the [`build_thir`] function, passing in the memory arena where the THIR will be allocated. Dropping this arena will result in the THIR being destroyed, which is useful to keep peak memory in check. Having a THIR representation of all bodies of a crate in memory at the same time would be very heavy. -[thir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/thir/index.html +[thir-docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/thir/index.html +[`thir::Expr`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/thir/struct.Expr.html +[`build_thir`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/thir/fn.build_thir.html