Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions src/thir.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

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 <!-- date-check --> January 2024) used for
[MIR construction], [exhaustiveness checking], and [unsafety checking].
[type checking]. It is (as of <!-- date-check --> October 2026) used for
[MIR construction], [exhaustiveness checking], [unsafety checking], and
[explicit tail call checking].

[type checking]: ./hir-typeck/summary.md
[MIR construction]: ./mir/construction.md
[exhaustiveness checking]: ./pat-exhaustive-checking.md
[unsafety checking]: ./unsafety-checking.md
[explicit tail call checking]: https://github.com/rust-lang/rust/issues/112788

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.
Expand Down Expand Up @@ -39,12 +41,9 @@ But it has some other interesting features that distinguish it from the HIR:
[`ExprId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/thir/struct.ExprId.html
[body owners]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.BodyOwnerKind.html

The THIR lives in [`rustc_mir_build::thir`][thir-docs].
To construct a [`thir::Expr`],
you can use the [`thir_body`] 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.
The THIR lives in [`rustc_middle::thir`][thir-docs].
To construct a [`thir::Expr`], you can use the [`thir_body`] query.
The THIR is freed after unsafety checking, 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.

Expand All @@ -59,15 +58,15 @@ fn main() {
}
```

Here is how that gets represented in THIR (as of <!-- date-check --> Jul 2026):
Here is how that gets represented in THIR (as of <!-- date-check --> October 2026):

```rust,no_run
DefId(0:3 ~ main[26fd]::main):
Thir {
body_type: Fn(
fn(),
),
attributes: {},
loop_hint_attrs: {},
// no match arms
arms: [],
blocks: [
Expand Down Expand Up @@ -224,6 +223,6 @@ Thir {
}
```

[thir-docs]: 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_middle/thir/index.html
[`thir::Expr`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/thir/struct.Expr.html
[`thir_body`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.thir_body
Loading