<commit_before># MIR construction

The lowering of [HIR] to [MIR] occurs for the following (probably incomplete)
list of items:

* Function and Closure bodies
* Initializers of `static` and `const` items
* Initializers of enum discriminants
* Glue and Shims of any kind
    * Tuple struct initializer functions
    * 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 [HAIR] that is only used during the lowering.
The [HAIR]'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 [HAIR] has datatypes that mirror the [HIR] datatypes, but instead of e.g. `-x`
being a `hair::ExprKind::Neg(hair::Expr)` it is a `hair::ExprKind::Neg(hir::Expr)`.
This shallowness enables the `HAIR` 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 [HAIR] (in
[https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir/hair/cx/expr/index.html])
and then process the [HAIR] 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)`)
produces 3 bindings, one for the argument, and two for the bindings. Next it generates
field accesses that read the fields from the argument and writes the value to the binding
variable.

With this initialization out of the way, the lowering triggers a recursive call
to a function that generates the MIR for the body (a `Block` expression) and
writes the result into the `RETURN_PLACE`.

## `unpack!` all the things

Functions that generate MIR tend to fall into one of two patterns.
First, if the function generates only statements, then it will take a
basic block as argument onto which those statements should be appended.
It can then return a result as normal:

```rust
fn generate_some_mir(&mut self, block: BasicBlock) -> ResultType {
   ...
}
```

But there are other functions that may generate new basic blocks as well.
For example, lowering an expression like `if foo { 22 } else { 44 }`
requires generating a small "diamond-shaped graph".
In this case, the functions take a basic block where their code starts
and return a (potentially) new basic block where the code generation ends.
The `BlockAnd` type is used to represent this:

```rust
fn generate_more_mir(&mut self, block: BasicBlock) -> BlockAnd<ResultType> {
    ...
}
```

When you invoke these functions, it is common to have a local variable `block`
that is effectively a "cursor". It represents the point at which we are adding new MIR.
When you invoke `generate_more_mir`, you want to update this cursor.
You can do this manually, but it's tedious:

```rust
let mut block;
let v = match self.generate_more_mir(..) {
    BlockAnd { block: new_block, value: v } => {
        block = new_block;
        v
    }
};
```

For this reason, we offer a macro that lets you write
`let v = unpack!(block = self.generate_more_mir(...))`.
It simply extracts the new block and overwrites the
variable `block` that you named in the `unpack!`.
MIR functions that generate statements always take as argument a
basic block onto which the statements should be appended.

## Lowering expressions into the desired MIR

There are essentially four kinds of representations one might want of an expression:
<commit_msg>Remove a sentence from the end of a chapter because it also appears right at the start of the chapter<commit_after># MIR construction

The lowering of [HIR] to [MIR] occurs for the following (probably incomplete)
list of items:

* Function and Closure bodies
* Initializers of `static` and `const` items
* Initializers of enum discriminants
* Glue and Shims of any kind
    * Tuple struct initializer functions
    * 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 [HAIR] that is only used during the lowering.
The [HAIR]'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 [HAIR] has datatypes that mirror the [HIR] datatypes, but instead of e.g. `-x`
being a `hair::ExprKind::Neg(hair::Expr)` it is a `hair::ExprKind::Neg(hir::Expr)`.
This shallowness enables the `HAIR` 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 [HAIR] (in
[https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir/hair/cx/expr/index.html])
and then process the [HAIR] 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)`)
produces 3 bindings, one for the argument, and two for the bindings. Next it generates
field accesses that read the fields from the argument and writes the value to the binding
variable.

With this initialization out of the way, the lowering triggers a recursive call
to a function that generates the MIR for the body (a `Block` expression) and
writes the result into the `RETURN_PLACE`.

## `unpack!` all the things

Functions that generate MIR tend to fall into one of two patterns.
First, if the function generates only statements, then it will take a
basic block as argument onto which those statements should be appended.
It can then return a result as normal:

```rust
fn generate_some_mir(&mut self, block: BasicBlock) -> ResultType {
   ...
}
```

But there are other functions that may generate new basic blocks as well.
For example, lowering an expression like `if foo { 22 } else { 44 }`
requires generating a small "diamond-shaped graph".
In this case, the functions take a basic block where their code starts
and return a (potentially) new basic block where the code generation ends.
The `BlockAnd` type is used to represent this:

```rust
fn generate_more_mir(&mut self, block: BasicBlock) -> BlockAnd<ResultType> {
    ...
}
```

When you invoke these functions, it is common to have a local variable `block`
that is effectively a "cursor". It represents the point at which we are adding new MIR.
When you invoke `generate_more_mir`, you want to update this cursor.
You can do this manually, but it's tedious:

```rust
let mut block;
let v = match self.generate_more_mir(..) {
    BlockAnd { block: new_block, value: v } => {
        block = new_block;
        v
    }
};
```

For this reason, we offer a macro that lets you write
`let v = unpack!(block = self.generate_more_mir(...))`.
It simply extracts the new block and overwrites the
variable `block` that you named in the `unpack!`.

## Lowering expressions into the desired MIR

There are essentially four kinds of representations one might want of an expression:

{'fraction_non_alphanumeric': 0.07380416059361336, 'fraction_numerical': 0.001855041738439115, 'mean_word_length': 4.469565217391304, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1744739', 'n_tokens_mistral': 2100, 'n_tokens_neox': 2012, 'n_words': 1078}