# Technical Documentation: rust-lang/rust

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/rust-lang/rust)

### Overview (README.md)

<div align="center">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/rust-lang/www.rust-lang.org/master/static/images/rust-social-wide-dark.svg">
    <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/rust-lang/www.rust-lang.org/master/static/images/rust-social-wide-light.svg">
    <img alt="The Rust Programming Language: A language empowering everyone to build reliable and efficient software"
         src="https://raw.githubusercontent.com/rust-lang/www.rust-lang.org/master/static/images/rust-social-wide-light.svg"
         width="50%">
  </picture>

[Website][Rust] | [Getting started] | [Learn] | [Documentation] | [Contributing]
</div>

This is the main source code repository for [Rust]. It contains the compiler,
standard library, and documentation.

[Rust]: https://www.rust-lang.org/
[Getting Started]: https://www.rust-lang.org/learn/get-started
[Learn]: https://www.rust-lang.org/learn
[Documentation]: https://www.rust-lang.org/learn#learn-use
[Contributing]: CONTRIBUTING.md

## Why Rust?

- **Performance:** Fast and memory-efficient, suitable for critical services, embedded devices, and easily integrated with other languages.

- **Reliability:** Our rich type system and ownership model ensure memory and thread safety, reducing bugs at compile-time.

- **Productivity:** Comprehensive documentation, a compiler committed to providing great diagnostics, and advanced tooling including package manager and build tool ([Cargo]), auto-formatter ([rustfmt]), linter ([Clippy]) and editor support ([rust-analyzer]).

[Cargo]: https://github.com/rust-lang/cargo
[rustfmt]: https://github.com/rust-lang/rustfmt
[Clippy]: https://github.com/rust-lang/rust-clippy
[rust-analyzer]: https://github.com/rust-lang/rust-analyzer

## Quick Start

Read ["Installation"] from [The Book].

["Installation"]: https://doc.rust-lang.org/book/ch01-01-installation.html
[The Book]: https://doc.rust-lang.org/book/index.html

## Installing from Source

If you really want to install from source (though this is not recommended), see
[INSTALL.md](INSTALL.md).

## Getting Help

See https://www.rust-lang.org/community for a list of chat platforms and forums.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md).

For a detailed explanation of the compiler's architecture and how to begin contributing, see the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/).

## License

Rust is primarily distributed under the terms of both the MIT license and the
Apache License (Version 2.0), with portions covered by various BSD-like
licenses.

See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and
[COPYRIGHT](COPYRIGHT) for details.

## Trademark

[The Rust Foundation][rust-foundation] owns and protects the Rust and Cargo
trademarks and logos (the "Rust Trademarks").

If you want to use these names or brands, please read the
[Rust language trademark policy][trademark-policy].

Third-party logos may be subject to third-party copyrights and trademarks. See
[Licenses][policies-licenses] for details.

[rust-foundation]: https://rustfoundation.org/
[trademark-policy]: https://rustfoundation.org/policy/rust-trademark-policy/
[policies-licenses]: https://www.rust-lang.org/policies/licenses

---

### Src Doc Index (`src/doc/index.md`)

% Rust Documentation

<style>
nav {
    display: none;
}
h3 {
    font-size: 1.35rem;
}
h4 {
    font-size: 1.1rem;
}

/* Formatting for docs search bar */
#search-input {
    width: calc(100% - 58px);
}
#search-but {
    cursor: pointer;
}
#search-but, #search-input {
    padding: 4px;
    border: 1px solid #ccc;
    border-radius: 3px;
    outline: none;
    font-size: 0.7em;
    background-color: #fff;
}
#search-but:hover, #search-input:focus {
    border-color: #55a9ff;
}

/* Formatting for external link icon */
svg.external-link {
  display: inline-block;
  position: relative;
  vertical-align: super;
  width: 0.7rem;
  height: 0.7rem;
  padding-left: 2px;
  top: 3px;
}
</style>

Welcome to an overview of the documentation provided by the [Rust
project]. This page contains links to various helpful references,
most of which are available offline (if opened with `rustup doc`). Many of these
resources take the form of "books"; we collectively call these "The Rust
Bookshelf." Some are large, some are small.

All of these books are managed by the Rust Organization, but other unofficial
documentation resources are included here as well!

If you're just looking for the standard library reference, here it is:
[Rust API documentation](std/index.html)


## Learning Rust

If you'd like to learn Rust, this is the section for you! All of these resources
assume that you have programmed before, but not in any specific language:

### The Rust Programming Language

Affectionately nicknamed "the book," [The Rust Programming Language](book/index.html)
will give you an overview of the language from first principles. You'll build a
few projects along the way, and by the end, you'll have a solid grasp of how to
use the language.

### Rust By Example

If reading multiple hundreds of pages about a language isn't your style, then
[Rust By Example](rust-by-example/index.html) has you covered. RBE shows off a
bunch of code without using a lot of words. It also includes exercises!

### Rustlings

[Rustlings](https://github.com/rust-lang/rustlings) guides you
through downloading and setting up the Rust toolchain, then provides an
interactive tool that teaches you how to solve coding challenges in Rust.

### Rust Playground

The [Rust Playground](https://play.rust-lang.org) is a great place
to try out and share small bits of code, or experiment with some of the most
popular crates.


## Using Rust

Once you've gotten familiar with the language, these resources can help you put
it to work.

### The Standard Library

Rust's standard library has [extensive API documentation](std/index.html), with
explanations of how to use various things, as well as example code for
accomplishing various tasks. Code examples have a "Run" button on hover that
opens the sample in the playground.

<div>
  <form action="std/index.html" method="get">
    <input id="search-input" type="search" name="search"
           placeholder="Search through the standard library"/>
    <button id="search-but">Search</button>
  </form>
</div>

### Your Personal Documentation

Whenever you are working in a crate, `cargo doc --open` will generate
documentation for your project _and_ all its dependencies in their correct
version, and open it in your browser. Add the flag `--document-private-items` to
also show items not marked `pub`.

### Rust Version History

[The Release Notes](releases.html) describes the change history of the Rust
toolchain and language.

[The Edition Guide](edition-guide/index.html) describes the Rust editions and
their differences. The latest version of the toolchain supports all
historical editions.

### The `rustc` Book

[The `rustc` Book](rustc/index.html) describes the Rust compiler, `rustc`.

### The Cargo Book

[The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and
dependency manager.

### The Rustdoc Book

[The Rustdoc Book](rustdoc/index.html) describes our documentation tool, `rustdoc`.

### The Clippy Book

[The Clippy Book](clippy/index.html) describes our static analyzer, Clippy.

### Extended Error Listing

Many of Rust's errors come with error codes, and you can request extended
diagnostics from the compiler on those errors (with `rustc --explain`). You can
also read them here if you prefer: [rustc error codes](error_codes/index.html)


## Mastering Rust

Once you're quite familiar with the language, you may find these advanced
resources useful.

### The Reference

[The Reference](reference/index.html) is not a formal spec, but is more detailed
and comprehensive than the book.

### The Style Guide

[The Rust Style Guide](style-guide/index.html) describes the standard formatting
of Rust code. Most developers use `cargo fmt` to invoke `rustfmt` and format the
code automatically (the result matches this style guide).

### The Rustonomicon

[The Rustonomicon](nomicon/index.html) is your guidebook to the dark arts of
unsafe Rust. It's also sometimes called "the 'nomicon."

### The Unstable Book

[The Unstable Book](unstable-book/index.html) has documentation for unstable
features.

### The `rustc` Development Guide

[The `rustc-dev-guide`](https://rustc-dev-guide.rust-lang.org/)
documents how the compiler works and how to contribute to it. This is useful if
you want to build or modify the Rust compiler from source (e.g. to target
something non-standard).


## Specialized Rust

When using Rust in specific domains, consider using the following resources
tailored to each area.

### Embedded Systems

When developing for Bare Metal or Embedded Linux systems, you may find these
resources maintained by the [Embedded Working Group] useful.

[Embedded Working Group]: https://github.com/rust-embedded

#### The Embedded Rust Book

[The Embedded Rust Book] is targeted at developers who are familiar with embedded
development and Rust, but who have not used Rust for embedded development.

[The Embedded Rust Book]: embedded-book/index.html
[Rust project]: https://www.rust-lang.org

<script>
// check if a given link is external
function isExternalLink(url) {
  const tmp = document.createElement('a');
  tmp.href = url;
  return tmp.host !== window.location.host;
}

// Add the `external` class to all <a> tags with external links and append the external link SVG
function updateExternalAnchors() {
  /*
    External link SVG from Font-Awesome
    CC BY-SA 3.0 https://creativecommons.org/licenses/by-sa/3.0
    via Wikimedia Commons
  */
  const svgText = `<svg
     class='external-link'
     xmlns='http://www.w3.org/2000/svg'
     viewBox='0 -256 1850 1850'
     width='100%'
     height='100%'>
       <g transform='matrix(1,0,0,-1,30,1427)'>
         <path d='M 1408,608 V 288 Q 1408,169 1323.5,84.5 1239,0 1120,
           0 H 288 Q 169,0 84.5,84.5 0,169 0,288 v 832 Q 0,1239 84.5,1323.5 169,
           1408 288,1408 h 704 q 14,0 23,-9 9,-9 9,-23 v -64 q 0,-14 -9,-23 -9,
           -9 -23,-9 H 288 q -66,0 -113,-47 -47,-47 -47,-113 V 288 q 0,-66 47,
           -113 47,-47 113,-47 h 832 q 66,0 113,47 47,47 47,113 v 320 q 0,14 9,
           23 9,9 23,9 h 64 q 14,0 23,-9 9,-9 9,-23 z m 384,864 V 960 q 0,
           -26 -19,-45 -19,-19 -45,-19 -26,0 -45,19 L 1507,1091 855,439 q -10,
           -10 -23,-10 -13,0 -23,10 L 695,553 q -10,10 -10,23 0,13 10,23 l 652,
           652 -176,176 q -19,19 -19,45 0,26 19,45 19,19 45,19 h 512 q 26,0 45,
           -19 19,-19 19,-45 z' style='fill:currentColor' />
         </g>
     </svg>`;
  let allAnchors = document.getElementsByTagName("a");

  for (var i = 0; i < allAnchors.length; ++i) {
    let anchor = allAnchors[i];
    if (isExternalLink(anchor.href)) {
      anchor.classList.add("external");
      anchor.innerHTML += svgText;
    }
  }
}

// on page load, update external anchors
document.addEventListener("DOMContentLoaded", updateExternalAnchors);

</script>

---

### Src Doc Intro (`src/doc/intro.md`)

% A 30-minute Introduction to Rust

This introduction is now deprecated. Please see [the introduction to the book][intro].

[intro]: book/README.html

---

### Src Doc Rustc Dev Guide README (`src/doc/rustc-dev-guide/README.md`)

[](https://github.com/rust-lang/rustc-dev-guide/actions/workflows/ci.yml)

## About the `rustc-dev-guide`

This is a collaborative effort to build a guide that explains how rustc works.
The aim of the guide is to help new contributors get oriented to rustc,
as well as to help more experienced folks in figuring out
some new part of the compiler that they haven't worked on before.

For more information, see [About This Guide](./src/about-this-guide.md).

For documentation on developing the standard library, see
[`std-dev-guide`](https://std-dev-guide.rust-lang.org/).

## Contributing to the guide

The guide is useful today, but it has a lot of work still to go.

If you'd like to help improve the guide, we'd love to have you!
You can find plenty of issues on the [issue
tracker](https://github.com/rust-lang/rustc-dev-guide/issues).
Just post a comment on the issue you would like to work on to make sure that we don't
accidentally duplicate work.
If you think something is missing, please open an issue about it!

See below for instructions on [writing new docs](#editing-the-guide).

The guide has a much lower bar for what it takes for a PR to be merged.
Check out the forge documentation for [our policy][forge_policy].

[forge_policy]: https://forge.rust-lang.org/rustc-dev-guide/index.html#review-policy

## Build Instructions

To build a local static HTML site, install [`mdbook`](https://github.com/rust-lang/mdBook) with:

```
cargo install --locked mdbook mdbook-linkcheck2 mdbook-mermaid
```

and execute the following command in the root of the repository:

```
mdbook serve --open
```

For a one-off build, you can use `mdbook build`.

### Link Validations

We use `mdbook-linkcheck2` to validate URLs included in our documentation.
Link checking is **not** run by default locally, though it is in CI.
To enable it locally, set the environment variable `ENABLE_LINKCHECK=1` like in the
following example.

```
ENABLE_LINKCHECK=1 mdbook serve
```

## Editing the guide

### Where to start

**In general, if you don't know how the compiler works, that is not a
problem!** In that case, what we will do is to schedule a bit of time
for you to talk with someone who **does** know the code, or who wants
to pair with you and figure it out.
Then you can work on writing up what you learned.

### Layout

The dev-guide is organized as a normal [mdBook](https://rust-lang.github.io/mdBook/):
It has a `src/SUMMARY.md` table of contents, which links to individual pages under `src/`.
Configuration lives in `book.toml`.
Images are in `src/img`.
The build files are found in the `book/html` directory.

**NOTE: if you do not add a page to SUMMARY.md, it will not be shown!**

### While writing

See the guide itself for instructions on [writing new docs].

[writing new docs]: src/contributing-to-guide.md

## Maintaining the guide

### CI

Various tools are kept under `ci/`.
Check links with `mdbook-linkcheck2 --standalone`.
Check semantic line breaks with `cargo run --manifest-path ci/sembr/Cargo.toml src`.
Triage `` annotations with `cargo run --manifest-path ci/date-check/Cargo.toml .`.

You can test those tools with `cargo test --manifest-path ci/<tool>/Cargo.toml`.

### Synchronizing josh subtree with rustc

This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree.
You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization.

You can find a guide on how to perform the synchronization [here](./src/external-repos.md#synchronizing-a-josh-subtree).

---

### Src Doc Rustdoc README (`src/doc/rustdoc/README.md`)

# Rustdoc

This is documentation for rustdoc itself, written in mdbook format.
To build the book, use `x.py doc src/doc/rustdoc`.
To run doctests, use `x.py test src/doc/rustdoc`.

---

### Src Doc Unstable Book README (`src/doc/unstable-book/README.md`)

# Unstable Book

These are the sources for <https://doc.rust-lang.org/nightly/unstable-book/>.
To generate them, run `./x doc unstable-book`, which will generate HTML files in `build/host/doc/unstable-book` using `src/tools/rustbook`.
If you need to change the overall structure, modify `src/tools/unstable-book-gen/src/SUMMARY.md`.

Note that most of this book is autogenerated by `unstable-book-gen`, with the exception of `compiler-flags` and `compiler-environment-variables`.
As a result, it does not integrate well with `mdbook`. Use `./x doc` instead.

---

### Src Doc Rustc Dev Guide Src Getting Started (`src/doc/rustc-dev-guide/src/getting-started.md`)

# Getting Started

Thank you for your interest in contributing to Rust!
There are many ways to contribute, and we appreciate all of them.

For general information about how to contribute to Rust,
see [Forge](https://forge.rust-lang.org/how-to-start-contributing.html).
The rest of this section is about how to contribute to the compiler specifically.

This documentation is _not_ intended to be comprehensive;
it is meant to be a quick guide for the most useful things.
For more information,
see [How to build and run the compiler](building/how-to-build-and-run.md).

## Finding help

See also ["Asking
Questions"](https://forge.rust-lang.org/how-to-start-contributing.html#asking-questions).

### Experts

Not all `t-compiler` members are experts on all parts of `rustc`;
it's a pretty large project.
To find out who could have some expertise on
different parts of the compiler, [consult triagebot assign groups][map].
The sections that start with `[assign*` in `triagebot.toml` file.
But also, feel free to ask questions even if you can't figure out who to ping.

Another way to find experts for a given part of the compiler is to see who has made recent commits.
For example, to find people who have recently worked on name resolution since the 1.68.2 release,
you could run `git shortlog -n 1.68.2.. compiler/rustc_resolve/`.
Ignore any commits starting with
"Rollup merge" or commits by `@bors` (see [CI contribution procedures](./contributing.md#ci) for
more information about these commits).

[map]: https://github.com/rust-lang/rust/blob/HEAD/triagebot.toml


## What should I work on?

The `rust` monorepo is quite large and it can be difficult to know which parts need
help, or are a good starting place for beginners.
Here are some suggested starting places.

### Easy or mentored issues

If you're looking for somewhere to start, check out the following [issue
search][help-wanted-search].
See the [Triage] for an explanation of these labels.
You can also try filtering the search to areas you're interested in.
For example:

- `label:T-compiler` will only show issues related to the compiler
- `label:A-diagnostics` will only show diagnostic issues

Not all important or beginner work has issue labels.
See below for how to find work that isn't labelled.

[help-wanted-search]: https://github.com/rust-lang/rust/issues?q=is%3Aopen%20is%3Aissue%20org%3Arust-lang%20no%3Aassignee%20label%3AE-easy%2CE-medium%2CE-help-wanted%2CE-mentor%20-label%3AS-blocked%20-linked%3Apr
[Triage]: https://forge.rust-lang.org/release/issue-triaging.html

### Recurring work

Some work is too large to be done by a single person.
In this case, it's common to have "Tracking issues" to co-ordinate the work between contributors.
Here are some example tracking issues where
it's easy to pick up work without a large time commitment:

- *Add recurring work items here.*

If you find more recurring work, please feel free to add it here!

### Diagnostic issues

Many diagnostic issues are self-contained and don't need detailed background knowledge of the
compiler.
You can see a list of diagnostic issues [here][diagnostic-issues].

[diagnostic-issues]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AA-diagnostics+no%3Aassignee

### Picking up abandoned pull requests

Sometimes, contributors send a pull request, but later find out that they don't have enough
time to work on it, or they simply are not interested in it anymore.
Such PRs are often eventually closed and they receive the `S-inactive` label.
You could try to examine some of these PRs and pick up the work.
You can find the list of such PRs [here][abandoned-prs].

If the PR has been implemented in some other way in the meantime, the `S-inactive` label
should be removed from it.
If not, and it seems that there is still interest in the change,
you can try to rebase the pull request on top of the latest `main` branch and send a new
pull request, continuing the work on the feature.

[abandoned-prs]: https://github.com/rust-lang/rust/pulls?q=is%3Apr+label%3AS-inactive+is%3Aclosed

### Writing tests

Issues that have been resolved but do not have a regression test are marked with the `E-needs-test` label.
Writing unit tests is a low-risk,
lower-priority task that offers new contributors a great opportunity to familiarize themselves
with the testing infrastructure and contribution workflow.
You can see a list of needs test issues [here][needs-test-issues].

[needs-test-issues]: https://github.com/rust-lang/rust/issues?q=is%3Aissue%20is%3Aopen%20label%3AE-needs-test%20no%3Aassignee

### Contributing to std (standard library)

See [std-dev-guide](https://std-dev-guide.rust-lang.org/).

### Other ways to contribute

See [Forge](https://forge.rust-lang.org/how-to-start-contributing.html#how-to-start-contributing-1).

## Cloning and Building

See ["How to build and run the compiler"](./building/how-to-build-and-run.md).

## Bug fixes or "normal" code changes

For most PRs, no special procedures are needed.
You can just [open a PR], and it will be reviewed, approved, and merged.
This includes most bug fixes, refactorings, and other user-invisible changes.
The next few sections talk about exceptions to this rule.

Also, note that it is perfectly acceptable to open WIP PRs or GitHub [Draft PRs].
Some people prefer to do this so they can get feedback along the
way or share their code with a collaborator.
Others do this so they can utilize
the CI to build and test their PR (e.g. when developing on a slow machine).

[open a PR]: git.md#opening-a-pr
[Draft PRs]: https://github.blog/2019-02-14-introducing-draft-pull-requests/

## Pull requests

Pull requests (or PRs for short) are the primary mechanism we use to change Rust.
GitHub itself has some [great documentation][about-pull-requests] on using the Pull Request feature.
We use the ["fork and pull" model][development-models],
where contributors push changes to their personal fork and create pull requests to
bring those changes into the source repository.
We have [a chapter](git.md) on how to use Git when contributing to Rust.

> **Advice for potentially large, complex, cross-cutting and/or very domain-specific changes**
>
> The compiler reviewers on rotation usually each have areas of the compiler that they know well,
> but also have areas that they are not very familiar with. If your PR contains changes that are
> large, complex, cross-cutting and/or highly domain-specific, it becomes very difficult to find a
> suitable reviewer who is comfortable in reviewing all of the changes in such a PR. This is also
> true if the changes are not only compiler-specific but also contain changes which fall under the
> purview of reviewers from other teams, like the standard library team. [There's a bot][triagebot]
> which notifies the relevant teams and pings people who have set up specific alerts based on the
> files modified.
>
> Before making such changes, you are strongly encouraged to **discuss your proposed changes with
> the compiler team beforehand** (and with other teams that the changes would require approval
> from), and work with the compiler team to see if we can help you **break down a large potentially
> unreviewable PR into a series of smaller more individually reviewable PRs**.
>
> You can communicate with the compiler team by creating a [#t-compiler thread on Zulip][t-compiler]
> to discuss your proposed changes.
>
> Communicating with the compiler team beforehand helps in several ways:
>
> 1. It increases the likelihood of your PRs being reviewed in a timely manner.
>     - We can help you identify suitable reviewers *before* you open actual PRs, or help find
>       advisors and liaisons to help you navigate the change procedures, or help with running
>       try-jobs, perf runs and crater runs as suitable.
> 2. It helps the compiler team track your changes.
> 3. The compiler team can perform vibe checks on your changes early and often, to see if the
>    direction of the changes align with what the compiler team prefers to see.
> 4. Helps to avoid situations where you may have invested significant time and effort into large
>   changes that the compiler team might not be willing to accept, or finding out very late that the
>   changes are in a direction that the compiler team disagrees with.

[about-pull-requests]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests
[development-models]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/getting-started/about-collaborative-development-models#fork-and-pull-model
[t-compiler]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler
[triagebot]: https://github.com/rust-lang/rust/blob/HEAD/triagebot.toml

## Issue triage

Please see <https://forge.rust-lang.org/release/issue-triaging.html>.

## Other Resources

This section has moved to the ["About this guide"][more-links] chapter.

[more-links]: ./about-this-guide.md#other-places-to-find-information

---

### Src Doc Rustc Dev Guide Src Overview (`src/doc/rustc-dev-guide/src/overview.md`)

# Overview of the compiler

This chapter is about the overall process of compiling a program -- how everything fits together.

The Rust compiler is special in two ways: it does things to your code that
other compilers don't do (e.g. borrow-checking) and it has a lot of
unconventional implementation choices (e.g. queries).
We will talk about these in turn in this chapter, and in the rest of the guide, we will look at the
individual pieces in more detail.

## What the compiler does to your code

So first, let's look at what the compiler does to your code.
For now, we will avoid mentioning how the compiler implements these steps except as needed.

### Invocation

Compilation begins when a user writes a Rust source program in text and invokes
the `rustc` compiler on it.
The work that the compiler needs to perform is defined by command-line options.
For example, it is possible to enable nightly
features (`-Z` flags), perform `check`-only builds, or emit the LLVM
Intermediate Representation (`LLVM-IR`) rather than executable machine code.
The `rustc` executable call may be indirect through the use of `cargo`.

Command line argument parsing occurs in the [`rustc_driver`].
This crate defines the compile configuration that is requested by the user and passes it
to the rest of the compilation process as a [`rustc_interface::Config`].

### Lexing and parsing

The raw Rust source text is analyzed by a low-level *lexer* located in [`rustc_lexer`].
At this stage, the source text is turned into a stream of
atomic source code units known as _tokens_.
 The `lexer` supports the Unicode character encoding.

The token stream passes through a higher-level lexer located in
[`rustc_parse`] to prepare for the next stage of the compile process.
The [`Lexer`] `struct` is used at this stage to perform a set of validations
and turn strings into interned symbols (_interning_ is discussed later).
[String interning] is a way of storing only one immutable copy of each distinct string value.

The lexer has a small interface and doesn't depend directly on the diagnostic
infrastructure in `rustc`.
Instead it provides diagnostics as plain data which
are emitted in [`rustc_parse::lexer`] as real diagnostics.
The `lexer` preserves full fidelity information for both IDEs and procedural macros
(sometimes referred to as "proc-macros").

The *parser* [translates the token stream from the `lexer` into an Abstract Syntax
Tree (AST)][parser].
It uses a recursive descent (top-down) approach to syntax analysis.
The crate entry points for the `parser` are the
[`Parser::parse_crate_mod`][parse_crate_mod] and [`Parser::parse_mod`][parse_mod]
methods found in [`rustc_parse::parser::Parser`].
The external module parsing
entry point is [`rustc_expand::module::parse_external_mod`][parse_external_mod].
And the macro-`parser` entry point is [`Parser::parse_nonterminal`][parse_nonterminal].

Parsing is performed with a set of [`parser`] utility methods including [`bump`],
[`check`], [`eat`], [`expect`], [`look_ahead`].

Parsing is organized by semantic construct.
Separate `parse_*` methods can be found in the [`rustc_parse`][rustc_parse_parser_dir] directory.
The source file name follows the construct name.
For example, the following files are found in the `parser`:

- [`expr.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_parse/src/parser/expr.rs)
- [`pat.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_parse/src/parser/pat.rs)
- [`ty.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_parse/src/parser/ty.rs)
- [`stmt.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_parse/src/parser/stmt.rs)

This naming scheme is used across many compiler stages.
You will find either a file or directory with the same name across the parsing, lowering, type
checking, [Typed High-level Intermediate Representation (`THIR`)][thir] lowering, and
[Mid-level Intermediate Representation (`MIR`)][mir] building sources.

Macro-expansion, `AST`-validation, name-resolution, and early linting also take
place during the lexing and parsing stage.

The [`rustc_ast::ast`]::{[`Crate`], [`Expr`], [`Pat`], ...} `AST` nodes are
returned from the parser while the standard [`Diag`] API is used for error handling.
Generally Rust's compiler will try to recover from errors
by parsing a superset of Rust's grammar, while also emitting an error type.

### `AST` lowering

Next the `AST` is converted into [High-Level Intermediate Representation
(`HIR`)][hir], a more compiler-friendly representation of the `AST`.
This process is called "lowering" and involves a lot of desugaring (the expansion and
formalizing of shortened or abbreviated syntax constructs) of things like loops and `async fn`.

We then use the `HIR` to do [*type inference*] (the process of automatic
detection of the type of an expression), [*trait solving*] (the process of
pairing up an impl with each reference to a `trait`), and [*type checking*].
Type checking is the process of converting the types found in the `HIR` ([`hir::Ty`]),
which represent what the user wrote, into the internal representation used by
the compiler ([`Ty<'tcx>`]).
It's called type checking because the information
is used to verify the type safety, correctness and coherence of the types used in the program.

### `MIR` lowering

The `HIR` is further lowered to `MIR`
(used for [borrow checking]) by constructing the `THIR`  (an even more desugared `HIR` used for
pattern and exhaustiveness checking) to convert into `MIR`.

We do [many optimizations on the MIR][mir-opt] because it is generic and that
improves later code generation and compilation speed.
It is easier to do some optimizations at `MIR` level than at `LLVM-IR` level.
For example LLVM doesn't seem
to be able to optimize the pattern the [`simplify_try`] `MIR`-opt looks for.

Rust code is also [_monomorphized_] during code generation, which means making
copies of all the generic code with the type parameters replaced by concrete types.
To do this, we need to collect a list of what concrete types to generate code for.
This is called _monomorphization collection_ and it happens at the `MIR` level.

[_monomorphized_]: https://en.wikipedia.org/wiki/Monomorphization

### Code generation

We then begin what is simply called _code generation_ or _codegen_.
The [code generation stage][codegen] is when higher-level representations of source are
turned into an executable binary.
Since `rustc` uses LLVM for code generation,
the first step is to convert the `MIR` to `LLVM-IR`.
This is where the `MIR` is actually monomorphized.
The `LLVM-IR` is passed to LLVM, which does a lot more
optimizations on it, emitting machine code which is basically assembly code
with additional low-level types and annotations added (e.g. an ELF object or
`WASM`).
The different libraries/binaries are then linked together to produce the final binary.

[*trait solving*]: traits/resolution.md
[*type checking*]: hir-typeck/summary.md
[*type inference*]: type-inference.md
[`bump`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.bump
[`check`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.check
[`Crate`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_ast/ast/struct.Crate.html
[`diag`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html
[`eat`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.eat
[`expect`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.expect
[`Expr`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_ast/ast/struct.Expr.html
[`hir::Ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Ty.html
[`look_ahead`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.look_ahead
[`Parser`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html
[`Pat`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_ast/ast/struct.Pat.html
[`rustc_ast::ast`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_ast/index.html
[`rustc_driver`]: rustc-driver/intro.md
[`rustc_interface::Config`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Config.html
[`rustc_lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lexer/index.html
[`rustc_parse::lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/index.html
[`rustc_parse::parser::Parser`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html
[`rustc_parse`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
[`simplify_try`]: https://github.com/rust-lang/rust/pull/66282
[`Lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html
[`Ty<'tcx>`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
[borrow checking]: borrow-check.md
[codegen]: backend/codegen.md
[hir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/index.html
[lex]: the-parser.md
[mir-opt]: mir/optimizations.md
[mir]: mir/index.md
[parse_crate_mod]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.parse_crate_mod
[parse_external_mod]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/module/fn.parse_external_mod.html
[parse_mod]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.parse_mod
[parse_nonterminal]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.parse_nonterminal
[parser]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
[rustc_parse_parser_dir]: https://github.com/rust-lang/rust/tree/HEAD/compiler/rustc_parse/src/parser
[String interning]: https://en.wikipedia.org/wiki/String_interning
[thir]: ./thir.md

## How it does it

Now that we have a high-level view of what the compiler does to your code,
let's take a high-level view of _how_ it does all that stuff.
There are a lot of constraints and conflicting goals that the compiler needs to
satisfy/optimize for.
For example,

- Compilation speed: how fast is it to compile a program?
  More/better compile-time analyses often means compilation is slower.
  - Also, we want to support incremental compilation, so we need to take that into account.
    How can we keep track of what work needs to be redone and
    what can be reused if the user modifies their program?
    - Also we can't store too much stuff in the incremental cache because
      it would take a long time to load from disk and it could take a lot
      of space on the user's system...
- Compiler memory usage: while compiling a program, we don't want to use more memory than we need.
- Program speed: how fast is your compiled program?
  More/better compile-time analyses often means the compiler can do better optimizations.
- Program size: how large is the compiled binary?
  Similar to the previous point.
- Compiler compilation speed: how long does it take to compile the compiler?
  This impacts contributors and compiler maintenance.
- Implementation complexity: building a compiler is one of the hardest
  things a person/group can do, and Rust is not a very simple language, so how
  do we make the compiler's code base manageable?
- Compiler correctness: the binaries produced by the compiler should do what
  the input programs says they do, and should continue to do so despite the
  tremendous amount of change constantly going on.
- Integration: a number of other tools need to use the compiler in
  various ways (e.g. `cargo`, `clippy`, `Miri`) that must be supported.
- Compiler stability: the compiler should not crash or fail ungracefully on the stable channel.
- Rust stability: the compiler must respect Rust's stability guarantees by not
  breaking programs that previously compiled despite the many changes that are
  always going on to its implementation.
- Limitations of other tools: `rustc` uses LLVM in its backend, and LLVM has some
  strengths we leverage and some aspects we need to work around.

So, as you continue your journey through the rest of the guide, keep these things in mind.
They will often inform decisions that we make.

### Intermediate representations

As with most compilers, `rustc` uses some intermediate representations (IRs) to
facilitate computations.
In general, working directly with the source code is extremely inconvenient and error-prone.
Source code is designed to be human-friendly while at
the same time being unambiguous, but it's less convenient for doing something
like, say, type checking.

Instead most compilers, including `rustc`, build some sort of IR out of the
source code which is easier to analyze.
`rustc` has a few IRs, each optimized for different purposes:

- Token stream: the lexer produces a stream of tokens directly from the source code.
  This stream of tokens is easier for the parser to deal with than raw text.
- Abstract Syntax Tree (`AST`): the abstract syntax tree is built from the stream
  of tokens produced by the lexer.
  It represents pretty much exactly what the user wrote.
  It helps to do some syntactic sanity
  checking (e.g. checking that a type is expected where the user wrote one).
- High-level IR (HIR): This is a sort of desugared `AST`.
  It's still close to what the user wrote syntactically, but it includes some implicit things
  such as some elided lifetimes, etc. This IR is amenable to type checking.
- Typed `HIR` (THIR) _formerly High-level Abstract IR (HAIR)_: This is an
  intermediate between `HIR` and MIR.
  It is like the `HIR` but it is fully typed
  and a bit more desugared (e.g. method calls and implicit dereferences are
  made fully explicit).
  As a result, it is easier to lower to `MIR` from `THIR`  than from HIR.
- Middle-level IR (`MIR`): This IR is basically a Control-Flow Graph (CFG).
  A CFG is a type of diagram that shows the basic blocks of a program and how control
  flow can go between them.
  Likewise, `MIR` also has a bunch of basic blocks with
  simple typed statements inside them (e.g. assignment, simple computations,
  etc) and control flow edges to other basic blocks (e.g., calls, dropping
  values).
  `MIR` is used for borrow checking and other
  important dataflow-based checks, such as checking for uninitialized values.
  It is also used for a series of optimizations and for constant evaluation (via `Miri`).
  Because `MIR` is still generic, we can do a lot of analyses here more
  efficiently than after monomorphization.
- `LLVM-IR`: This is the standard form of all input to the LLVM compiler.
  `LLVM-IR` is a sort of typed assembly language with lots of annotations.
  It's
  a standard format that is used by all compilers that use LLVM (e.g. the clang
  C compiler also outputs `LLVM-IR`).
  `LLVM-IR` is designed to be easy for other
  compilers to emit and also rich enough for LLVM to run a bunch of optimizations on it.

One other thing to note is that many values in the compiler are _interned_.
This is a performance and memory optimization in which we allocate the values in
a special allocator called an _[arena]_.
Then, we pass around references to the values allocated in the arena.
This allows us to make
sure that identical values (e.g. types in your program) are only allocated once
and can be compared cheaply by comparing pointers.
Many of the intermediate representations are interned.

[arena]: https://en.wikipedia.org/wiki/Region-based_memory_management

### Queries

The first big implementation choice is Rust's use of the _query_ system in its compiler.
The Rust compiler _is not_ organized as a series of passes over the code which execute sequentially.
The Rust compiler does this to make
incremental compilation possible -- that is, if the user makes a change to
their program and recompiles, we want to do as little redundant work as
possible to output the new binary.

In `rustc`, all the major steps above are organized as a bunch of queries that call each other.
For example, there is a query to ask for the type of something
and another to ask for the optimized `MIR` of a function.
These queries can call each other and are all tracked through the query system.
The results of the queries are cached on disk so that the compiler can tell which queries' results
changed from the last compilation and only redo those.
This is how incremental compilation works.

In principle, for the query-fied steps, we do each of the above for each item individually.
For example, we will take the `HIR` for a function and use queries
to ask for the `LLVM-IR` for that HIR.
This drives the generation of optimized
`MIR`, which drives the borrow checker, which drives the generation of `MIR`, and so on.

... except that this is very over-simplified.
In fact, some queries are not
cached on disk, and some parts of the compiler have to run for all code anyway
for correctness even if the code is dead code (e.g. the borrow checker). For
example, [currently the `mir_borrowck` query is first executed on all functions
of a crate.][passes] Then the codegen backend invokes the
`collect_and_partition_mono_items` query, which first recursively requests the
`optimized_mir` for all reachable functions, which in turn runs `mir_borrowck`
for that function and then creates codegen units.
This kind of split will need
to remain to ensure that unreachable functions still have their errors emitted.

[passes]: https://github.com/rust-lang/rust/blob/e69c7306e2be08939d95f14229e3f96566fb206c/compiler/rustc_interface/src/passes.rs#L791

Moreover, the compiler wasn't originally built to use a query system; the query
system has been retrofitted into the compiler, so parts of it are not query-fied yet.
Also, LLVM isn't our code, so that isn't querified either.
The plan is to eventually query-fy all of the steps listed in the previous section,
but as of  November 2022, only the steps between `HIR` and
`LLVM-IR` are query-fied.
That is, lexing, parsing, name resolution, and macro
expansion are done all at once for the whole program.

One other thing to mention here is the all-important "typing context",
[`TyCtxt`], which is a giant struct that is at the center of all things.
(Note that the name is mostly historic.
This is _not_ a "typing context" in the sense of `Γ` or `Δ` from type theory.
The name is retained because that's what the name of the struct is in the source code.) All
queries are defined as methods on the [`TyCtxt`] type, and the in-memory query
cache is stored there too.
In the code, there is usually a variable called `tcx` which is a handle on the typing context.
You will also see lifetimes with
the name `'tcx`, which means that something is tied to the lifetime of the
[`TyCtxt`] (usually it is stored or interned there).

[`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html

For more information about queries in the compiler, see [the queries chapter][queries].

[queries]: ./query.md

### `ty::Ty`

Types are really important in Rust, and they form the core of a lot of compiler analyses.
The main type (in the compiler) that represents types (in the user's
program) is [`rustc_middle::ty::Ty`][ty].
This is so important that we have a whole chapter
on [`ty::Ty`][ty], but for now, we just want to mention that it exists and is the way
`rustc` represents types!

Also note that the [`rustc_middle::ty`] module defines the [`TyCtxt`] struct we mentioned before.

[ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
[`rustc_middle::ty`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_middle/ty/index.html

### Parallelism

Compiler performance is a problem that we would like to improve on (and are always working on).
One aspect of that is parallelizing `rustc` itself.

Currently, there is only one part of rustc that is parallel by default:
[code generation](./parallel-rustc.md#Codegen).

However, the rest of the compiler is still not yet parallel.
There have been lots of efforts spent on this, but it is generally a hard problem.
The current approach is to turn [`RefCell`]s into [`Mutex`]s -- that is, we
switch to thread-safe internal mutability.
However, there are ongoing
challenges with lock contention, maintaining query-system invariants under
concurrency, and the complexity of the code base.
One can try out the current work by enabling parallel compilation in `bootstrap.toml`.
It's still early days,
but there are already some promising performance improvements.

[`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
[`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html

### Bootstrapping

`rustc` itself is written in Rust.
So how do we compile the compiler? We use an older compiler to compile the newer compiler.
This is called [_bootstrapping_].

Bootstrapping has a lot of interesting implications.
For example, it means that one of the major users of Rust is the Rust compiler, so we are
constantly testing our own software ("eating our own dogfood").

For more details on bootstrapping, see [the bootstrapping section of the guide][rustc-bootstrap].

[_bootstrapping_]: https://en.wikipedia.org/wiki/Bootstrapping_(compilers)
[rustc-bootstrap]: building/bootstrapping/intro.md



# References

- Command line parsing
  - Guide: [The Rustc Driver and Interface](rustc-driver/intro.md)
  - Driver definition: [`rustc_driver`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/)
  - Main entry point: [`rustc_session::config::build_session_options`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/config/fn.build_session_options.html)
- Lexical Analysis: Lex the user program to a stream of tokens
  - Guide: [Lexing and Parsing](the-parser.md)
  - Lexer definition: [`rustc_lexer`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lexer/index.html)
  - Main entry point: [`rustc_lexer::Cursor::advance_token`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lexer/struct.Cursor.html#method.advance_token)
- Parsing: Parse the stream of tokens to an Abstract Syntax Tree (AST)
  - Guide: [Lexing and Parsing](the-parser.md)
  - Guide: [Macro Expansion](macro-expansion.md)
  - Guide: [Name Resolution](name-resolution.md)
  - Parser definition: [`rustc_parse`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html)
  - Main entry points:
    - [Entry point for first file in crate](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/passes/fn.parse.html)
    - [Entry point for outline module parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/module/fn.parse_external_mod.html)
    - [Entry point for macro fragments][parse_nonterminal]
  - `AST` definition: [`rustc_ast`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/index.html)
  - Feature gating: [Feature Gate Checking](feature-gate-check.md)
  - Early linting: **TODO**
- The High Level Intermediate Representation (HIR)
  - Guide: [The HIR](hir.md)
  - Guide: [Identifiers in the HIR](hir.md#identifiers-in-the-hir)
  - Guide: [The `HIR` Map](hir.md#the-hir-map)
  - Guide: [Lowering `AST` to `HIR`](./hir/lowering.md)
  - How to view `HIR` representation for your code `cargo rustc -- -Z unpretty=hir-tree`
  - Rustc `HIR` definition: [`rustc_hir`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/index.html)
  - Main entry point: **TODO**
  - Late linting: **TODO**
- Type Inference
  - Guide: [Type Inference](type-inference.md)
  - Guide: [The ty Module: Representing Types](ty.md) (semantics)
  - Main entry point (type inference): [`InferCtxtBuilder::enter`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxtBuilder.html#method.enter)
  - Main entry point (type checking bodies): [the `typeck` query](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.typeck)
    - These two functions can't be decoupled.
- The Mid Level Intermediate Representation (MIR)
  - Guide: [The `MIR` (Mid level IR)](mir/index.md)
  - Definition: [`rustc_middle/src/mir`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/index.html)
  - Definition of sources that manipulates the MIR: [`rustc_mir_build`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/index.html), [`rustc_mir_dataflow`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/index.html), [`rustc_mir_transform`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/index.html)
- The Borrow Checker
  - Guide: [MIR Borrow Check](borrow-check.md)
  - Definition: [`rustc_borrowck`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/index.html)
  - Main entry point: [`mir_borrowck` query](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/fn.mir_borrowck.html)
- `MIR` Optimizations
  - Guide: [MIR Optimizations](mir/optimizations.md)
  - Definition: [`rustc_mir_transform`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/index.html)
  - Main entry point: [`optimized_mir` query](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/fn.optimized_mir.html)
- Code Generation
  - Guide: [Code Generation](backend/codegen.md)
  - Generating Machine Code from `LLVM-IR` with LLVM - **TODO: reference?**
  - Main entry point: [`rustc_codegen_ssa::base::codegen_crate`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/fn.codegen_crate.html)
    - This monomorphizes and produces `LLVM-IR` for one codegen unit.
      It then starts a background thread to run LLVM, which must be joined later.
    - Monomorphization happens lazily via [`FunctionCx::monomorphize`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/struct.FunctionCx.html#method.monomorphize) and [`rustc_codegen_ssa::base::codegen_instance `](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/fn.codegen_instance.html)

---

### Src Doc Rustc Dev Guide Src Part 2 Intro (`src/doc/rustc-dev-guide/src/part-2-intro.md`)

# High-Level Compiler Architecture

The remaining parts of this guide discuss how the compiler works. They go
through everything from high-level structure of the compiler to how each stage
of compilation works. They should be friendly to both readers interested in the
end-to-end process of compilation _and_ readers interested in learning about a
specific system they wish to contribute to. If anything is unclear, feel free
to file an issue on the [rustc-dev-guide
repo](https://github.com/rust-lang/rustc-dev-guide/issues) or contact the compiler
team, as detailed in [this chapter from Part 1](./compiler-team.md).

In this part, we will look at the high-level architecture of the compiler. In
particular, we will look at three overarching design choices that impact the
whole compiler: the query system, incremental compilation, and interning.

---

### Src Doc Rustc Dev Guide Src Part 3 Intro (`src/doc/rustc-dev-guide/src/part-3-intro.md`)

# Source Code Representation

This part describes the process of taking raw source code from the user and
transforming it into various forms that the compiler can work with easily.
These are called _intermediate representations (IRs)_.

This process starts with compiler understanding what the user has asked for:
parsing the command line arguments given and determining what it is to compile.
After that, the compiler transforms the user input into a series of IRs that
look progressively less like what the user wrote.

---

### Src Doc Rustc Dev Guide Src Part 4 Intro (`src/doc/rustc-dev-guide/src/part-4-intro.md`)

# Analysis

This part discusses the many analyses that the compiler uses to check various
properties of the code and to inform later stages.
Typically, this is what people mean when they talk about "Rust's type system".
This includes the representation, inference, and checking of types, the trait system, and the
borrow checker.
These analyses do not happen as one big pass or set of contiguous passes.
Rather, they are spread out throughout various parts of the
compilation process and use different intermediate representations.
For example,
type checking happens on the HIR, while borrow checking happens on the MIR.
Nonetheless, for the sake of presentation, we will discuss all of these
analyses in this part of the guide.

---

### Src Doc Rustc Dev Guide Src Part 5 Intro (`src/doc/rustc-dev-guide/src/part-5-intro.md`)

# From MIR to binaries

All of the preceding chapters of this guide have one thing in common:
we never generated any executable machine code at all!
With this chapter, all of that changes.

So far,
we've shown how the compiler can take raw source code in text format
and transform it into [MIR].
We have also shown how the compiler does various
analyses on the code to detect things like type or lifetime errors.
Now, we will finally take the MIR and produce some executable machine code.

[MIR]: ./mir/index.md

> NOTE: This part of a compiler is often called the _backend_.
> The term is a bit overloaded because in the compiler source,
> it usually refers to the "codegen backend" (i.e. LLVM, Cranelift, or GCC).
> Usually, when you see the word "backend"  in this part,
> we are referring to the "codegen backend".

So what do we need to do?

1. First, we need to collect the set of things to generate code for.
   In particular,
   we need to find out which concrete types to substitute for generic ones,
   since we need to generate code for the concrete types.
   Generating code for the concrete types
   (i.e. emitting a copy of the code for each concrete type) is called _monomorphization_,
   so the process of collecting all the concrete types is called _monomorphization collection_.
2. Next, we need to actually lower the MIR to a codegen IR
   (usually LLVM IR) for each concrete type we collected.
3. Finally, we need to invoke the codegen backend,
   which runs a bunch of optimization passes,
   generates executable code,
   and links together an executable binary.

[codegen1]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/fn.codegen_crate.html

The code for codegen is actually a bit complex due to a few factors:

- Support for multiple codegen backends (LLVM, Cranelift, and GCC).
  We try to share as much backend code between them as possible,
  so a lot of it is generic over the codegen implementation.
  This means that there are often a lot of layers of abstraction.
- Codegen happens asynchronously in another thread for performance.
- The actual codegen is done by a third-party library (either of the 3 backends).

Generally, the [`rustc_codegen_ssa`][ssa] crate contains backend-agnostic code,
while the [`rustc_codegen_llvm`][llvm] crate contains code specific to LLVM codegen.

[ssa]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/index.html
[llvm]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_llvm/index.html

At a very high level, the entry point is
[`rustc_codegen_ssa::base::codegen_crate`][codegen1].
This function starts the process discussed in the rest of this chapter.

---

### Src Doc Rustc Dev Guide Src Syntax Intro (`src/doc/rustc-dev-guide/src/syntax-intro.md`)

# Syntax and the AST

Working directly with source code is very inconvenient and error-prone.
Thus, before we do anything else, we convert raw source code into an
[Abstract Syntax Tree (AST)][AST].
It turns out that doing this involves a lot of work,
including [lexing, parsing], [macro expansion], [name resolution], conditional
compilation, [feature-gate checking], and [validation] of the [AST].
In this chapter, we take a look at all of these steps.

Notably, there isn't always a clean ordering between these tasks.
For example, macro expansion relies on name resolution to resolve the names of macros and imports.
And parsing requires macro expansion, which in turn may require parsing the output of the macro.

[AST]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
[macro expansion]: ./macro-expansion.md
[feature-gate checking]: ./feature-gate-check.md
[lexing, parsing]: ./the-parser.md
[name resolution]: ./name-resolution.md
[validation]: ./ast-validation.md

---

### Src Doc Style Guide Src README (`src/doc/style-guide/src/README.md`)

# Rust Style Guide

## Motivation - why use a formatting tool?

Formatting code is a mostly mechanical task which takes both time and mental
effort. By using an automatic formatting tool, a programmer is relieved of
this task and can concentrate on more important things.

Furthermore, by sticking to an established style guide (such as this one),
programmers don't need to formulate ad hoc style rules, nor do they need to
debate with other programmers what style rules should be used, saving time,
communication overhead, and mental energy.

Humans comprehend information through pattern matching. By ensuring that all
Rust code has similar formatting, less mental effort is required to comprehend a
new project, lowering the barrier to entry for new developers.

Thus, there are productivity benefits to using a formatting tool (such as
`rustfmt`), and even larger benefits by using a community-consistent
formatting, typically by using a formatting tool's default settings.

## The default Rust style

The Rust Style Guide defines the default Rust style, and *recommends* that
developers and tools follow the default Rust style. Tools such as `rustfmt` use
the style guide as a reference for the default style. Everything in this style
guide, whether or not it uses language such as "must" or the imperative mood
such as "insert a space ..." or "break the line after ...", refers to the
default style.

This should not be interpreted as forbidding developers from following a
non-default style, or forbidding tools from adding any particular configuration
options.

## Bugs

If the style guide differs from rustfmt, that may represent a bug in rustfmt,
or a bug in the style guide; either way, please report it to the style team or
the rustfmt team or both, for investigation and fix.

If implementing a new formatting tool based on the style guide and default Rust
style, please test it on the corpus of existing Rust code, and avoid causing
widespread breakage. The implementation and testing of such a tool may surface
bugs in either the style guide or rustfmt, as well as bugs in the tool itself.

We typically resolve bugs in a fashion that avoids widespread breakage.

## Formatting conventions

### Indentation and line width

- Use spaces, not tabs.
- Each level of indentation must be 4 spaces (that is, all indentation
  outside of string literals and comments must be a multiple of 4).
- The maximum width for a line is 100 characters.

#### Block indent

Prefer block indent over visual indent:

```rust
// Block indent
a_function_call(
    foo,
    bar,
);

// Visual indent
a_function_call(foo,
                bar);
```

This makes for smaller diffs (e.g., if `a_function_call` is renamed in the above
example) and less rightward drift.

### Trailing commas

In comma-separated lists of any kind, use a trailing comma when followed by a
newline:

```rust
function_call(
    argument,
    another_argument,
);

let array = [
    element,
    another_element,
    yet_another_element,
];
```

This makes moving code (e.g., by copy and paste) easier, and makes diffs
smaller, as appending or removing items does not require modifying another line
to add or remove a comma.

### Blank lines

Separate items and statements by either zero or one blank lines (i.e., one or
two newlines). E.g,

```rust
fn foo() {
    let x = ...;

    let y = ...;
    let z = ...;
}

fn bar() {}
fn baz() {}
```

### Trailing whitespace

Do not include trailing whitespace on the end of any line. This includes blank
lines, comment lines, code lines, and string literals.

Note that avoiding trailing whitespace in string literals requires care to
preserve the value of the literal.

### Sorting

In various cases, the default Rust style specifies to sort things. If not
otherwise specified, such sorting should be "version sorting", which ensures
that (for instance) `x8` comes before `x16` even though the character `1` comes
before the character `8`.

For the purposes of the Rust style, to compare two strings for version-sorting:

- Process both strings from beginning to end as two sequences of maximal-length
  chunks, where each chunk consists either of a sequence of characters other
  than ASCII digits, or a sequence of ASCII digits (a numeric chunk), and
  compare corresponding chunks from the strings.
- To compare two numeric chunks, compare them by numeric value, ignoring
  leading zeroes. If the two chunks have equal numeric value, but different
  numbers of leading digits, and this is the first time this has happened for
  these strings, treat the chunks as equal (moving on to the next chunk) but
  remember which string had more leading zeroes.
- To compare two chunks if both are not numeric, compare them by Unicode
  character lexicographically, with two exceptions:
  - `_` (underscore) sorts immediately after ` ` (space) but before any other
    character. (This treats underscore as a word separator, as commonly used in
    identifiers.)
  - Unless otherwise specified, version-sorting should sort non-lowercase
    characters (characters that can start an `UpperCamelCase` identifier)
    before lowercase characters.
- If the comparison reaches the end of the string and considers each pair of
  chunks equal:
  - If one of the numeric comparisons noted the earliest point at which one
    string had more leading zeroes than the other, sort the string with more
    leading zeroes first.
  - Otherwise, the strings are equal.

Note that there exist various algorithms called "version sorting", which
generally try to solve the same problem, but which differ in various ways (such
as in their handling of numbers with leading zeroes). This algorithm
does not purport to precisely match the behavior of any particular other
algorithm, only to produce a simple and satisfying result for Rust formatting.
In particular, this algorithm aims to produce a satisfying result for a set of
symbols that have the same number of leading zeroes, and an acceptable and
easily understandable result for a set of symbols that has varying numbers of
leading zeroes.

As an example, version-sorting will sort the following strings in the order
given:
- `_ZYXW`
- `_abcd`
- `A2`
- `ABCD`
- `Z_YXW`
- `ZY_XW`
- `ZY_XW`
- `ZYXW`
- `ZYXW_`
- `a1`
- `abcd`
- `u_zzz`
- `u8`
- `u16`
- `u32`
- `u64`
- `u128`
- `u256`
- `ua`
- `usize`
- `uz`
- `v000`
- `v00`
- `v0`
- `v0s`
- `v00t`
- `v0u`
- `v001`
- `v01`
- `v1`
- `v009`
- `v09`
- `v9`
- `v010`
- `v10`
- `w005s09t`
- `w5s009t`
- `x64`
- `x86`
- `x86_32`
- `x86_64`
- `x86_128`
- `x87`
- `zyxw`

### [Module-level items](items.md)

### [Statements](statements.md)

### [Expressions](expressions.md)

### [Types](types.md)

### Comments

The following guidelines for comments are recommendations only, a mechanical
formatter might skip formatting of comments.

Prefer line comments (`//`) to block comments (`/* ... */`).

When using line comments, put a single space after the opening sigil.

When using single-line block comments, put a single space after the opening
sigil and before the closing sigil. For multi-line block comments, put a
newline after the opening sigil, and a newline before the closing sigil.

Prefer to put a comment on its own line. Where a comment follows code, put a
single space before it. Where a block comment appears inline, use surrounding
whitespace as if it were an identifier or keyword.

Examples:

```rust
// A comment on an item.
struct Foo { ... }

fn foo() {} // A comment after an item.

pub fn foo(/* a comment before an argument */ x: T) {...}
```

Comments should usually be complete sentences. Start with a capital letter, end
with a period (`.`). An inline block comment may be treated as a note without
punctuation.

Source lines which are entirely a comment should be limited to 80 characters
in length (including comment sigils, but excluding indentation) or the maximum
width of the line (including comment sigils and indentation), whichever is
smaller:

```rust
// This comment goes up to the ................................. 80 char margin.

{
    // This comment is .............................................. 80 chars wide.
}

{
    {
        {
            {
                {
                    {
                        // This comment is limited by the ......................... 100 char margin.
                    }
                }
            }
        }
    }
}
```

#### Doc comments

Prefer line comments (`///`) to block comments (`/** ... */`).

Prefer outer doc comments (`///` or `/** ... */`), only use inner doc comments
(`//!` and `/*! ... */`) to write module-level or crate-level documentation.

Put doc comments before attributes.

### Attributes

Put each attribute on its own line, indented to the level of the item.
In the case of inner attributes (`#!`), indent it to the level of the inside of
the item. Prefer outer attributes, where possible.

For attributes with argument lists, format like functions.

```rust
#[repr(C)]
#[foo(foo, bar)]
#[long_multi_line_attribute(
    split,
    across,
    lines,
)]
struct CRepr {
    #![repr(C)]
    x: f32,
    y: f32,
}
```

For attributes with an equal sign, put a single space before and after the `=`,
e.g., `#[foo = 42]`.

There must only be a single `derive` attribute. Note for tool authors: if
combining multiple `derive` attributes into a single attribute, the ordering of
the derived names must generally be preserved for correctness:
`#[derive(Foo)] #[derive(Bar)] struct Baz;` must be formatted to
`#[derive(Foo, Bar)] struct Baz;`.

### *small* items

In many places in this guide we specify formatting that depends on a code
construct being *small*. For example, single-line vs multi-line struct
literals:

```rust
// Normal formatting
Foo {
    f1: an_expression,
    f2: another_expression(),
}

// "small" formatting
Foo { f1, f2 }
```

We leave it to individual tools to decide on exactly what *small* means. In
particular, tools are free to use different definitions in different
circumstances.

Some suitable heuristics are the size of the item (in characters) or the
complexity of an item (for example, that all components must be simple names,
not more complex sub-expressions). For more discussion on suitable heuristics,
see [this issue](https://github.com/rust-lang-nursery/fmt-rfcs/issues/47).

## [Non-formatting conventions](advice.md)

## [Cargo.toml conventions](cargo.md)

## [Principles used for deciding these guidelines](principles.md)

---

### Src Doc Rustc Dev Guide Src Appendix Code Index (`src/doc/rustc-dev-guide/src/appendix/code-index.md`)

# Code Index

rustc has a lot of important data structures.
This is an attempt to give some guidance on where to learn more
about some of the key data structures of the compiler.

Item            |  Kind    | Short description           | Chapter            | Declaration
----------------|----------|-----------------------------|--------------------|-------------------
`BodyId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/hir.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.BodyId.html)
`Compiler` | struct | Represents a compiler session and can be used to drive a compilation. | [The Rustc Driver and Interface] | [compiler/rustc_interface/src/interface.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Compiler.html)
`ast::Crate` | struct | A syntax-level representation of a parsed crate | [The parser] | [compiler/rustc_ast/src/ast.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/struct.Crate.html)
`hir::Crate` | struct | A more abstract, compiler-friendly form of a crate's AST | [The Hir] | [compiler/rustc_middle/src/hir/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/struct.Crate.html)
`DefId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/def_id.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html)
`Diag` | struct | A struct for a compiler diagnostic, such as an error or lint | [Emitting Diagnostics] | [compiler/rustc_errors/src/diagnostic.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html)
`DocContext` | struct | A state container used by rustdoc when crawling through a crate to gather its documentation | [Rustdoc] | [src/librustdoc/core.rs](https://github.com/rust-lang/rust/blob/HEAD/src/librustdoc/core.rs)
`HirId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir_id/src/lib.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.HirId.html)
`Lexer` | struct | This is the lexer used during parsing. It consumes characters from the raw source code being compiled and produces a series of tokens for use by the rest of the parser | [The parser] |  [compiler/rustc_parse/src/lexer/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html)
`NodeId` | struct | One of four types of HIR node identifiers. Being phased out | [Identifiers in the HIR] | [compiler/rustc_ast/src/ast.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/node_id/struct.NodeId.html)
`ParamEnv` | struct | Information about generic parameters or `Self`, useful for working with associated or generic items | [Parameter Environment] | [compiler/rustc_middle/src/ty/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html)
`ParseSess` | struct | This struct contains information about a parsing session | [The parser] | [compiler/rustc_session/src/parse/parse.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.ParseSess.html)
`Rib` | struct | Represents a single scope of names | [Name resolution] | [compiler/rustc_resolve/src/lib.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.Rib.html)
`Session` | struct | The data associated with a compilation session | [The parser], [The Rustc Driver and Interface] | [compiler/rustc_session/src/session.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html)
`SourceFile` | struct | Part of the `SourceMap`. Maps AST nodes to their source code for a single source file. Was previously called FileMap | [The parser] | [compiler/rustc_span/src/lib.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.SourceFile.html)
`SourceMap` | struct | Maps AST nodes to their source code. It is composed of `SourceFile`s. Was previously called CodeMap | [The parser] | [compiler/rustc_span/src/source_map.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/source_map/struct.SourceMap.html)
`Span` | struct  | A location in the user's source code, used for error reporting primarily | [Emitting Diagnostics] | [compiler/rustc_span/src/span_encoding.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html)
`TokenStream` | struct | An abstract sequence of tokens, organized into `TokenTree`s | [The parser], [Macro expansion] | [compiler/rustc_ast/src/tokenstream.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/tokenstream/struct.TokenStream.html)
`TraitDef` | struct | This struct contains a trait's definition with type information | [The `ty` modules] |  [compiler/rustc_middle/src/ty/trait_def.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait_def/struct.TraitDef.html)
`TraitRef` | struct | The combination of a trait and its input types (e.g. `P0: Trait<P1...Pn>`) | [Trait Solving: Goals and Clauses]  |  [compiler/rustc_middle/src/ty/sty.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.TraitRef.html)
`Ty<'tcx>` | struct | This is the internal representation of a type used for type checking | [Type checking] | [compiler/rustc_middle/src/ty/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html)
`TyCtxt<'tcx>` | struct | The "typing context". This is the central data structure in the compiler. It is the context that you use to perform all manner of queries | [The `ty` modules] | [compiler/rustc_middle/src/ty/context.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html)

[The HIR]: ../hir.md
[Identifiers in the HIR]: ../hir.md#hir-id
[The parser]: ../the-parser.md
[The Rustc Driver and Interface]: ../rustc-driver/intro.md
[Type checking]: ../hir-typeck/summary.md
[The `ty` modules]: ../ty.md
[Rustdoc]: ../rustdoc.md
[Emitting Diagnostics]: ../diagnostics.md
[Macro expansion]: ../macro-expansion.md
[Name resolution]: ../name-resolution.md
[Parameter Environment]: ../typing-parameter-envs.md
[Trait Solving: Goals and Clauses]: ../traits/goals-and-clauses.md#domain-goals

---

### Src Doc Rustc Dev Guide Src Building Quickstart (`src/doc/rustc-dev-guide/src/building/quickstart.md`)

# Quickstart

This is a quickstart guide about getting the compiler running.
For more information on the individual steps, see the other pages in this chapter.

First, clone the repository:

```sh
git clone https://github.com/rust-lang/rust.git
cd rust
```

When building the compiler, we don't use `cargo` directly;
instead we use a wrapper called "x", which is invoked with `./x`.

We need to create a configuration for the build.
Use `./x setup` to create a good default.

```sh
./x setup
```

Then, we can build the compiler.
Use `./x build` to build the compiler, standard library, and a few tools.
You can also `./x check` to just check it.
All these commands can take specific components/paths as arguments, for example `./x check
compiler` to just check the compiler.

```sh
./x build
```

> When doing a change to the compiler that does not affect the way it compiles
the standard library (so for example, a change to an error message), use
`--keep-stage-std 1` to avoid recompiling it.

After building the compiler and standard library, you now have a working compiler toolchain.
You can use it with rustup by linking it.

```sh
rustup toolchain link stage1 build/host/stage1
```

**NOTE**: If you use `./x setup tools`, the default stage will be set to 2 instead of 1.
Adjust your command accordingly:
```sh
rustup toolchain link stage2 build/host/stage2
```

Now you have a toolchain called `stage1` linked to your build.
You can use it to test the compiler.

```sh
rustc +stage1 testfile.rs
```

After doing a change, you can run the compiler test suite with `./x test`.

`./x test` runs the full test suite, which is slow and rarely what you want.
Usually, `./x test tests/ui` is what you want after a compiler change, testing
all [UI tests](../tests/ui.md) that invoke the compiler on a specific test file
and check the output.

```sh
./x test tests/ui
```

Use `--bless` if you've made a change and want to update the `.stderr` files with the new output.

Congrats, you are now ready to make a change to the compiler!
If you have more questions, [the full chapter](./how-to-build-and-run.md) might contain the
answers, and if it doesn't, feel free to ask for help on
[Zulip](https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp).

If you use VSCode, Vim, Emacs, Helix or Zed, `./x setup` will ask you if you want to
set up the editor config.
For more information, check out [suggested workflows](./suggested.md).

---

### Src Doc Rustc Dev Guide Src Debuginfo Intro (`src/doc/rustc-dev-guide/src/debuginfo/intro.md`)

# Debug info

Debug info is a collection of information generated by the compiler that allows debuggers to
correctly interpret the state of a program while it is running.
That includes things like mapping instruction addresses to lines of code in the source file,
and type layout information so that bytes in memory can be read and displayed in a meaningful way.

Debug info can be a slightly overloaded term, covering all the layers between Rust MIR, and the
end-user seeing the output of their debugger onscreen.
In brief, the stack from beginning to end is as follows:

1. Rustc inspects the MIR and communicates the relevant source, symbol, and type information to LLVM
2. LLVM translates this information into a target-specific debug info format during compilation
3. A debugger reads and interprets the debug info, mapping source-lines and allowing the debugee's
variables in memory to be located and read with the correct layout
4. Built-in debugger formatting and styling is applied to variables
5. User-defined scripts are run, formatting and styling the variables further
6. The debugger frontend displays the variable to the user, possibly through the means of additional
API layers (e.g. VSCode extension by way of the
[Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/))


> NOTE: This subsection of the dev guide is perhaps more detailed than necessary. It aims to collect
> a large amount of scattered information into one place and equip the reader with as firm a grasp of
> the entire debug stack as possible.
>
> If you are only interested in working on the visualizer
> scripts, the information in the [debugger-visualizers](./debugger-visualizers.md) and
> [testing](./testing.md) will suffice. If you need to make changes to Rust's debug node generation,
> please see [rust-codegen](./rust-codegen.md). All other sections are supplementary, but can be
> vital to understanding some of the compromises the visualizers or codegen need to make. It can
> also be valuable to know when a problem might be better solved in LLVM or the debugger itself.

# DWARF

The is the primary debug info format for `*-gnu` targets.
It is typically bundled in with the
binary, but it [can be generated as a separate file](https://gcc.gnu.org/wiki/DebugFission).
The DWARF standard is available [here](https://dwarfstd.org/).

> NOTE: To inspect DWARF debug info, [gimli](https://crates.io/crates/gimli) can be used
> programatically. If you prefer a GUI, the author recommends [DWEX](https://github.com/sevaa/dwex)

# PDB/CodeView

The primary debug info format for `*-msvc` targets.
PDB is a proprietary container format created by Microsoft that, unfortunately,
[has multiple meanings](https://docs.rs/ms-pdb/0.1.10/ms_pdb/taster/enum.Flavor.html).
We are concerned with ordinary PDB files, as Portable PDB is used mainly for .Net applications.
PDB files are separate from the compiled binary and use the `.pdb` extension.

PDB files contain CodeView objects, equivalent to DWARF's tags.
CodeView, the debugger that consumed CodeView objects, was originally released in 1985.
Its original intent was for C debugging,
and was later extended to support Visual C++.
There are still minor alterations to the format to support modern architectures and languages,
but many of these changes are undocumented and/or sparsely used.

It is important to keep this context in mind when working with CodeView objects.
Due to its origins,
the "feature-set" of these objects is very limited, and focused around the core features of C.
It does not have many of the convenience or features of modern DWARF standards.
A fair number of workarounds exist within the debug info stack
to compensate for CodeView's shortcomings.

Due to its proprietary nature, it is very difficult to find information about PDB and CodeView.
Many of the sources were made at vastly different times
and contain incomplete or somewhat contradictory information.
As such, this page will aim to collect as many sources as possible.

* [TIS PE specification](https://web.archive.org/web/20260315080740/http://x-ways.net/winhex/kb/ff/PE_EXE.pdf)
which includes a lengthy section titled "Microsoft Symbol and Type Information", detailing much of
the CodeView format.
The document was created in 1993, but the information is still detailed,
accurate, and has useful diagrams.
* LLVM
    * [CodeView Overview](https://llvm.org/docs/SourceLevelDebugging.html#codeview-debug-info-format)
    * [PDB Overview and technical details](https://llvm.org/docs/PDB/index.html)
* Microsoft
    * [microsoft-pdb](https://github.com/microsoft/microsoft-pdb) - A C/C++ implementation of a PDB
    reader.
    The implementation does not contain the full PDB or CodeView specification, but does
    contain enough information for other PDB consumers to be written.
    At time of writing (Nov 2025),
    this repo has been archived for several years.
    * [pdb-rs](https://github.com/microsoft/pdb-rs/) - A Rust-based PDB reader and writer based on
    other publicly-available information.
    Does not guarantee stability or spec compliance.
    Also contains `pdbtool`, which can dump PDB files (`cargo install --locked pdbtool`)
    * [Debug Interface Access SDK](https://learn.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/getting-started-debug-interface-access-sdk).
    While it does not document the PDB format directly, details can be gleaned from the interface
    itself.
    * [PDB-Documentation](https://github.com/PascalBeyer/PDB-Documentation) - a resource compiling
    much of the publicly available information about PDB and CodeView.

# Debuggers

Rust supports 3 major debuggers: GDB, LLDB, and CDB.
Each has its own set of requirements,
limitations, and quirks.
This unfortunately creates a large surface area to account for.

> NOTE: CDB is a proprietary debugger created by Microsoft.
> The underlying engine also powers WinDbg, KD, the Microsoft C/C++ extension for VSCode,
> and part of the Visual Studio Debugger.
> In these docs, it will be referred to as CDB for consistency

While GDB and LLDB do offer facilities to natively support Rust's value layout, this isn't
completely necessary.
Rust currently outputs debug info very similar to that of C++, allowing
debuggers without Rust support to work with a slightly degraded experience.
More detail will be included in later sections,
but here is a quick reference for the capabilities of each debugger:

| Debugger | Debug Info Format | Native Rust support | Expression Style | Visualizer Scripts |
| --- | --- | --- | --- | --- |
| GDB | DWARF | Full | Rust | Python |
| LLDB | DWARF and PDB | Partial | C/C++ | Python |
| CDB | PDB | None | C/C++ | Natvis |

> IMPORTANT: CDB can be assumed to run only on Windows. No assumptions can be made about the OS
>running GDB or LLDB.

## Unsupported

Below, are several unsupported debuggers that are of particular note due to their potential impact
in the future.

* [Bugstalker](https://github.com/godzie44/BugStalker) is an x86-64 Linux debugger written in Rust,
  specifically to debug Rust programs.
  While promising, it is still in early development.
* [RAD Debugger](https://github.com/EpicGamesExt/raddebugger) is a Windows-only GUI debugger.
  It has a custom debug info format that PDB is translated into.
  The project also includes a linker that can generate their new debug info format
  during the linking phase.

---

### Src Doc Rustc Dev Guide Src Mir Index (`src/doc/rustc-dev-guide/src/mir/index.md`)

# The MIR (Mid-level IR)

MIR is Rust's _Mid-level Intermediate Representation_.
It is constructed from [HIR](../hir.md).
MIR was introduced in [RFC 1211].
It is a radically simplified form of Rust that is used for
certain flow-sensitive safety checks – notably the borrow checker!
– and also for optimization and code generation.

If you'd like a very high-level introduction to MIR,
as well as some of the compiler concepts that it relies on (such as control-flow
graphs and desugaring), you may enjoy the [rust-lang blog post that introduced MIR][blog].

[blog]: https://blog.rust-lang.org/2016/04/19/MIR.html

## Introduction to MIR

MIR is defined in the [`compiler/rustc_middle/src/mir/`][mir] module,
but much of the code that manipulates it is found in [`compiler/rustc_mir_build`][mirmanip_build],
[`compiler/rustc_mir_transform`][mirmanip_transform],
and [`compiler/rustc_mir_dataflow`][mirmanip_dataflow].

[RFC 1211]: https://rust-lang.github.io/rfcs/1211-mir.html

Some of the key characteristics of MIR are:

- It is based on a [control-flow graph][cfg].
- It does not have nested expressions.
- All types in MIR are fully explicit.

[cfg]: ../appendix/background.md#cfg

## Key MIR vocabulary

This section introduces the key concepts of MIR, summarized here:

- **Basic blocks**: units of the control-flow graph, consisting of:
  - **statements:** actions with one successor
  - **terminators:** actions with potentially multiple successors; always at the end of a block
  - (if you're not familiar with the term *basic block*, see the [background chapter][cfg])
- **Locals:** Memory locations allocated on the stack (conceptually, at least),
  such as function arguments, local variables, and temporaries.
  These are identified by an index, written with a leading underscore, like `_1`.
  There is also a special "local" (`_0`) allocated to store the return value.
- **Places:** expressions that identify a location in memory, like `_1` or `_1.f`.
- **Rvalues:** expressions that produce a value.
  The "R" stands for the fact that these are the "right-hand side" of an assignment.
  - **Operands:** the arguments to an rvalue,
    which can either be a constant (like `22`) or a place (like `_1`).

You can get a feeling for how MIR is constructed by translating simple
programs into MIR and reading the pretty printed output.
In fact, the playground makes this easy,
since it supplies a MIR button that will show you the MIR for your program.
Try putting this program into play (or [clicking on this link][sample-play]),
and then clicking the "MIR" button on the top:

[sample-play]: https://play.rust-lang.org/?gist=30074856e62e74e91f06abd19bd72ece&version=stable&edition=2021

```rust
fn main() {
    let mut vec = Vec::new();
    vec.push(1);
    vec.push(2);
}
```

You should see something like:

```mir
// WARNING: This output format is intended for human consumers only
// and is subject to change without notice. Knock yourself out.
fn main() -> () {
    ...
}
```

This is the MIR format for the `main` function.
MIR shown by above link is optimized.
Some statements like `StorageLive` are removed in optimization.
This happens because the compiler notices the value is never accessed in the code.
We can use `rustc [filename].rs -Z mir-opt-level=0 --emit mir` to view unoptimized MIR.
This requires the nightly toolchain.


**Variable declarations.** If we drill in a bit,
we'll see it begins with a bunch of variable declarations.
They look like this:

```mir
let mut _0: ();                      // return place
let mut _1: std::vec::Vec<i32>;      // in scope 0 at src/main.rs:2:9: 2:16
let mut _2: ();
let mut _3: &mut std::vec::Vec<i32>;
let mut _4: ();
let mut _5: &mut std::vec::Vec<i32>;
```

You can see that variables in MIR don't have names, they have indices,
like `_0` or `_1`.  We also intermingle the user's variables (e.g.,
`_1`) with temporary values (e.g., `_2` or `_3`). You can tell apart
user-defined variables because they have debuginfo associated to them (see below).

**User variable debuginfo.** Below the variable declarations,
we find the only hint that `_1` represents a user variable:
```mir
scope 1 {
    debug vec => _1;                 // in scope 1 at src/main.rs:2:9: 2:16
}
```
Each `debug <Name> => <Place>;` annotation describes a named user variable,
and where (i.e. the place) a debugger can find the data of that variable.
Here the mapping is trivial, but optimizations may complicate the place,
or lead to multiple user variables sharing the same place.
Additionally, closure captures are described using the same system, and so
they're complicated even without optimizations, e.g.: `debug x => (*((*_1).0: &T));`.

The "scope" blocks (e.g., `scope 1 { .. }`) describe the lexical structure of
the source program (which names were in scope when), so any part of the program
annotated with `// in scope 0` would be missing `vec`, if you were stepping
through the code in a debugger, for example.

**Basic blocks.** Reading further, we see our first **basic block** (naturally
it may look slightly different when you view it, and I am ignoring some of the comments):

```mir
bb0: {
    StorageLive(_1);
    _1 = const <std::vec::Vec<T>>::new() -> bb2;
}
```

A basic block is defined by a series of **statements** and a final **terminator**.
In this case, there is one statement:

```mir
StorageLive(_1);
```

This statement indicates that the variable `_1` is "live",
meaning that it may be used later – this will persist until we encounter a
`StorageDead(_1)` statement, which indicates that the variable `_1` is done being used.
These "storage statements" are used by LLVM to allocate stack space.

The **terminator** of the block `bb0` is the call to `Vec::new`:

```mir
_1 = const <std::vec::Vec<T>>::new() -> bb2;
```

Terminators are different from statements because they can have more
than one successor – that is, control may flow to different places.
Function calls like the call to `Vec::new` are always
terminators because of the possibility of unwinding,
although in the case of `Vec::new` we are able to see that indeed unwinding is not possible,
and hence we list only one successor block, `bb2`.

If we look ahead to `bb2`, we will see it looks like this:

```mir
bb2: {
    StorageLive(_3);
    _3 = &mut _1;
    _2 = const <std::vec::Vec<T>>::push(move _3, const 1i32) -> [return: bb3, unwind: bb4];
}
```

Here there are two statements: another `StorageLive`, introducing the `_3` temporary,
and then an assignment:

```mir
_3 = &mut _1;
```

Assignments in general have the form:

```text
<Place> = <Rvalue>
```

A place is an expression like `_3`, `_3.f` or `*_3` – it denotes a location in memory.
An **Rvalue** is an expression that creates a value: in this case,
the rvalue is a mutable borrow expression, which looks like `&mut <Place>`.
So we can kind of define a grammar for rvalues like so:

```text
<Rvalue>  = & (mut)? <Place>
          | <Operand> + <Operand>
          | <Operand> - <Operand>
          | ...

<Operand> = Constant
          | copy Place
          | move Place
```

As you can see from this grammar,
rvalues cannot be nested – they can only reference places and constants.
Moreover, when you use a place,
we indicate whether we are **copying it** (which requires that the
place have a type `T` where `T: Copy`) or **moving it** (which works for a place of any type).
So, for example, if we had the expression `x = a + b + c` in Rust,
that would get compiled to two statements and a temporary:

```mir
TMP1 = a + b
x = TMP1 + c
```

([Try it and see][play-abc],
though you may want to do release mode to skip over the overflow checks.)

[play-abc]: https://play.rust-lang.org/?gist=1751196d63b2a71f8208119e59d8a5b6&version=stable

## MIR data types

The MIR data types are defined in the [`compiler/rustc_middle/src/mir/`][mir] module.
Each of the key concepts mentioned in the previous section
maps in a fairly straightforward way to a Rust type.

The main MIR data type is [`Body`].
It contains the data for a single
function (along with sub-instances of Mir for "promoted constants",
but [you can read about those below](#promoted-constants)).

- **Basic blocks**: The basic blocks are stored in the field
  [`Body::basic_blocks`][basicblocks]; this is a vector of [`BasicBlockData`] structures.
  Nobody ever references a basic block directly: instead, we pass around [`BasicBlock`] values,
  which are [newtype'd] indices into this vector.
- **Statements** are represented by the type [`Statement`].
- **Terminators** are represented by the [`Terminator`].
- **Locals** are represented by a [newtype'd] index type [`Local`].
  The data for a local variable is found in the [`Body::local_decls`][localdecls] vector.
  There is also a special constant
  [`RETURN_PLACE`] identifying the special "local" representing the return value.
- **Places** are identified by the struct [`Place`].
  There are a few fields:
  - Local variables like `_1`
  - **Projections**, which are fields or other things that "project out" from a base place.
    These are represented by the [newtype'd] type
    [`ProjectionElem`]. So e.g. the place `_1.f` is a projection,
    with `f` being the "projection element" and `_1` being the base path.
    `*_1` is also a projection,
    with the `*` being represented by the [`ProjectionElem::Deref`] element.
- **Rvalues** are represented by the enum [`Rvalue`].
- **Operands** are represented by the enum [`Operand`].

## Representing constants

When code has reached the MIR stage, constants can generally come in two forms:
*MIR constants* ([`mir::Constant`]) and *type system constants* ([`ty::Const`]).
MIR constants are used as operands: in `x + CONST`, `CONST` is a MIR constant;
similarly, in `x + 2`, `2` is a MIR constant.
Type system constants are used in the type system,
in particular for array lengths, but also for const generics.

Generally, both kinds of constants can be "unevaluated" or "already evaluated".
An unevaluated constant simply stores the `DefId` of what needs to be evaluated
to compute this result.
An evaluated constant (a "value") has already been
computed; their representation differs between type system constants and MIR
constants: MIR constants evaluate to a `mir::ConstValue`; type system constants
evaluate to a `ty::ValTree`.

Type system constants have some more variants to support const generics: they
can refer to local const generic parameters, and they are subject to inference.
Furthermore, the `mir::Constant::Ty` variant lets us use an arbitrary type
system constant as a MIR constant; this happens whenever a const generic
parameter is used as an operand.

### MIR constant values

In general,
a MIR constant value (`mir::ConstValue`) was computed by evaluating some constant the user wrote.
This [const evaluation](../const-eval.md) produces
a very low-level representation of the result in terms of individual bytes.
We call this an "indirect" constant (`mir::ConstValue::Indirect`) since the value
is stored in-memory.

However, storing everything in-memory would be awfully inefficient.
Hence there are some other variants in `mir::ConstValue` that can represent certain simple
and common values more efficiently.
In particular, everything that can be directly written as a literal in Rust (integers,
floats, chars, bools,
but also `"string literals"` and `b"byte string literals"`) has an optimized variant that
avoids the full overhead of the in-memory representation.

### ValTrees

An evaluated type system constant is a "valtree".
The `ty::ValTree` datastructure allows us to represent

* arrays,
* many structs,
* tuples,
* enums and,
* most primitives.

The most important rule for this representation is that every value must be uniquely represented.
In other words, a specific value must only be representable in one specific way.
For example, there is only one way to represent an array of two integers as a `ValTree`:
`Branch([Leaf(first_int), Leaf(second_int)])`.
Even though theoretically a `[u32; 2]` could be encoded in a `u64` and thus just be a
`Leaf(bits_of_two_u32)`, that is not a legal construction of `ValTree` (and is very complex to do,
so it is unlikely anyone is tempted to do so).

These rules also mean that some values are not representable.
There can be no `union`s in type level constants,
as it is not clear how they should be represented,
because their active variant is unknown.
Similarly, there is no way to represent raw pointers as addresses are unknown at compile-time,
and thus we cannot make any assumptions about them.
References on the other hand *can* be represented,
as equality for references is defined as equality on their value,
so we ignore their address and just look at the backing value.
We must make sure that the pointer values of the references are not observable at compile time.
We thus encode `&42` exactly like `42`.
Any conversion from valtree back to a MIR constant value must reintroduce an actual indirection.
At codegen time,
the addresses may be deduplicated between multiple uses or not,
entirely depending on arbitrary optimization choices.

As a consequence, all decoding of `ValTree` must happen by matching on the type first and making
decisions depending on that.
The value itself gives no useful information without the type that belongs to it.

### Promoted constants

See the const-eval WG's [docs on promotion](https://github.com/rust-lang/const-eval/blob/master/promotion.md).


[mir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/index.html
[mirmanip_build]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/index.html
[mirmanip_transform]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/index.html
[mirmanip_dataflow]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/index.html
[`Body`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Body.html
[newtype'd]: ../appendix/glossary.md#newtype
[basicblocks]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Body.html#structfield.basic_blocks
[`BasicBlock`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.BasicBlock.html
[`BasicBlockData`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.BasicBlockData.html
[`Statement`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Statement.html
[`Terminator`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/terminator/struct.Terminator.html
[`Local`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Local.html
[localdecls]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Body.html#structfield.local_decls
[`RETURN_PLACE`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/constant.RETURN_PLACE.html
[`Place`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Place.html
[`ProjectionElem`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.ProjectionElem.html
[`ProjectionElem::Deref`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.ProjectionElem.html#variant.Deref
[`Rvalue`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.Rvalue.html
[`Operand`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.Operand.html
[`mir::Constant`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.Const.html
[`ty::Const`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Const.html

---

### Src Doc Rustc Dev Guide Src Rustc Driver Intro (`src/doc/rustc-dev-guide/src/rustc-driver/intro.md`)

# `rustc_driver` and `rustc_interface`

## `rustc_driver`

The [`rustc_driver`] is essentially `rustc`'s `main` function.
It acts as the glue for running the various phases of the compiler in the correct order,
using the interface defined in the [`rustc_interface`] crate.
Where possible, using [`rustc_driver`] rather than [`rustc_interface`] is recommended.

The main entry point of [`rustc_driver`] is [`rustc_driver::compiler_entrypoint`][rd_ce].
This builder accepts the same command-line args as rustc as well as an implementation of [`Callbacks`] and a couple of other optional options.
[`Callbacks`] is a `trait` that allows for custom compiler configuration,
as well as allowing custom code to run after different phases of the compilation.

## `rustc_interface`

The [`rustc_interface`] crate provides a low level API to external users for manually driving the compilation process,
allowing third parties to effectively use `rustc`'s internals as a library for analyzing a crate or for ad hoc emulating of the compiler for cases where [`rustc_driver`] is not flexible enough (i.e. `rustdoc` compiling code and serving output).

The main entry point of [`rustc_interface`] ([`rustc_interface::run_compiler`][i_rc]) takes a configuration variable for the compiler
and a `closure` taking a yet unresolved [`Compiler`].
[`run_compiler`][i_rc] creates a `Compiler` from the configuration and passes it to the `closure`.
Inside the `closure` you can use the `Compiler` to call various functions to compile a crate and get the results.
You can see a minimal example of how to use [`rustc_interface`] [here][example].

You can see an example of how to use the various functions using [`rustc_interface`] needs by looking at the `rustc_driver` implementation,
specifically [`rustc_driver_impl::compiler_entrypoint`][rdi_ce]
(not to be confused with [`rustc_interface::run_compiler`][i_rc]).

> **Warning:** By its very nature, the internal compiler APIs are always going
> to be unstable. That said, we do try not to break things unnecessarily.


[`Compiler`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Compiler.html
[`rustc_driver`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/
[`rustc_interface`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/index.html
[`Callbacks`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/trait.Callbacks.html
[example]: https://github.com/rust-lang/rustc-dev-guide/blob/main/examples/rustc-interface-example.rs
[i_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/fn.run_compiler.html
[rd_ce]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/fn.compiler_entrypoint.html
[rdi_ce]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver_impl/fn.compiler_entrypoint.html

---

### Src Doc Rustc Dev Guide Src Tests Intro (`src/doc/rustc-dev-guide/src/tests/intro.md`)

# Testing the compiler

The Rust project runs a wide variety of different tests,
orchestrated by the build system (`./x test`).
This section gives a brief overview of the different testing tools.
Subsequent chapters dive into [running tests](running.md) and [adding new tests](adding.md).

## Kinds of tests

There are several kinds of tests to exercise things in the Rust distribution.
Almost all of them are driven by `./x test`, with some exceptions noted below.

### Compiletest

The main test harness for testing the compiler itself is a tool called [compiletest].

[compiletest] supports running different styles of tests,
organized into *test suites*.
A *test mode* may provide common presets/behavior for a set of *test suites*.
[compiletest]-supported tests are located in the [`tests`] directory.

The [Compiletest chapter][compiletest] goes into detail on how to use this tool.

> Example: `./x test tests/ui`

[compiletest]: compiletest.md
[`tests`]: https://github.com/rust-lang/rust/tree/HEAD/tests

### Package tests

The standard library and many of the compiler packages include typical Rust `#[test]` unit tests,
integration tests, and documentation tests.
You can pass a path to `./x test` for almost any package in the `library/` or `compiler/`
directory, and `x` will essentially run `cargo test` on that package.

Examples:

| Command                                   | Description                           |
|-------------------------------------------|---------------------------------------|
| `./x test library/std`                    | Runs tests on `std` only              |
| `./x test library/core`                   | Runs tests on `core` only             |
| `./x test compiler/rustc_data_structures` | Runs tests on `rustc_data_structures` |

The standard library relies very heavily on documentation tests to cover its functionality.
However, unit tests and integration tests can also be used as needed.
Almost all of the compiler packages have doctests disabled.

All standard library and compiler unit tests are placed in separate `tests` file
(which is enforced in [tidy][tidy-unit-tests]).
This ensures that when the test file is changed, the crate does not need to be recompiled.
For example:

```rust,ignore
#[cfg(test)]
mod tests;
```

If it wasn't done this way, and you were working on something like `core`, that
would require recompiling the entire standard library, and the entirety of `rustc`.

`./x test` includes some CLI options for controlling the behavior with these package tests:

* `--doc` — Only runs documentation tests in the package.
* `--all-targets` — Run all tests *except* documentation tests.
* `--tests` — Only runs unit and integration tests

[tidy-unit-tests]: https://github.com/rust-lang/rust/blob/HEAD/src/tools/tidy/src/unit_tests.rs

### Tidy

Tidy is a custom tool used for validating source code style and formatting conventions,
such as rejecting long lines.
There is more information in the
[section on coding conventions](../conventions.md#formatting) or the [Tidy Readme].

> Examples: `./x test tidy`

[Tidy Readme]: https://github.com/rust-lang/rust/blob/HEAD/src/tools/tidy/Readme.md


### Formatting

Rustfmt is integrated with the build system to enforce uniform style across the compiler.
The formatting check is automatically run by the Tidy tool mentioned above.

Examples:

| Command                 | Description                                                        |
|-------------------------|--------------------------------------------------------------------|
| `./x fmt --check`       | Checks formatting and exits with an error if formatting is needed. |
| `./x fmt`               | Runs rustfmt across the entire codebase.                           |
| `./x test tidy --bless` | First runs rustfmt to format the codebase, then runs tidy checks.  |

### Book documentation tests

All of the books that are published have their own tests,
primarily for validating that the Rust code examples pass.
Under the hood, these are essentially using `rustdoc --test` on the markdown files.
The tests can be run by passing a path to a book to `./x test`.

> Example: `./x test src/doc/book`

### Documentation link checker

Links across all documentation is validated with a link checker tool,
and it can be invoked so:

```console
./x test linkchecker
```

This requires building all of the documentation, which might take a while.

### `distcheck`

`distcheck` verifies that the source distribution tarball created by the build system will unpack,
build, and run all tests.

```console
./x test distcheck
```

### Tool tests

Packages that are included with Rust have all of their tests run as well.
This includes things such as cargo, clippy, rustfmt, miri, bootstrap (testing the
Rust build system itself), etc.

Most of the tools are located in the [`src/tools`] directory.
To run the tool's tests, just pass its path to `./x test`.

> Example: `./x test src/tools/cargo`

Usually these tools involve running `cargo test` within the tool's directory.

If you want to run only a specified set of tests, append `--test-args FILTER_NAME` to the command.

> Example: `./x test src/tools/miri --test-args padding`

In CI, some tools are allowed to fail.
Failures send notifications to the corresponding teams, and are tracked on the [toolstate website].
More information can be found in the [toolstate documentation].

[`src/tools`]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/
[toolstate documentation]: https://forge.rust-lang.org/infra/toolstate.html
[toolstate website]: https://rust-lang-nursery.github.io/rust-toolstate/

### Ecosystem testing

Rust tests integration with real-world code to catch regressions and make
informed decisions about the evolution of the language.
There are several kinds of ecosystem tests, including Crater.
See the [Ecosystem testing chapter](ecosystem.md) for more details.

### Performance testing

A separate infrastructure is used for testing and tracking performance of the compiler.
See the [Performance testing chapter](perf.md) for more details.

### Codegen backend testing

See [Codegen backend testing](./codegen-backend-tests/intro.md).

## Miscellaneous information

There are some other useful testing-related info at [Misc info](misc.md).

## Further reading

The following blog posts may also be of interest:

- brson's classic ["How Rust is tested"][howtest]

[howtest]: https://brson.github.io/2017/07/10/how-rust-is-tested

---

### Src Doc Rustc Src Codegen Options Index (`src/doc/rustc/src/codegen-options/index.md`)

# Codegen Options

All of these options are passed to `rustc` via the `-C` flag, short for "codegen." You can see
a version of this list for your exact compiler by running `rustc -C help`.

## code-model

This option lets you choose which code model to use. \
Code models put constraints on address ranges that the program and its symbols may use. \
With smaller address ranges machine instructions
may be able to use more compact addressing modes.

The specific ranges depend on target architectures and addressing modes available to them. \
For x86 more detailed description of its code models can be found in
[System V Application Binary Interface](https://gitlab.com/x86-psABIs/x86-64-ABI/-/jobs/artifacts/master/raw/x86-64-ABI/abi.pdf?job=build)
specification.

Supported values for this option are:

- `tiny` - Tiny code model.
- `small` - Small code model. This is the default model for majority of supported targets.
- `kernel` - Kernel code model.
- `medium` - Medium code model.
- `large` - Large code model.

Supported values can also be discovered by running `rustc --print code-models`.

## codegen-units

This flag controls the maximum number of code generation units the crate is
split into. It takes an integer greater than 0.

When a crate is split into multiple codegen units, LLVM is able to process
them in parallel. Increasing parallelism may speed up compile times, but may
also produce slower code. Setting this to 1 may improve the performance of
generated code, but may be slower to compile.

The default value, if not specified, is 16 for non-incremental builds. For
incremental builds the default is 256 which allows caching to be more granular.

## collapse-macro-debuginfo

This flag controls whether code locations from a macro definition are collapsed into a single
location associated with that macro's call site, when generating debuginfo for this crate.

This option, if passed, overrides both default collapsing behavior and `#[collapse_debuginfo]`
attributes in code.

* `y`, `yes`, `on`, `true`: collapse code locations in debuginfo.
* `n`, `no`, `off` or `false`: do not collapse code locations in debuginfo.
* `external`: collapse code locations in debuginfo only if the macro comes from a different crate.

## control-flow-guard

This flag controls whether LLVM enables the Windows [Control Flow
Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard)
platform security feature. This flag is currently ignored for non-Windows targets.
It takes one of the following values:

* `y`, `yes`, `on`, `true`, `checks`, or no value: enable Control Flow Guard.
* `nochecks`: emit Control Flow Guard metadata without runtime enforcement checks (this
should only be used for testing purposes as it does not provide security enforcement).
* `n`, `no`, `off`, `false`: do not enable Control Flow Guard (the default).

## debug-assertions

This flag lets you turn `cfg(debug_assertions)` [conditional
compilation](../../reference/conditional-compilation.md#debug_assertions) on
or off. It takes one of the following values:

* `y`, `yes`, `on`, `true`, or no value: enable debug-assertions.
* `n`, `no`, `off` or `false`: disable debug-assertions.

If not specified, debug assertions are automatically enabled only if the
[opt-level](#opt-level) is 0.

## debuginfo

This flag controls the generation of debug information. It takes one of the
following values:

* `0` or `none`: no debug info at all (the default).
* `line-directives-only`: line info directives only. For the nvptx* targets this enables [profiling](https://reviews.llvm.org/D46061). For other use cases, `line-tables-only` is the better, more compatible choice.
* `line-tables-only`: line tables only. Generates the minimal amount of debug info for backtraces with filename/line number info, but not anything else, i.e. no variable or function parameter info.
* `1` or `limited`: debug info without type or variable-level information.
* `2` or `full`: full debug info.

Note: The [`-g` flag][option-g-debug] is an alias for `-C debuginfo=2`.

## default-linker-libraries

This flag controls whether or not the linker includes its default libraries.
It takes one of the following values:

* `y`, `yes`, `on`, `true`: include default libraries.
* `n`, `no`, `off` or `false` or no value: exclude default libraries (the default).

For example, for gcc flavor linkers, this issues the `-nodefaultlibs` flag to
the linker.

## dlltool

On `windows-gnu` targets, this flag controls which dlltool `rustc` invokes to
generate import libraries when using the [`raw-dylib` link kind](../../reference/items/external-blocks.md#the-link-attribute).
It takes a path to [the dlltool executable](https://sourceware.org/binutils/docs/binutils/dlltool.html).
If this flag is not specified, a dlltool executable will be inferred based on
the host environment and target.

## dwarf-version

This option controls the version of DWARF that the compiler emits, on platforms
that use DWARF to encode debug information. It takes one of the following
values:

* `2`: DWARF version 2 (the default on certain platforms, like Android).
* `3`: DWARF version 3 (the default on certain platforms, like AIX).
* `4`: DWARF version 4 (the default on most platforms, like Linux & macOS).
* `5`: DWARF version 5.

DWARF version 1 is not supported.

## embed-bitcode

This flag controls whether or not the compiler embeds LLVM bitcode into object
files. It takes one of the following values:

* `y`, `yes`, `on`, `true` or no value: put bitcode in rlibs (the default).
* `n`, `no`, `off` or `false`: omit bitcode from rlibs.

LLVM bitcode is required when rustc is performing link-time optimization (LTO).
Embedded bitcode will appear in rustc-generated object files inside of a section
whose name is defined by the target platform. Most of the time this is `.llvmbc`.

The use of `-C embed-bitcode=no` can significantly improve compile times and
reduce generated file sizes if your compilation does not actually need bitcode
(e.g. if you're not performing LTO). For these reasons, Cargo uses `-C embed-bitcode=no`
whenever possible. Likewise, if you are building directly with `rustc` we recommend
using `-C embed-bitcode=no` whenever you are not using LTO.

If combined with `-C lto`, `-C embed-bitcode=no` will cause `rustc` to abort
at start-up, because the combination is invalid.

> **Note**: if you're building Rust code with LTO then you probably don't even
> need the `embed-bitcode` option turned on. You'll likely want to use
> `-Clinker-plugin-lto` instead which skips generating object files entirely and
> simply replaces object files with LLVM bitcode. The only purpose for
> `-Cembed-bitcode` is when you're generating an rlib that is both being used
> with and without LTO. For example Rust's standard library ships with embedded
> bitcode since users link to it both with and without LTO.
>
> This also may make you wonder why the default is `yes` for this option. The
> reason for that is that it's how it was for rustc 1.44 and prior. In 1.45 this
> option was added to turn off what had always been the default.

## embed-metadata

This option instructs `rustc` to include the full metadata in `rlib` and `dylib`
crate types. The default value is `yes` (enabled). If disabled (`no`), only stub
metadata will be stored in these files, to reduce their size on disk. When using
`-Cembed-metadata=no`, you will probably want to use `--emit=metadata` to produce
the full metadata into a separate `.rmeta` file.

## extra-filename

This option allows you to put extra data in each output filename. It takes a
string to add as a suffix to the filename. See the [`--emit`
flag][option-emit] for more information.

## force-frame-pointers

This flag forces the use of frame pointers. It takes one of the following
values:

* `y`, `yes`, `on`, `true` or no value: force-enable frame pointers.
* `n`, `no`, `off` or `false`: do not force-enable frame pointers. This does
  not necessarily mean frame pointers will be removed.

The default behaviour, if frame pointers are not force-enabled, depends on the
target.

## force-unwind-tables

This flag forces the generation of unwind tables. It takes one of the following
values:

* `y`, `yes`, `on`, `true` or no value: Unwind tables are forced to be generated.
* `n`, `no`, `off` or `false`: Unwind tables are not forced to be generated. If unwind
  tables are required by the target an error will be emitted.

The default if not specified depends on the target.

## incremental

This flag allows you to enable incremental compilation, which allows `rustc`
to save information after compiling a crate to be reused when recompiling the
crate, improving re-compile times. This takes a path to a directory where
incremental files will be stored.

Using incremental compilation inhibits certain optimizations (for example by increasing the amount of codegen units) and is therefore not recommended for release builds.

## instrument-coverage

This option enables instrumentation-based code coverage support. See the
chapter on [instrumentation-based code coverage] for more information.

Note that while the `-C instrument-coverage` option is stable, the profile data
format produced by the resulting instrumentation may change, and may not work
with coverage tools other than those built and shipped with the compiler.

## jump-tables

This option is used to allow or prevent the LLVM codegen backend from creating
jump tables when lowering switches from Rust code.

* `y`, `yes`, `on`, `true` or no value: allow jump tables (the default).
* `n`, `no`, `off` or `false`: disable jump tables.

To prevent jump tables being created from Rust code, a target must ensure
all crates are compiled with jump tables disabled.

Note, in many cases the Rust toolchain is distributed with precompiled
crates, such as the core and std crates, which could possibly include
jump tables. Furthermore, this option does not guarantee a target will
be free of jump tables. They could arise from external dependencies,
inline asm, or other complicated interactions when using crates which
are compiled with jump table support.

Disabling jump tables can be used to help provide protection against
jump-oriented-programming (JOP) attacks.

## link-arg

This flag lets you append a single extra argument to the linker invocation.

"Append" is significant; you can pass this flag multiple times to add multiple arguments.

On Unix-like targets that use `cc` as the linker driver, use `-Clink-arg=-Wl,$ARG` to pass an argument to the actual linker.

## link-args

This flag lets you append multiple extra arguments to the linker invocation. The
options should be separated by spaces.

## link-dead-code

Tries to generate and link dead code that would otherwise not be generated or
linked. It takes one of the following values:

* `y`, `yes`, `on`, `true` or no value: try to keep dead code.
* `n`, `no`, `off` or `false`: remove dead code (the default).

This flag was historically used to help improve some older forms of code
coverage measurement. Its use is not recommended.

## link-self-contained

This flag controls whether the linker will use libraries and objects shipped with Rust instead of
those in the system.  It also controls which binary is used for the linker itself. This allows
overriding cases when detection fails or the user wants to use shipped libraries.

You can enable or disable the usage of any self-contained components using one of the following values:

* no value: rustc will use heuristic to disable self-contained mode if system has necessary tools.
* `y`, `yes`, `on`, `true`: use only libraries/objects shipped with Rust.
* `n`, `no`, `off` or `false`: rely on the user or the linker to provide non-Rust libraries/objects.

It is also possible to enable or disable specific self-contained components in a more granular way.
You can pass a comma-separated list of self-contained components, individually enabled
(`+component`) or disabled (`-component`).

Currently, only the `linker` granular option is stabilized, and only on the `x86_64-unknown-linux-gnu` target:
- `linker`: toggle the usage of self-contained linker binaries (linker, dlltool, and their necessary libraries)

Note that only the `-linker` opt-out is stable on the `x86_64-unknown-linux-gnu` target: `+linker` is
already the default on this target.

#### Implementation notes

On the `x86_64-unknown-linux-gnu` target, when using the default linker flavor (using `cc` as the
linker driver) and linker features (to try using `lld`), `rustc` will try to use the self-contained
linker by passing a `-B /path/to/sysroot/` link argument to the driver to find `rust-lld` in the
sysroot. For backwards-compatibility, and to limit name and `PATH` collisions, this is done using a
shim executable (the `lld-wrapper` tool) that forwards execution to the `rust-lld` executable itself.

## linker

This flag controls which linker `rustc` invokes to link your code. It takes a
path to the linker executable. If this flag is not specified, the linker will
be inferred based on the target. See also the [linker-flavor](#linker-flavor)
flag for another way to specify the linker.

Note that on Unix-like targets (for example, `*-unknown-linux-gnu` or `*-unknown-freebsd`)
the C compiler (for example `cc` or `clang`) is used as the "linker" here, serving as a linker driver.
It will invoke the actual linker with all the necessary flags to be able to link against the system libraries like libc.

## linker-features

The `-Clinker-features` flag allows enabling or disabling specific features used during linking.

These feature flags are a flexible extension mechanism that is complementary to linker flavors,
designed to avoid the combinatorial explosion of having to create a new set of flavors for each
linker feature we'd want to use.

The flag accepts a comma-separated list of features, individually enabled (`+feature`) or disabled
(`-feature`).

Currently only one is stable, and only on the `x86_64-unknown-linux-gnu` target:
- `lld`: to toggle trying to use the lld linker, either the system-installed binary, or the self-contained
  `rust-lld` linker (via the [`-Clink-self-contained=+linker`](#link-self-contained) flag).

For example, use:
- `-Clinker-features=+lld` to opt into using the `lld` linker, when possible (see the Implementation notes below)
- `-Clinker-features=-lld` to opt out instead, for targets where it is configured as the default linker

Note that only the `-lld` opt-out is stable on the `x86_64-unknown-linux-gnu` target: `+lld` is
already the default on this target.

#### Implementation notes

On the `x86_64-unknown-linux-gnu` target, when using the default linker flavor (using `cc` as the
linker driver), `rustc` will try to use lld by passing a `-fuse-ld=lld` link argument to the driver.
`rustc` will also try to detect if that _causes_ an error during linking (for example, if GCC is too
old to understand the flag, and returns an error) and will then retry linking without this argument,
as a fallback.

If the user _also_ passes a `-Clink-arg=-fuse-ld=$value`, both will be given to the linker
driver but the user's will be passed last, and would generally have priority over `rustc`'s.

## linker-flavor

This flag controls the linker flavor used by `rustc`. If a linker is given with
the [`-C linker` flag](#linker), then the linker flavor is inferred from the
value provided. If no linker is given then the linker flavor is used to
determine the linker to use. Every `rustc` target defaults to some linker
flavor. Valid options are:

* `em`: use [Emscripten `emcc`](https://emscripten.org/docs/tools_reference/emcc.html).
* `gcc`: use the `cc` executable, which is typically gcc or clang on many systems.
* `ld`: use the `ld` executable.
* `msvc`: use the `link.exe` executable from Microsoft Visual Studio MSVC.
* `wasm-ld`: use the [`wasm-ld`](https://lld.llvm.org/WebAssembly.html)
  executable, a port of LLVM `lld` for WebAssembly.
* `ld64.lld`: use the LLVM `lld` executable with the [`-flavor darwin`
  flag][lld-flavor] for Apple's `ld`.
* `ld.lld`: use the LLVM `lld` executable with the [`-flavor gnu`
  flag][lld-flavor] for GNU binutils' `ld`.
* `lld-link`: use the LLVM `lld` executable with the [`-flavor link`
  flag][lld-flavor] for Microsoft's `link.exe`.

[lld-flavor]: https://releases.llvm.org/12.0.0/tools/lld/docs/Driver.html

## linker-plugin-lto

This flag defers LTO optimizations to the linker. See
[linker-plugin-LTO](../linker-plugin-lto.md) for more details. It takes one of
the following values:

* `y`, `yes`, `on`, `true` or no value: enable linker plugin LTO.
* `n`, `no`, `off` or `false`: disable linker plugin LTO (the default).
* A path to the linker plugin.

More specifically this flag will cause the compiler to replace its typical
object file output with LLVM bitcode files. For example an rlib produced with
`-Clinker-plugin-lto` will still have `*.o` files in it, but they'll all be LLVM
bitcode instead of actual machine code. It is expected that the native platform
linker is capable of loading these LLVM bitcode files and generating code at
link time (typically after performing optimizations).

Note that rustc can also read its own object files produced with
`-Clinker-plugin-lto`. If an rlib is only ever going to get used later with a
`-Clto` compilation then you can pass `-Clinker-plugin-lto` to speed up
compilation and avoid generating object files that aren't used.

## llvm-args

This flag can be used to pass a list of arguments directly to LLVM.

The list must be separated by spaces.

Pass `--help` to see a list of options.

<div class="warning">

Because this flag directly talks to LLVM, it is not subject to the usual stability guarantees of rustc's CLI interface.

</div>

## lto

This flag controls whether LLVM uses [link time
optimizations](https://llvm.org/docs/LinkTimeOptimization.html) to produce
better optimized code, using whole-program analysis, at the cost of longer
linking time. It takes one of the following values:

* `y`, `yes`, `on`, `true`, `fat`, or no value: perform "fat" LTO which attempts to
  perform optimizations across all crates within the dependency graph.
* `thin`: perform ["thin"
  LTO](http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html).
  This is similar to "fat", but takes substantially less time to run while
  still achieving performance gains similar to "fat".
  For larger projects like the Rust compiler, ThinLTO can even result in better performance than fat LTO.
* `n`, `no`, `off`, `false`: disables LTO.

If `-C lto` is not specified, then the compiler will attempt to perform "thin
local LTO" which performs "thin" LTO on the local crate only across its
[codegen units](#codegen-units). When `-C lto` is not specified, LTO is
disabled if codegen units is 1 or optimizations are disabled ([`-C
opt-level=0`](#opt-level)). That is:

* When `-C lto` is not specified:
  * `codegen-units=1`: disable LTO.
  * `opt-level=0`: disable LTO.
* When `-C lto` is specified:
  * `lto`: 16 codegen units, perform fat LTO across crates.
  * `codegen-units=1` + `lto`: 1 codegen unit, fat LTO across crates.

See also [linker-plugin-lto](#linker-plugin-lto) for cross-language LTO.

## metadata

This option allows you to control the metadata used for symbol mangling. This
takes a space-separated list of strings. Mangled symbols will incorporate a
hash of the metadata. This may be used, for example, to differentiate symbols
between two different versions of the same crate being linked.

## no-prepopulate-passes

This flag tells the pass manager to use an empty list of passes, instead of the
usual pre-populated list of passes.

When combined with `-O --emit llvm-ir`, it can be used to see the optimized LLVM IR emitted by rustc before any optimizations are applied by LLVM.

## no-redzone

This flag allows you to disable [the
red zone](https://en.wikipedia.org/wiki/Red_zone_\(computing\)). It takes one
of the following values:

* `y`, `yes`, `on`, `true` or no value: disable the red zone.
* `n`, `no`, `off` or `false`: enable the red zone.

The default behaviour, if the flag is not specified, depends on the target.

## no-vectorize-loops

This flag disables [loop
vectorization](https://llvm.org/docs/Vectorizers.html#the-loop-vectorizer).

## no-vectorize-slp

This flag disables vectorization using
[superword-level
parallelism](https://llvm.org/docs/Vectorizers.html#the-slp-vectorizer).

## opt-level

This flag controls the optimization level.

* `0`: no optimizations, also turns on
  [`cfg(debug_assertions)`](#debug-assertions) (the default).
* `1`: basic optimizations.
* `2`: some optimizations.
* `3`: all optimizations.
* `s`: optimize for binary size.
* `z`: optimize for binary size, but more aggressively. Often results in larger binaries than `s`

Note: The [`-O` flag][option-o-optimize] is an alias for `-C opt-level=3`.

The default is `0`.

## overflow-checks

This flag allows you to control the behavior of [runtime integer
overflow](../../reference/expressions/operator-expr.md#overflow). When
overflow-checks are enabled, a panic will occur on overflow. This flag takes
one of the following values:

* `y`, `yes`, `on`, `true` or no value: enable overflow checks.
* `n`, `no`, `off` or `false`: disable overflow checks.

If not specified, overflow checks are enabled if
[debug-assertions](#debug-assertions) are enabled, disabled otherwise.

## panic

This option lets you control what happens when the code panics.

* `abort`: terminate the process upon panic
* `immediate-abort`: terminate the process upon panic, and do not call any panic hooks
* `unwind`: unwind the stack upon panic

If not specified, the default depends on the target.

If any crate in the crate graph uses `abort`, the final binary (`bin`, `dylib`, `cdylib`, `staticlib`) must also use `abort`.
If any crate in the crate graph uses `immediate-abort`, every crate in the graph must use `immediate-abort`.
If `std` is used as a `dylib` with `unwind`, the final binary must also use `unwind`.

## passes

This flag can be used to add extra [LLVM
passes](http://llvm.org/docs/Passes.html) to the compilation.

The list must be separated by spaces.

See also the [`no-prepopulate-passes`](#no-prepopulate-passes) flag.

<div class="warning">

Because this flag directly talks to LLVM, it not subject to the usual stability guarantees of rustc's CLI interface.

</div>

## prefer-dynamic

By default, `rustc` prefers to statically link dependencies. This option will
indicate that dynamic linking should be used if possible if both a static and
dynamic versions of a library are available.

There is [an internal algorithm](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_metadata/src/dependency_format.rs)
for determining whether or not it is possible to statically or dynamically link
with a dependency.

This flag takes one of the following values:

* `y`, `yes`, `on`, `true` or no value: prefer dynamic linking.
* `n`, `no`, `off` or `false`: prefer static linking (the default).

## profile-generate

This flag allows for creating instrumented binaries that will collect
profiling data for use with profile-guided optimization (PGO). The flag takes
an optional argument which is the path to a directory into which the
instrumented binary will emit the collected data. See the chapter on
[profile-guided optimization] for more information.

## profile-sample-use

This flag specifies the profiling data file to be used for sample-based
profile-guided optimization (SPGO). The flag takes a mandatory argument which
is the path to a valid `.prof` file. See the chapter on
[profile-guided optimization] for more information.
The `-Zdebuginfo-for-profiling` can be used to improve the quality of the
profiling data.

## profile-use

This flag specifies the profiling data file to be used for profile-guided
optimization (PGO). The flag takes a mandatory argument which is the path
to a valid `.profdata` file. See the chapter on
[profile-guided optimization] for more information.

## relocation-model

This option controls generation of
[position-independent code (PIC)](https://en.wikipedia.org/wiki/Position-independent_code).

Supported values for this option are:

#### Primary relocation models

- `static` - non-relocatable code, machine instructions may use absolute addressing modes.

- `pic` - fully relocatable position independent code,
machine instructions need to use relative addressing modes.  \
Equivalent to the "uppercase" `-fPIC` or `-fPIE` options in other compilers,
depending on the produced crate types.  \
This is the default model for majority of supported targets.

- `pie` - position independent executable, relocatable code but without support for symbol
interpositioning (replacing symbols by name using `LD_PRELOAD` and similar). Equivalent to the "uppercase" `-fPIE` option in other compilers. `pie`
code cannot be linked into shared libraries (you'll get a linking error on attempt to do this).

#### Special relocation models

- `dynamic-no-pic` - relocatable external references, non-relocatable code.  \
Only makes sense on Darwin and is rarely used.  \
If StackOverflow tells you to use this as an opt-out of PIC or PIE, don't believe it,
use `-C relocation-model=static` instead.
- `ropi`, `rwpi` and `ropi-rwpi` - relocatable code and read-only data, relocatable read-write data,
and combination of both, respectively.  \
Only makes sense for certain embedded ARM targets.
- `default` - relocation model default to the current target.  \
Only makes sense as an override for some other explicitly specified relocation model
previously set on the command line.

Supported values can also be discovered by running `rustc --print relocation-models`.

#### Linking effects

In addition to codegen effects, `relocation-model` has effects during linking.

If the relocation model is `pic` and the current target supports position-independent executables
(PIE), the linker will be instructed (`-pie`) to produce one.  \
If the target doesn't support both position-independent and statically linked executables,
then `-C target-feature=+crt-static` "wins" over `-C relocation-model=pic`,
and the linker is instructed (`-static`) to produce a statically linked
but not position-independent executable.

## relro-level

This flag controls what level of RELRO (Relocation Read-Only) is enabled. RELRO is an exploit
mitigation which makes the Global Offset Table (GOT) read-only.

Supported values for this option are:

- `off`: Dynamically linked functions are resolved lazily and the GOT is writable.
- `partial`: Dynamically linked functions are resolved lazily and written into the Procedure
  Linking Table (PLT) part of the GOT (`.got.plt`). The non-PLT part of the GOT (`.got`) is made
  read-only and both are moved to prevent writing from buffer overflows.
- `full`: Dynamically linked functions are resolved at the start of program execution and the
  Global Offset Table (`.got`/`.got.plt`) is populated eagerly and then made read-only. The GOT is
  also moved to prevent writing from buffer overflows. Full RELRO uses more memory and increases
  process startup time.

This flag is ignored on platforms where RELRO is not supported (targets which do not use the ELF
binary format), such as Windows or macOS. Each rustc target has its own default for RELRO. rustc
enables Full RELRO by default on platforms where it is supported.

## remark

This flag lets you print remarks for optimization passes.

The list of passes should be separated by spaces.

`all` will remark on every pass.

## rpath

This flag controls whether rustc sets an [`rpath`](https://en.wikipedia.org/wiki/Rpath) for the binary.
It takes one of the following values:

* `y`, `yes`, `on`, `true` or no value: enable rpath.
* `n`, `no`, `off` or `false`: disable rpath (the default).

This flag only does something on Unix-like platforms (Mach-O and ELF), it is ignored on other platforms.

If enabled, rustc will add output-relative (using `@load_path` on Mach-O and `$ORIGIN` on ELF respectively) rpaths to all `dylib` dependencies.

For example, for the following directory structure, with `libdep.so` being a `dylib` crate compiled with `-Cprefer-dynamic`:

```text
dep
 |- libdep.so
a.rs
```

`rustc a.rs --extern dep=dep/libdep.so -Crpath` will, on x86-64 Linux, result in approximately the following `DT_RUNPATH`: `$ORIGIN/dep:$ORIGIN/$RELATIVE_PATH_TO_SYSROOT/lib/rustlib/x86_64-unknown-linux-gnu/lib` (where `RELATIVE_PATH_TO_SYSROOT` depends on the build directory location).

This is primarily useful for local development, to ensure that all the `dylib` dependencies can be found appropriately.

To set the rpath to a different value (which can be useful for distribution), `-Clink-arg` with a platform-specific linker argument can be used to set the rpath directly.

## save-temps

This flag controls whether temporary files generated during compilation are
deleted once compilation finishes. It takes one of the following values:

* `y`, `yes`, `on`, `true` or no value: save temporary files.
* `n`, `no`, `off` or `false`: delete temporary files (the default).

## split-debuginfo

This option controls the emission of "split debuginfo" for debug information
that `rustc` generates. The default behavior of this option is
platform-specific, and not all possible values for this option work on all
platforms. Possible values are:

* `off` - This is the default for platforms with ELF binaries and windows-gnu
  (not Windows MSVC and not macOS). This typically means that DWARF debug
  information can be found in the final artifact in sections of the executable.
  This option is not supported on Windows MSVC. On macOS this options prevents
  the final execution of `dsymutil` to generate debuginfo.

* `packed` - This is the default for Windows MSVC and macOS. The term
  "packed" here means that all the debug information is packed into a separate
  file from the main executable. On Windows MSVC this is a `*.pdb` file, on
  macOS this is a `*.dSYM` folder, and on other platforms this is a `*.dwp`
  file.

* `unpacked` - This means that debug information will be found in separate
  files for each compilation unit (object file). This is not supported on
  Windows MSVC. On macOS this means the original object files will contain
  debug information. On other Unix platforms this means that `*.dwo` files will
  contain debug information.

Note that all three options are supported on Linux and Apple platforms,
`packed` is supported on Windows-MSVC, and all other platforms support `off`.
Attempting to use an unsupported option requires using the nightly channel
with the `-Z unstable-options` flag.

## strip

The option `-C strip=val` controls stripping of debuginfo and similar auxiliary
data from binaries during linking.

Supported values for this option are:

- `none` - debuginfo and symbols are not modified.
- `debuginfo` - debuginfo sections and debuginfo symbols from the symbol table
  section are stripped at link time and are not copied to the produced binary.
  This should leave backtraces mostly-intact but may make using a debugger like
  gdb or lldb ineffectual. Prior to 1.79, this unintentionally disabled the
  generation of `*.pdb` files on MSVC, resulting in the absence of symbols.
- `symbols` - same as `debuginfo`, but the rest of the symbol table section is
  stripped as well, depending on platform support. On platforms which depend on
  this symbol table for backtraces, profiling, and similar, this can affect
  them so negatively as to make the trace incomprehensible. Programs which may
  be combined with others, such as CLI pipelines and developer tooling, or even
  anything which wants crash-reporting, should usually avoid `-Cstrip=symbols`.

Note that, at any level, removing debuginfo only necessarily impacts "friendly"
introspection. `-Cstrip` cannot be relied on as a meaningful security or
obfuscation measure, as disassemblers and decompilers can extract considerable
information even in the absence of symbols.

## symbol-mangling-version

This option controls the [name mangling] format for encoding Rust item names
for the purpose of generating object code and linking.

Supported values for this option are:

* `v0` — The "v0" mangling scheme.

The default, if not specified, will use a compiler-chosen default which may
change in the future.

See the [Symbol Mangling] chapter for details on symbol mangling and the mangling format.

[name mangling]: https://en.wikipedia.org/wiki/Name_mangling
[Symbol Mangling]: ../symbol-mangling/index.md

## target-cpu

This instructs `rustc` to generate code specifically for a particular processor.

You can run `rustc --print target-cpus` to see the valid options to pass
and the default target CPU for the current build target.
Each target has a default base CPU. Special values include:

* `native` can be passed to use the processor of the host machine.
* `generic` refers to an LLVM target with minimal features but modern tuning.

## target-feature

Individual targets will support different features; this flag lets you control
enabling or disabling a feature. Each feature should be prefixed with a `+` to
enable it or `-` to disable it.

Features from multiple `-C target-feature` options are combined. \
Multiple features can be specified in a single option by separating them
with commas - `-C target-feature=+x,-y`. \
If some feature is specified more than once with both `+` and `-`,
then values passed later override values passed earlier. \
For example, `-C target-feature=+x,-y,+z -Ctarget-feature=-x,+y`
is equivalent to `-C target-feature=-x,+y,+z`.

To see the valid options and an example of use, run `rustc --print
target-features`.

Using this flag is unsafe and might result in [undefined runtime
behavior](../targets/known-issues.md).

See also the [`target_feature`
attribute](../../reference/attributes/codegen.md#the-target_feature-attribute)
for controlling features per-function.

This also supports the feature `+crt-static` and `-crt-static` to control
[static C runtime linkage](../../reference/linkage.html#static-and-dynamic-c-runtimes).

Each target and [`target-cpu`](#target-cpu) has a default set of enabled
features.

## tune-cpu

This instructs `rustc` to schedule code specifically for a particular
processor. This does not affect the compatibility (instruction sets or ABI),
but should make your code slightly more efficient on the selected CPU.

The valid options are the same as those for [`target-cpu`](#target-cpu).
The default is `None`, which LLVM translates as the `target-cpu`.

This is an unstable option. Use `-Z tune-cpu=machine` to specify a value.

Due to limitations in LLVM (12.0.0-git9218f92), this option is currently
effective only for x86 targets.

[option-emit]: ../command-line-arguments.md#option-emit
[option-o-optimize]: ../command-line-arguments.md#option-o-optimize
[instrumentation-based code coverage]: ../instrument-coverage.md
[profile-guided optimization]: ../profile-guided-optimization.md
[option-g-debug]: ../command-line-arguments.md#option-g-debug

---

### Src Doc Rustc Src Lints Index (`src/doc/rustc/src/lints/index.md`)

# Lints

In software, a "lint" is a tool used to help improve your source code. The
Rust compiler contains a number of lints, and when it compiles your code, it will
also run the lints. These lints may produce a warning, an error, or nothing at all,
depending on how you've configured things.

Here's a small example:

```bash
$ cat main.rs
fn main() {
    let x = 5;
}
$ rustc main.rs
warning: unused variable: `x`
 --> main.rs:2:9
  |
2 |     let x = 5;
  |         ^
  |
  = note: `#[warn(unused_variables)]` on by default
  = note: to avoid this warning, consider using `_x` instead
```

This is the `unused_variables` lint, and it tells you that you've introduced
a variable that you don't use in your code. That's not *wrong*, so it's not
an error, but it might be a bug, so you get a warning.

## Future-incompatible lints

Sometimes the compiler needs to be changed to fix an issue that can cause
existing code to stop compiling. "Future-incompatible" lints are issued in
these cases to give users of Rust a smooth transition to the new behavior.
Initially, the compiler will continue to accept the problematic code and issue
a warning. The warning has a description of the problem, a notice that this
will become an error in the future, and a link to a tracking issue that
provides detailed information and an opportunity for feedback. This gives
users some time to fix the code to accommodate the change. After some time,
the warning may become an error.

The following is an example of what a future-incompatible looks like:

```text
warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
  --> lint_example.rs:11:13
   |
11 |     let y = &x.data.0;
   |             ^^^^^^^^^
   |
   = note: `#[warn(safe_packed_borrows)]` on by default
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
   = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
```

For more information about the process and policy of future-incompatible
changes, see [RFC 1589].

[RFC 1589]: https://rust-lang.github.io/rfcs/1589-rustc-bug-fix-procedure.html

---

### Src Doc Rustc Src Symbol Mangling Index (`src/doc/rustc/src/symbol-mangling/index.md`)

# Symbol Mangling

[Symbol name mangling] is used by `rustc` to encode a unique name for symbols that are used during code generation.
The encoded names are used by the linker to associate the name with the thing it refers to.

The method for mangling the names can be controlled with the [`-C symbol-mangling-version`] option.

[Symbol name mangling]: https://en.wikipedia.org/wiki/Name_mangling
[`-C symbol-mangling-version`]: ../codegen-options/index.md#symbol-mangling-version

## Per-item control

The [`#[no_mangle]` attribute][reference-no_mangle] can be used on items to disable name mangling on that item.

The [`#[export_name]`attribute][reference-export_name] can be used to specify the exact name that will be used for a function or static.

Items listed in an [`extern` block][reference-extern-block] use the identifier of the item without mangling to refer to the item.
The [`#[link_name]` attribute][reference-link_name] can be used to change that name.

### WebAssembly import modules

On WebAssembly targets, foreign items in `extern` blocks can use the same import name without
conflicting when they use different [`#[link(wasm_import_module = "...")]`][reference-link-attribute]
values.

[reference-no_mangle]: ../../reference/abi.html#the-no_mangle-attribute
[reference-export_name]: ../../reference/abi.html#the-export_name-attribute
[reference-link_name]: ../../reference/items/external-blocks.html#the-link_name-attribute
[reference-link-attribute]: ../../reference/items/external-blocks.html#the-link-attribute
[reference-extern-block]: ../../reference/items/external-blocks.html

## Decoding

The encoded names may need to be decoded in some situations.
For example, debuggers and other tooling may need to demangle the name so that it is more readable to the user.
Recent versions of `gdb` and `lldb` have built-in support for demangling Rust identifiers.
In situations where you need to do your own demangling, the [`rustc-demangle`] crate can be used to programmatically demangle names.
[`rustfilt`] is a CLI tool which can demangle names.

An example of running rustfilt:

```text
$ rustfilt _RNvCskwGfYPst2Cb_3foo16example_function
foo::example_function
```

[`rustc-demangle`]: https://crates.io/crates/rustc-demangle
[`rustfilt`]: https://crates.io/crates/rustfilt

## Mangling versions

There is currently one stable mangling scheme version - `v0`. On nightly builds, rustc supports
switching back to the `legacy` mangling scheme using [`-C symbol-mangling-version`]. The `v0`
mangling scheme is described in the [v0 Symbol Format](v0.md) chapter.

---

### Src Doc Rustc Src Targets Index (`src/doc/rustc/src/targets/index.md`)

# Targets

`rustc` is a cross-compiler by default. This means that you can use any compiler to build for any
architecture. The list of *targets* are the possible architectures that you can build for. See
the [Platform Support](../platform-support.md) page for a detailed list of targets, or
[Built-in Targets](built-in.md) for instructions on how to view what is available for your version
of `rustc`.

To see all the options that you can set with a target, see the docs
[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/struct.Target.html).

To compile to a particular target, use the `--target` flag:

```bash
$ rustc src/main.rs --target=wasm32-unknown-unknown
```
## Target Features
`x86`,  and `ARMv8` are two popular CPU architectures. Their instruction sets form a common baseline across most CPUs. However, some CPUs extend these with custom instruction sets, e.g. vector (`AVX`), bitwise manipulation (`BMI`) or cryptographic (`AES`).

Developers, who know on which CPUs their compiled code is going to run can choose to add (or remove) CPU specific instruction sets via the `-C target-feature=val` flag.

Please note, that this flag is generally considered as unsafe. More details can be found in [this section](known-issues.md).

---

### Src Doc Rustc Src Tests Index (`src/doc/rustc/src/tests/index.md`)

# Tests

`rustc` has a built-in facility for building and running tests for a crate.
More information about writing and running tests may be found in the [Testing
Chapter] of the Rust Programming Language book.

Tests are written as free functions with the [`#[test]`
attribute][attribute-test]. For example:

```rust
#[test]
fn it_works() {
    assert_eq!(2 + 2, 4);
}
```

Tests "pass" if they return without an error. They "fail" if they [panic], or
return a type such as [`Result`] that implements the [`Termination`] trait
with a non-zero value.

By passing the [`--test` option] to `rustc`, the compiler will build the crate
in a special mode to construct an executable that will run the tests in the
crate. The `--test` flag will make the following changes:

* The crate will be built as a `bin` [crate type], forcing it to be an
  executable.
* Links the executable with [`libtest`], the test harness that is part of the
  standard library, which handles running the tests.
* Synthesizes a [`main` function] which will process command-line arguments
  and run the tests. This new `main` function will replace any existing `main`
  function as the entry point of the executable, though the existing `main`
  will still be compiled.
* Enables the [`test` cfg option], which allows your code to use conditional
  compilation to detect if it is being built as a test.
* Enables building of functions annotated with the [`test`][attribute-test]
  and [`bench`](#benchmarks) attributes, which will be run by the test
  harness.

After the executable is created, you can run it to execute the tests and
receive a report on what passes and fails. If you are using [Cargo] to manage
your project, it has a built-in [`cargo test`] command which handles all of
this automatically. An example of the output looks like this:

```text
running 4 tests
test it_works ... ok
test check_valid_args ... ok
test invalid_characters ... ok
test walks_the_dog ... ok

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
```

> **Note**: Tests must be built with the [`unwind` panic
> strategy][panic-strategy]. This is because all tests run in the same
> process, and they are intended to catch panics, which is not possible with
> the `abort` strategy. See the unstable [`-Z panic-abort-tests`] option for
> experimental support of the `abort` strategy by spawning tests in separate
> processes.

## Test attributes

Tests are indicated using attributes on free functions. The following
attributes are used for testing, see the linked documentation for more
details:

* [`#[test]`][attribute-test] — Indicates a function is a test to be run.
* `#[bench]` — Indicates a function is a benchmark to be
  run. Benchmarks are currently unstable and only available in the nightly
  channel, see the [unstable docs][bench-docs] for more details.
* [`#[should_panic]`][attribute-should_panic] — Indicates that the test
  function will only pass if the function [panics][panic].
* [`#[ignore]`][attribute-ignore] — Indicates that the test function will be
  compiled, but not run by default. See the [`--ignored`](#--ignored) and
  [`--include-ignored`](#--include-ignored) options to run these tests.

## CLI arguments

The libtest harness has several command-line arguments to control its
behavior.

> Note: When running with [`cargo test`], the libtest CLI arguments must be
> passed after the `--` argument to differentiate between flags for Cargo and
> those for the harness. For example: `cargo test -- --no-capture`

### Filters

Positional arguments (those without a `-` prefix) are treated as filters which
will only run tests whose name matches one of those strings. The filter will
match any substring found in the full path of the test function. For example,
if the test function `it_works` is located in the module
`utils::paths::tests`, then any of the filters `works`, `path`, `utils::`, or
`utils::paths::tests::it_works` will match that test.

See [Selection options](#selection-options) for more options to control which
tests are run.

### Action options

The following options perform different actions other than running tests.

#### `--list`

Prints a list of all tests and benchmarks. Does not run any of the tests.
[Filters](#filters) can be used to list only matching tests.

#### `-h`, `--help`

Displays usage information and command-line options.

### Selection options

The following options change how tests are selected.

#### `--test`

This is the default mode where all tests will be run as well as running all
benchmarks with only a single iteration (to ensure the benchmark works,
without taking the time to actually perform benchmarking). This can be
combined with the `--bench` flag to run both tests and perform full
benchmarking.

#### `--bench`

This runs in a mode where tests are ignored, and only runs benchmarks. This
can be combined with `--test` to run both benchmarks and tests.

#### `--exact`

This forces [filters](#filters) to match the full path of the test exactly.
For example, if the test `it_works` is in the module `utils::paths::tests`,
then only the string `utils::paths::tests::it_works` will match that test.

#### `--skip` _FILTER_

Skips any tests whose name contains the given _FILTER_ string. This flag may
be passed multiple times.

#### `--ignored`

Runs only tests that are marked with the [`ignore`
attribute][attribute-ignore].

#### `--include-ignored`

Runs both [ignored](#--ignored) and non-ignored tests.

#### `--exclude-should-panic`

Excludes tests marked with the [`should_panic`
attribute][attribute-should_panic].

⚠️ 🚧 This option is [unstable](#unstable-options), and requires the `-Z
unstable-options` flag. See [tracking issue
#82348](https://github.com/rust-lang/rust/issues/82348) for more information.

### Execution options

The following options affect how tests are executed.

#### `--fail-fast`

Stops tests after the first failure.

If running tests in parallel (which is the default), then tests that have already been started on
other threads will be allowed to run to completion before the process exits.

Note that when running tests in parallel, the test execution order is non-deterministic:
if multiple tests would fail, the first failure encountered will be reported.

⚠️ 🚧 This requires the `-Z unstable-options` flag.

#### `--test-threads` _NUM_THREADS_

Sets the number of threads to use for running tests in parallel. By default,
uses the amount of concurrency available on the hardware as indicated by
[`available_parallelism`].

Deprecated: this can also be specified with the `RUST_TEST_THREADS` environment variable.

#### `--force-run-in-process`

Forces the tests to run in a single process when using the [`abort` panic
strategy][panic-strategy].

⚠️ 🚧 This only works with the unstable [`-Z panic-abort-tests`] option, and
requires the `-Z unstable-options` flag. See [tracking issue
#67650](https://github.com/rust-lang/rust/issues/67650) for more information.

#### `--ensure-time`

⚠️ 🚧 This option is [unstable](#unstable-options), and requires the `-Z
unstable-options` flag. See [tracking issue
#64888](https://github.com/rust-lang/rust/issues/64888) and the [unstable
docs](../../unstable-book/compiler-flags/report-time.html) for more information.

#### `--shuffle`

Runs the tests in random order, as opposed to the default alphabetical order.

Deprecated: this may also be specified by setting the `RUST_TEST_SHUFFLE` environment
variable to anything but `0`.

The random number generator seed that is output can be passed to
[`--shuffle-seed`](#--shuffle-seed-seed) to run the tests in the same order
again.

Note that `--shuffle` does not affect whether the tests are run in parallel. To
run the tests in random order sequentially, use `--shuffle --test-threads 1`.

⚠️ 🚧 This option is [unstable](#unstable-options), and requires the `-Z
unstable-options` flag. See [tracking issue
#89583](https://github.com/rust-lang/rust/issues/89583) for more information.

#### `--shuffle-seed` _SEED_

Like [`--shuffle`](#--shuffle), but seeds the random number generator with
_SEED_. Thus, calling the test harness with `--shuffle-seed` _SEED_ twice runs
the tests in the same order both times.

_SEED_ is any 64-bit unsigned integer, for example, one produced by
[`--shuffle`](#--shuffle).

Deprecated: this can also be specified with the `RUST_TEST_SHUFFLE_SEED` environment
variable.

⚠️ 🚧 This option is [unstable](#unstable-options), and requires the `-Z
unstable-options` flag. See [tracking issue
#89583](https://github.com/rust-lang/rust/issues/89583) for more information.

### Output options

The following options affect the output behavior.

#### `-q`, `--quiet`

Displays one character per test instead of one line per test. This is an alias
for [`--format=terse`](#--format-format).

#### `--no-capture`

Does not capture the stdout and stderr of the test, and allows tests to print
to the console. Usually the output is captured, and only displayed if the test
fails.

Deprecated: this may also be specified by setting the `RUST_TEST_NOCAPTURE` environment
variable to anything but `0`.

`--nocapture` is a deprecated alias for `--no-capture`.

#### `--show-output`

Displays the stdout and stderr of successful tests after all tests have run.

Contrast this with [`--no-capture`](#--no-capture) which allows tests to print
*while they are running*, which can cause interleaved output if there are
multiple tests running in parallel, `--show-output` ensures the output is
contiguous, but requires waiting for all tests to finish.

#### `--color` _COLOR_

Control when colored terminal output is used. Valid options:

* `auto`: Colorize if stdout is a tty and [`--no-capture`](#--no-capture) is not
  used. This is the default.
* `always`: Always colorize the output.
* `never`: Never colorize the output.

#### `--format` _FORMAT_

Controls the format of the output. Valid options:

* `pretty`: This is the default format, with one line per test.
* `terse`: Displays only a single character per test. [`--quiet`](#-q---quiet)
  is an alias for this option.
* `json`: Emits JSON objects, one per line. ⚠️ 🚧 This option is
  [unstable](#unstable-options), and requires the `-Z unstable-options` flag.
  See [tracking issue #49359](https://github.com/rust-lang/rust/issues/49359)
  for more information.

#### `--logfile` _PATH_

Writes the results of the tests to the given file.

This option is deprecated.

#### `--report-time`

⚠️ 🚧 This option is [unstable](#unstable-options), and requires the `-Z
unstable-options` flag. See [tracking issue
#64888](https://github.com/rust-lang/rust/issues/64888) and the [unstable
docs](../../unstable-book/compiler-flags/report-time.html) for more information.

### Unstable options

Some CLI options are added in an "unstable" state, where they are intended for
experimentation and testing to determine if the option works correctly, has
the right design, and is useful. The option may not work correctly, break, or
change at any time. To signal that you acknowledge that you are using an
unstable option, they require passing the `-Z unstable-options` command-line
flag.

## Benchmarks

The libtest harness supports running benchmarks for functions annotated with
the `#[bench]` attribute. Benchmarks are currently unstable, and only
available on the [nightly channel]. More information may be found in the
[unstable book][bench-docs].

## Custom test frameworks

Experimental support for using custom test harnesses is available on the
[nightly channel]. See [tracking issue
#50297](https://github.com/rust-lang/rust/issues/50297) and the
[custom_test_frameworks documentation] for more information.

[`--test` option]: ../command-line-arguments.md#option-test
[`-Z panic-abort-tests`]: https://github.com/rust-lang/rust/issues/67650
[`available_parallelism`]: ../../std/thread/fn.available_parallelism.html
[`cargo test`]: ../../cargo/commands/cargo-test.html
[`libtest`]: ../../test/index.html
[`main` function]: ../../reference/crates-and-source-files.html#main-functions
[`Result`]: ../../std/result/index.html
[`Termination`]: ../../std/process/trait.Termination.html
[`test` cfg option]: ../../reference/conditional-compilation.html#test
[attribute-ignore]: ../../reference/attributes/testing.html#the-ignore-attribute
[attribute-should_panic]: ../../reference/attributes/testing.html#the-should_panic-attribute
[attribute-test]: ../../reference/attributes/testing.html#the-test-attribute
[bench-docs]: ../../unstable-book/library-features/test.html
[Cargo]: ../../cargo/index.html
[crate type]: ../../reference/linkage.html
[custom_test_frameworks documentation]: ../../unstable-book/language-features/custom-test-frameworks.html
[nightly channel]: ../../book/appendix-07-nightly-rust.html
[panic-strategy]: ../../book/ch09-01-unrecoverable-errors-with-panic.html
[panic]: ../../book/ch09-01-unrecoverable-errors-with-panic.html
[Testing Chapter]: ../../book/ch11-00-testing.html

---

### Src Tools Rust Analyzer Docs Book README (`src/tools/rust-analyzer/docs/book/README.md`)

# rust-analyzer documentation

The rust analyzer manual uses [mdbook](https://rust-lang.github.io/mdBook/).

## Quick start

To run the documentation site locally:

```bash
cargo install --locked mdbook
cargo xtask codegen
cd docs/book
mdbook serve
# make changes to documentation files in doc/book/src
# ...
```

mdbook will rebuild the documentation as changes are made.

## Making updates

While not required, installing the mdbook binary can be helpful in order to see the changes.
Start with the mdbook [User Guide](https://rust-lang.github.io/mdBook/guide/installation.html) to familiarize yourself with the tool.

## Generated documentation

Four sections are generated dynamically: assists, configuration, diagnostics and features. Their content is found in the `generated.md` files
of the respective book section, for example `src/configuration_generated.md`, and are included in the book via mdbook's
[include](https://rust-lang.github.io/mdBook/format/mdbook.html#including-files) functionality. Generated files can be rebuilt by running the various
test cases that generate them, or by simply running all of the `rust-analyzer` tests with `cargo test` and `cargo xtask codegen`.

---

### Src Doc Rustc Dev Guide Src Building Bootstrapping Intro (`src/doc/rustc-dev-guide/src/building/bootstrapping/intro.md`)

# Bootstrapping the compiler

[*Bootstrapping*] is the process of using a compiler to compile itself.
More accurately, it means using an older compiler to compile a newer version of the same compiler.

This raises a chicken-and-egg paradox: where did the first compiler come from?
It must have been written in a different language.
In Rust's case, it was [written in OCaml][ocaml-compiler].
However, it was abandoned long ago, and the
only way to build a modern version of `rustc` is with a slightly less modern version.

This is exactly how Rust's bootstrap build system works: it downloads the current beta release of
`rustc`, then uses it to compile the new compiler.

In this section, we give a high-level overview of
[what Bootstrap does](./what-bootstrapping-does.md), followed by a high-level
introduction to [how Bootstrap does it](./how-bootstrap-does-it.md).

Additionally, see [debugging bootstrap](./debugging-bootstrap.md) to learn about debugging methods.

[*Bootstrapping*]: https://en.wikipedia.org/wiki/Bootstrapping_(compilers)
[ocaml-compiler]: https://github.com/rust-lang/rust/tree/ef75860a0a72f79f97216f8aaa5b388d98da6480/src/boot

---

### Src Doc Rustc Dev Guide Src Tests Codegen Backend Tests Intro (`src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/intro.md`)

# Codegen backend testing

See also the [Code generation](../../backend/codegen.md) chapter.

In addition to the primary LLVM codegen backend, the rust-lang/rust CI also runs tests of the [cranelift][cg_clif] and [GCC][cg_gcc] codegen backends in certain test jobs.

For more details on the tests involved, see:

- [Cranelift codegen backend tests](./cg_clif.md)
- [GCC codegen backend tests](./cg_gcc.md)

[cg_clif]: https://github.com/rust-lang/rustc_codegen_cranelift
[cg_gcc]: https://github.com/rust-lang/rustc_codegen_gcc

---

### Src Doc Rustc Src Lints Listing Index (`src/doc/rustc/src/lints/listing/index.md`)

# Lint Listing

This section lists out all of the lints, grouped by their default lint levels.

You can also see this list by running `rustc -W help`.

---

### Src Tools Rust Analyzer Docs Book Src README (`src/tools/rust-analyzer/docs/book/src/README.md`)

# rust-analyzer

rust-analyzer is a language server that provides IDE functionality for
writing Rust programs. You can use it with any editor that supports
the [Language Server
Protocol](https://microsoft.github.io/language-server-protocol/) (VS
Code, Vim, Emacs, Zed, etc).

rust-analyzer features include go-to-definition, find-all-references,
refactorings and code completion. rust-analyzer also supports
integrated formatting (with rustfmt) and integrated diagnostics (with
rustc and clippy).

Internally, rust-analyzer is structured as a set of libraries for
analyzing Rust code. See
[Architecture](https://rust-analyzer.github.io/book/contributing/architecture.html)
for more details.

To improve this document, send a pull request:
[https://github.com/rust-lang/rust-analyzer](https://github.com/rust-lang/rust-analyzer/blob/master/docs/book/README.md)

The manual is written in markdown and includes
some extra files which are generated from the source code. Run
`cargo test` and `cargo xtask codegen` to create these.

If you have questions about using rust-analyzer, please ask them in the
["IDEs and Editors"](https://users.rust-lang.org/c/ide/14) topic of Rust
users forum.

---

### Src Tools Rust Analyzer Docs Book Src Contributing README (`src/tools/rust-analyzer/docs/book/src/contributing/README.md`)

# Contributing Quick Start

rust-analyzer is an ordinary Rust project, which is organized as a Cargo workspace, builds on stable and doesn't depend on C libraries.
So, just

```bash
cargo test
```

should be enough to get you started!

To learn more about how rust-analyzer works, see [Architecture](architecture.md).
It also explains the high-level layout of the source code.
Do skim through that document.

We also publish rustdoc docs to <https://rust-lang.github.io/rust-analyzer/ide/>.
Note though, that the internal documentation is very incomplete.

Various organizational and process issues are discussed in this document.

# Getting in Touch

rust-analyzer is a part of the [RLS-2.0 working
group](https://github.com/rust-lang/compiler-team/tree/6a769c13656c0a6959ebc09e7b1f7c09b86fb9c0/working-groups/rls-2.0).
Discussion happens in this Zulip stream:

<https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer>

# Issue Labels

* [good-first-issue](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22good%20first%20issue%22)
  are good issues to get into the project.
* [E-has-instructions](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-has-instructions)
  issues have links to the code in question and tests.
* [Broken Window](https://github.com/rust-lang/rust-analyzer/issues?q=is:issue+is:open+label:%22Broken+Window%22)
  are issues which are not necessarily critical by themselves, but which should be fixed ASAP regardless, to avoid accumulation of technical debt.
* [E-easy](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy),
  [E-medium](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-medium),
  [E-hard](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-hard),
  [E-unknown](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-unknown),
  labels are *estimates* for how hard would be to write a fix. Each triaged issue should have one of these labels.
* [S-actionable](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AS-actionable) and
  [S-unactionable](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AS-unactionable)
  specify if there are concrete steps to resolve or advance an issue. Roughly, actionable issues need only work to be fixed,
  while unactionable ones are blocked either on user feedback (providing a reproducible example), or on larger architectural
  work or decisions. This classification is descriptive, not prescriptive, and might be wrong: Any unactionable issue might have a simple fix that we missed.
  Each triaged issue should have one of these labels.
* [fun](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3Afun)
  is for cool, but probably hard stuff.
* [C-Architecture](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aissue%20state%3Aopen%20label%3AC-Architecture)
  is for moderate/large scale architecture discussion.
  Also a kind of fun.
  These issues should generally include a link to a Zulip discussion thread.

# Code Style & Review Process

See the [Style Guide](style.md).

# Cookbook

## CI

We use GitHub Actions for CI.
Most of the things, including formatting, are checked by `cargo test`.
If `cargo test` passes locally, that's a good sign that CI will be green as well.
The only exception is that some long-running tests are skipped locally by default.
Use `env RUN_SLOW_TESTS=1 cargo test` to run the full suite.

We use bors to enforce the [not rocket science](https://graydon2.dreamwidth.org/1597.html) rule.

## Launching rust-analyzer

Debugging the language server can be tricky.
LSP is rather chatty, so driving it from the command line is not really feasible, driving it via VS Code requires interacting with two processes.

For this reason, the best way to see how rust-analyzer works is to **find a relevant test and execute it**.
VS Code & Emacs include an action for running a single test.

Launching a VS Code instance with a locally built language server is also possible.
There's **"Run Extension (Debug Build)"** launch configuration for this in VS Code.

In general, I use one of the following workflows for fixing bugs and implementing features:

If the problem concerns only internal parts of rust-analyzer (i.e. I don't need to touch the `rust-analyzer` crate or TypeScript code), there is a unit-test for it.
So, I use **rust-analyzer: Run** action in VS Code to run this single test, and then just do printf-driven development/debugging.
As a sanity check after I'm done, I use `cargo xtask install --server` and **Reload Window** action in VS Code to verify that the thing works as I expect.

If the problem concerns only the VS Code extension, I use **Run Installed Extension** launch configuration from `launch.json`.
Notably, this uses the usual `rust-analyzer` binary from `PATH`.
For this, it is important to have the following in your `settings.json` file:

```json
{
    "rust-analyzer.server.path": "rust-analyzer"
}
```

After I am done with the fix, I use `cargo xtask install --client` to try the new extension for real.

If I need to fix something in the `rust-analyzer` crate, I feel sad because it's on the boundary between the two processes, and working there is slow.
I usually just `cargo xtask install --server` and poke changes from my live environment.
Note that this uses `--release`, which is usually faster overall, because loading stdlib into debug version of rust-analyzer takes a lot of time.
To speed things up, sometimes I open a temporary hello-world project which has `"rust-analyzer.cargo.sysroot": null` in `.code/settings.json`.
This flag causes rust-analyzer to skip loading the sysroot, which greatly reduces the amount of things rust-analyzer needs to do, and makes printf's more useful.
Note that you should only use the `eprint!` family of macros for debugging: stdout is used for LSP communication, and `print!` would break it.

If I need to fix something simultaneously in the server and in the client, I feel even more sad.
I don't have a specific workflow for this case.

Additionally, I use `cargo run --release -p rust-analyzer -- analysis-stats path/to/some/rust/crate` to run a batch analysis.
This is primarily useful for performance optimizations, or for bug minimization.

## TypeScript Tests

If you change files under `editors/code` and would like to run the tests and linter, install npm and run:

```bash
cd editors/code
npm ci
npm run lint
```

## How to ...

* ... add an assist? [#7535](https://github.com/rust-lang/rust-analyzer/pull/7535)
* ... add a new protocol extension? [#4569](https://github.com/rust-lang/rust-analyzer/pull/4569)
* ... add a new configuration option? [#7451](https://github.com/rust-lang/rust-analyzer/pull/7451)
* ... add a new completion? [#6964](https://github.com/rust-lang/rust-analyzer/pull/6964)
* ... allow new syntax in the parser? [#7338](https://github.com/rust-lang/rust-analyzer/pull/7338)

## Logging

Logging is done by both rust-analyzer and VS Code, so it might be tricky to figure out where logs go.

Inside rust-analyzer, we use the [`tracing`](https://docs.rs/tracing/) crate for logging,
and [`tracing-subscriber`](https://docs.rs/tracing-subscriber) for logging frontend.
By default, log goes to stderr, but the stderr itself is processed by VS Code.
`--log-file <PATH>` CLI argument allows logging to file.
Setting the `RA_LOG_FILE=<PATH>` environment variable will also log to file, it will also override `--log-file`.

To see the server stderr output in the running VS Code instance, go to the "Output" tab of the panel
and select `rust-analyzer Language Server`.
This shows `eprintln!` as well.
Note that `stdout` is used by LSP messages, so using `println!`—or anything that writes to `stdout`—will break rust-analyzer!

To log all communication between the server and the client, there are two choices:

* You can log on the server side, by running something like

  ```bash
  env RA_LOG=lsp_server=debug code .
  ```

* You can log on the client side, by the `rust-analyzer: Toggle LSP Logs` command or enabling `"rust-analyzer.trace.server": "verbose"` workspace setting.
  These logs are shown in a separate tab named `rust-analyzer LSP Trace` in the output and could be used with LSP inspector.
  Kudos to [@DJMcNab](https://github.com/DJMcNab) for setting this awesome infra up!

Finally there are the logs of the VSCode extension itself which go into the `rust-analyzer Extension` output tab.

There are also several VS Code commands which might be of interest:

* `rust-analyzer: Status` shows some memory-usage statistics.

* `rust-analyzer: View Hir` shows the HIR expressions within the function containing the cursor.

* If `rust-analyzer.showSyntaxTree` is enabled in settings, `Rust Syntax Tree: Focus on Rust Syntax Tree View` shows the syntax tree of the current file.

  You can click on nodes in the rust editor to go to the corresponding syntax node.

  You can click on `Reveal Syntax Element` next to a syntax node to go to the corresponding rust code and highlight the proper text range.

  If you trigger Go to Definition in the inspected Rust source file,
  the syntax tree view should scroll to and select the
  appropriate syntax node token.

  You can click on `Copy` next to a syntax node to copy a text representation of the node.

  

## Profiling

We have a built-in hierarchical profiler, you can enable it by using `RA_PROFILE` env-var:

```bash
RA_PROFILE=*             // dump everything
RA_PROFILE=foo|bar|baz   // enabled only selected entries
RA_PROFILE=*@3>10        // dump everything, up to depth 3, if it takes more than 10 ms
```

Some rust-analyzer contributors have `export RA_PROFILE='*>10'` in my shell profile.

For machine-readable JSON output, we have the `RA_PROFILE_JSON` env variable. We support
filtering only by span name:

```bash
RA_PROFILE=* // dump everything
RA_PROFILE_JSON="vfs_load|parallel_prime_caches|discover_command" // dump selected spans
```

We also have a "counting" profiler which counts number of instances of popular structs.
It is enabled by `RA_COUNT=1`.

To measure time for from-scratch analysis, use something like this:

```bash
cargo run --release -p rust-analyzer -- analysis-stats ../chalk/
```

Look for `fn benchmark_xxx` tests for a quick way to reproduce performance problems.

## Release Process

Release process is handled by `release`, `dist`, `publish-release-notes` and `promote` xtasks, `release` being the main one.

`release` assumes that you have checkouts of `rust-analyzer`, `rust-analyzer.github.io`, and `rust-lang/rust` in the same directory:

```bash
./rust-analyzer
./rust-analyzer.github.io
./rust-rust-analyzer  # Note the name!
```

The remote for `rust-analyzer` must be called `upstream` (I use `origin` to point to my fork).
In addition, for `xtask promote` (see below), `rust-rust-analyzer` must have a `rust-analyzer` remote pointing to this repository on GitHub.

`release` calls the GitHub API calls to scrape pull request comments and categorize them in the changelog.
This step uses the `curl` and `jq` applications, which need to be available in `PATH`.
Finally, you need to obtain a GitHub personal access token and set the `GITHUB_TOKEN` environment variable.

Release steps:

1. Set the `GITHUB_TOKEN` environment variable.
2. Inside rust-analyzer, run `cargo xtask release`. This will:
   * checkout the `release` branch
   * reset it to `upstream/nightly`
   * push it to `upstream`. This triggers GitHub Actions which:
     * runs `cargo xtask dist` to package binaries and VS Code extension
     * makes a GitHub release
     * publishes the VS Code extension to the marketplace
   * call the GitHub API for PR details
   * create a new changelog in `rust-analyzer.github.io`
3. While the release is in progress, fill in the changelog.
4. Commit & push the changelog.
5. Run `cargo xtask publish-release-notes <CHANGELOG>` -- this will convert the changelog entry in AsciiDoc to Markdown and update the body of GitHub Releases entry.
6. Tweet.
7. Perform a subtree [pull](#performing-a-pull).
8. Perform a subtree [push](#performing-a-push).

If the GitHub Actions release fails because of a transient problem like a timeout, you can re-run the job from the Actions console.
If it fails because of something that needs to be fixed, remove the release tag (if needed), fix the problem, then start over.
Make sure to remove the new changelog post created when running `cargo xtask release` a second time.

We release "nightly" every night automatically and promote the latest nightly to "stable" manually, every week.

We don't do "patch" releases, unless something truly egregious comes up.
To do a patch release, cherry-pick the fix on top of the current `release` branch and push the branch.
There's no need to write a changelog for a patch release, it's OK to include the notes about the fix into the next weekly one.
Note: we tag releases by dates, releasing a patch release on the same day should work (by overwriting a tag), but I am not 100% sure.

## Permissions

There are two sets of people with extra permissions:

* The [rust-lang](https://github.com/rust-lang) team [t-rust-analyzer](https://github.com/rust-lang/team/blob/master/teams/rust-analyzer.toml).
  This team has write access to the repository and merge queue permissions (note the repo itself is managed by infra admins).
  It's ok to self-approve if you think you know what you are doing!
  Feel free to request a review or assign any PR to a reviewer with the relevant expertise to bring the work to their attention.
  Don't feel pressured to review assigned PRs though.
  If you don't feel like reviewing for whatever reason, someone else will pick the review up (but please speak up if you don't feel like it)!
* The [rust-lang](https://github.com/rust-lang) team [t-rust-analyzer-contributors](https://github.com/rust-lang/team/blob/master/teams/rust-analyzer-contributors.toml).
  This team has general triaging permissions allowing to label, close and re-open issues.

## Synchronizing subtree changes
`rust-analyzer` is a [josh](https://josh-project.github.io/josh/intro.html) subtree of the [rust-lang/rust](https://github.com/rust-lang/rust)
repository. We use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization between these two
repositories. You can find documentation of the tool [here](https://github.com/rust-lang/josh-sync).

You can install the synchronization tool using the following commands:

```bash
cargo install --locked --git https://github.com/rust-lang/josh-sync
```

Both pulls (synchronizing changes from rust-lang/rust into rust-analyzer) and pushes (synchronizing
changes from rust-analyzer into rust-lang/rust) are performed from this repository.
changes from rust-analyzer to rust-lang/rust) are performed from this repository.

Usually we first perform a pull, wait for it to be merged, and then perform a push.

### Performing a pull
1) Checkout a new branch that will be used to create a PR against rust-analyzer
2) Run the pull command
    ```
    rustc-josh-sync pull
    ```
3) Push the branch to your fork of `rust-analyzer` and create a PR
  - If you have the `gh` CLI installed, `rustc-josh-sync` can create the PR for you.

### Performing a push

Wait for the previous pull to be merged.

1) Switch to `master` and pull
2) Run the push command to create a branch named `<branch-name>` in a `rustc` fork under the `<gh-username>` account
    ```
    rustc-josh-sync push <branch-name> <gh-username>
    ```
   - The push will ask you to download a checkout of the `rust-lang/rust` repository.
   - If you get prompted for a password, see [this](https://github.com/rust-lang/josh-sync?tab=readme-ov-file#git-peculiarities).
3) Create a PR from `<branch-name>` into `rust-lang/rust`

> Besides the `rust` checkout, the Josh cache (stored under `~/.cache/rustc-josh`) will contain a bare clone of `rust-lang/rust`. This currently takes several GBs.

---

### Src Doc Complement Design Faq (`src/doc/complement-design-faq.md`)

% The Rust Design FAQ

This content has moved to [the website](https://www.rust-lang.org/).

---

### Src Doc Complement Lang Faq (`src/doc/complement-lang-faq.md`)

% The Rust Language FAQ

This content has moved to [the website](https://www.rust-lang.org/).

---

### Src Doc Complement Project Faq (`src/doc/complement-project-faq.md`)

% The Rust Project FAQ

This content has moved to [the website](https://www.rust-lang.org/).

---

### Src Doc Grammar (`src/doc/grammar.md`)

% Grammar

The Rust grammar may now be found in the [reference]. Additionally, the [grammar
working group] is working on producing a testable grammar.

[reference]: https://doc.rust-lang.org/reference/
[grammar working group]: https://github.com/rust-lang/wg-grammar

---

### Src Doc Guide Crates (`src/doc/guide-crates.md`)

% The (old) Rust Crates and Modules Guide

This content has moved into
[the Rust Programming Language book](book/crates-and-modules.html).

---

### Src Doc Guide Error Handling (`src/doc/guide-error-handling.md`)

% Error Handling in Rust

This content has moved into
[the Rust Programming Language book](book/ch09-00-error-handling.html).

---

### Src Doc Guide Ffi (`src/doc/guide-ffi.md`)

% The (old) Rust Foreign Function Interface Guide

This content has moved into
[the Rust Programming Language book](book/ffi.html).

---

### Src Doc Guide Macros (`src/doc/guide-macros.md`)

% The (old) Rust Macros Guide

This content has moved into
[the Rust Programming Language book](book/macros.html).

---

### Src Doc Guide Ownership (`src/doc/guide-ownership.md`)

% The (old) Rust Ownership Guide

This content has moved into
[the Rust Programming Language book](book/ch04-00-understanding-ownership.html).

---

### Src Doc Guide Pointers (`src/doc/guide-pointers.md`)

% The Rust Pointer Guide

This content has been removed, with no direct replacement. Rust only
has two built-in pointer types now,
[references](book/ch04-02-references-and-borrowing.html) and [raw
pointers](book/raw-pointers.html). Older Rusts had many more pointer
types, they’re gone now.

---

### Src Doc Guide Strings (`src/doc/guide-strings.md`)

% The (old) Guide to Rust Strings

This content has moved into
[the Rust Programming Language book](book/strings.html).

---

### Src Doc Guide Tasks (`src/doc/guide-tasks.md`)

% The (old) Rust Threads and Communication Guide

This content has moved into
[the Rust Programming Language book](book/concurrency.html).

---

### Src Doc Guide Testing (`src/doc/guide-testing.md`)

% The (old) Rust Testing Guide

This content has moved into
[the Rust Programming Language book](book/ch11-00-testing.html).

---

### Src Doc Guide Unsafe (`src/doc/guide-unsafe.md`)

% Writing Safe Low-level and Unsafe Code in Rust

This content has moved into
[the Rust Programming Language book](book/unsafe.html).

---

### Src Doc Guide (`src/doc/guide.md`)

% The (old) Rust Guide

This content has moved into
[the Rust Programming Language book](book/README.html).

---

### Src Doc Not Found (`src/doc/not_found.md`)

% Not Found


<style type="text/css">
#rustdoc-toc { display: none; }
.header-section-number { display: none; }
li {list-style-type: none; }
#search-input {
    width: calc(100% - 100px);
}
#search-but {
    cursor: pointer;
}
#search-but, #search-input {
    padding: 4px;
    border: 1px solid #ccc;
    border-radius: 3px;
    outline: none;
    font-size: 0.7em;
    background-color: #fff;
}
#search-but:hover, #search-input:focus {
    border-color: #55a9ff;
}
#search-from {
    border: none;
    padding: 0;
    font-size: 0.7em;
}
</style>

Looks like you've taken a wrong turn.

Some things that might be helpful to you though:

# Search

<div>
  <form id="search-form" action="https://duckduckgo.com/">
    <input id="search-input" type="search" name="q"></input>
    <input type="submit" value="Search" id="search-but">
    
    <fieldset id="search-from" style="display:none">
      <label><input name="from" value="library" type="radio"> From the Standard Library</label>
      <label><input name="from" value="duckduckgo" type="radio" checked> From DuckDuckGo</label>
    </fieldset>
  </form>
</div>

# Reference

 * [The Rust official site](https://www.rust-lang.org)
 * [The Rust reference](https://doc.rust-lang.org/reference/index.html)

# Docs

[The standard library](https://doc.rust-lang.org/std/)

<script>
function get_url_fragments() {
    var last = document.URL.split("/").pop();
    var tokens = last.split(".");
    var op = [];
    for (var i=0; i < tokens.length; i++) {
        var t = tokens[i];
        if (t == 'html' || t.indexOf("#") != -1) {
            // no html or anchors
        } else {
            op.push(t);
        }
    }
    return op;
}

function on_submit(event) {
    var form = event.target;
    var q = form['q'].value;

    event.preventDefault();

    if (form['from'].value === 'duckduckgo') {
        document.location.href = form.action + '?q=' + encodeURIComponent(q + ' site:doc.rust-lang.org');
    } else if (form['from'].value === 'library') {
        document.location.href = '/std/index.html?search=' + encodeURIComponent(q);
    }
}

function populate_search() {
    var form = document.getElementById('search-form');
    form.addEventListener('submit', on_submit);
    document.getElementById('search-from').style.display = '';

    form['from'].value = 'library';

    var op = get_url_fragments();
    document.getElementById('search-input').value = op.join(' ');
}
populate_search();
</script>

---

### Src Doc Reference (`src/doc/reference.md`)

% The Rust Reference has moved

We've split up the reference into chapters. Please find it at its new
home [here](https://doc.rust-lang.org/stable/reference/introduction.html).

---

### Src Doc Robots (`src/doc/robots.txt`)

User-agent: *
Disallow: /1.
Disallow: /0.
Disallow: /book/first-edition/
Disallow: /book/second-edition/
Disallow: /stable/book/first-edition/
Disallow: /stable/book/second-edition/
Disallow: /beta/book/first-edition/
Disallow: /beta/book/second-edition/
Disallow: /nightly/book/first-edition/
Disallow: /nightly/book/second-edition/

Sitemap: https://doc.rust-lang.org/sitemap.txt

---

### Src Doc Rust (`src/doc/rust.md`)

% The Rust Reference Manual

The manual has moved, and is now called [the reference](reference/index.html).

---

### Src Doc Rustdoc (`src/doc/rustdoc.md`)

% Rust Documentation

This has been moved [into the rustdoc book](rustdoc/index.html).

---

### Src Doc Sitemap (`src/doc/sitemap.txt`)

https://doc.rust-lang.org/stable/
https://doc.rust-lang.org/beta/
https://doc.rust-lang.org/nightly/

---

### Src Doc Tutorial (`src/doc/tutorial.md`)

% The Rust Tutorial

This tutorial has been deprecated in favor of [the Book](book/index.html), which is available free online and in dead tree form. Go check that out instead!

---

### Compiler Rustc Codegen Cranelift Docs Dwarf (`compiler/rustc_codegen_cranelift/docs/dwarf.md`)

# Line number information

Line number information maps between machine code instructions and the source level location.

## Encoding

The line number information is stored in the `.debug_line` section for ELF and `__debug_line`
section of the `__DWARF` segment for Mach-O object files. The line number information contains a
header followed by the line program. The line program is a program for a virtual machine with
instructions like set line number for the current machine code instruction and advance the current
machine code instruction.

## Tips

You need to set either `DW_AT_low_pc` and `DW_AT_high_pc` **or** `DW_AT_ranges` of a
`DW_TAG_compilation_unit` to the range of addresses in the compilation unit. After that you need
to set `DW_AT_stmt_list` to the `.debug_line` section offset of the line program. Otherwise a
debugger won't find the line number information. On macOS the debuginfo relocations **must** be
section relative and not symbol relative.
See [#303 (comment)](https://github.com/bjorn3/rustc_codegen_cranelift/issues/303#issuecomment-457825535)
for more information.

# Function debuginfo

## Tips

`DW_TAG_subprogram` requires `DW_AT_name`, `DW_AT_low_pc` and `DW_AT_high_pc` **or** `DW_AT_ranges`.
Otherwise gdb will silently skip it. When `DW_AT_high_pc` is a length instead of an address, the
DWARF version must be at least 4.

<details>
<summary>IRC log of #gdb on irc.freenode.org at 2020-04-23</summary>

```
/* Detailed source-code truncated for AI context efficiency. */
```

</details>

---

### Compiler Rustc Codegen Cranelift Docs Rustc Testing (`compiler/rustc_codegen_cranelift/docs/rustc_testing.md`)

# Building and testing with changes in rustc code

This is useful when changing code in `rustc_codegen_cranelift` as part of changing [main Rust repository](https://github.com/rust-lang/rust/).
This can happen, for example, when you are implementing a new compiler intrinsic.

Instruction below uses `$RustCheckoutDir` as substitute for any folder where you cloned Rust repository.

You need to do this steps to successfully compile and use the cranelift backend with your changes in rustc code:

1. `cd $RustCheckoutDir`
2. Run `python x.py setup` and choose option for compiler (`b`).
3. Build compiler and necessary tools: `python x.py build --stage=2 compiler library/std src/tools/rustdoc src/tools/rustfmt`
   * (Optional) You can also build cargo by adding `src/tools/cargo` to previous command.
4. Copy cargo from a nightly toolchain: `cp $(rustup +nightly which cargo) ./build/host/stage2/bin/cargo`. Note that you would need to do this every time you rebuilt `rust` repository.
5. Link your new `rustc` to toolchain: `rustup toolchain link stage2 ./build/host/stage2/`.
6. (Windows only) compile the build system: `rustc +stage2 -O build_system/main.rs -o y.exe`.
7. You need to prefix every `./y.sh` (or `y` if you built `build_system/main.rs` as `y`) command by `rustup run stage2` to make cg_clif use your local changes in rustc.
  * `rustup run stage2 ./y.sh prepare`
  * `rustup run stage2 ./y.sh build`
  * (Optional) run tests: `rustup run stage2 ./y.sh test`
8. Now you can use your cg_clif build to compile other Rust programs, e.g. you can open any Rust crate and run commands like `$RustCheckoutDir/compiler/rustc_codegen_cranelift/dist/cargo-clif build --release`.

You can also set `rust-analyzer.rustc.source` to your rust workspace to get rust-analyzer to understand your changes.

---

### Compiler Rustc Codegen Cranelift Docs Usage (`compiler/rustc_codegen_cranelift/docs/usage.md`)

# Usage

rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo build` or `cargo run` for existing projects.

Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`y.sh prepare` and `y.sh build` or `test.sh`).

## Cargo

In the directory with your project (where you can do the usual `cargo build`), run:

```bash
$ $cg_clif_dir/dist/cargo-clif build
```

This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.

## Rustc

> You should prefer using the Cargo method.

```bash
$ $cg_clif_dir/dist/rustc-clif my_crate.rs
```

## Jit mode

> ⚠⚠⚠ The JIT mode is highly experimental. It may be slower than AOT compilation due to lack of incremental compilation. It may also be hard to setup if you have cargo dependencies. ⚠⚠⚠

In jit mode cg_clif will immediately execute your code without creating an executable file.

> This requires all dependencies to be available as dynamic library.
> The jit mode will probably need cargo integration to make this possible.

```bash
$ $cg_clif_dir/dist/cargo-clif jit
```

or

```bash
$ $cg_clif_dir/dist/rustc-clif -Cllvm-args=jit-mode -Cprefer-dynamic my_crate.rs
```

## Shell

These are a few functions that allow you to easily run rust code from the shell using cg_clif as jit.

```bash
function jit_naked() {
    echo "$@" | $cg_clif_dir/dist/rustc-clif - -Zunstable-options -Cllvm-args=jit-mode -Cprefer-dynamic
}

function jit() {
    jit_naked "fn main() { $@ }"
}

function jit_calc() {
    jit 'println!("0x{:x}", ' $@ ');';
}
```

---

### Compiler Rustc Codegen Gcc Doc Add Attribute (`compiler/rustc_codegen_gcc/doc/add-attribute.md`)

# Add support for a new function attribute

To add support for a new function attribute in libgccjit, you need to do the following steps:

 1. Copy the corresponding function from `c-family/c-attribs.cc` into `jit/dummy-frontend.cc`. For example if you add the `target` attribute, the function name will be `handle_target_attribute`.
 2. Copy the corresponding entry from the `c_common_attribute_table` variable in the `c-family/c-attribs.cc` file into the `jit_attribute_table` variable in `jit/dummy-frontend.cc`.
 3. Add a new variant in the `gcc_jit_fn_attribute` enum in the `jit/libgccjit.h` file.
 4. Add a test to ensure the attribute is correctly applied in `gcc/testsuite/jit.dg/`. Take a look at `gcc/testsuite/jit.dg/test-nonnull.c` if you want an example.
 5. Run the example like this (in your `gcc-build` folder): `make check-jit RUNTESTFLAGS="-v -v -v jit.exp=jit.dg/test-nonnull.c"`

Once done, you need to update the [gccjit.rs] crate to add the new enum variant in the corresponding enum (`FnAttribute`).

Finally, you need to update this repository by calling the relevant API you added in [gccjit.rs].

To test it, build `gcc`, run `cargo update -p gccjit` and then you can test the generated output for a given Rust crate.

[gccjit.rs]: https://github.com/rust-lang/gccjit.rs

---

### Compiler Rustc Codegen Gcc Doc Debugging Libgccjit (`compiler/rustc_codegen_gcc/doc/debugging-libgccjit.md`)

# Debugging libgccjit

Sometimes, libgccjit will crash and output an error like this:

```
during RTL pass: expand
libgccjit.so: error: in expmed_mode_index, at expmed.h:249
0x7f0da2e61a35 expmed_mode_index
	../../../gcc/gcc/expmed.h:249
0x7f0da2e61aa4 expmed_op_cost_ptr
	../../../gcc/gcc/expmed.h:271
0x7f0da2e620dc sdiv_cost_ptr
	../../../gcc/gcc/expmed.h:540
0x7f0da2e62129 sdiv_cost
	../../../gcc/gcc/expmed.h:558
0x7f0da2e73c12 expand_divmod(int, tree_code, machine_mode, rtx_def*, rtx_def*, rtx_def*, int)
	../../../gcc/gcc/expmed.c:4335
0x7f0da2ea1423 expand_expr_real_2(separate_ops*, rtx_def*, machine_mode, expand_modifier)
	../../../gcc/gcc/expr.c:9240
0x7f0da2cd1a1e expand_gimple_stmt_1
	../../../gcc/gcc/cfgexpand.c:3796
0x7f0da2cd1c30 expand_gimple_stmt
	../../../gcc/gcc/cfgexpand.c:3857
0x7f0da2cd90a9 expand_gimple_basic_block
	../../../gcc/gcc/cfgexpand.c:5898
0x7f0da2cdade8 execute
	../../../gcc/gcc/cfgexpand.c:6582
```

To see the code which causes this error, call the following function:

```c
gcc_jit_context_dump_to_file(ctxt, "/tmp/output.c", 1 /* update_locations */)
```

This will create a C-like file and add the locations into the IR pointing to this C file.
Then, rerun the program and it will output the location in the second line:

```
libgccjit.so: /tmp/something.c:61322:0: error: in expmed_mode_index, at expmed.h:249
```

Or add a breakpoint to `add_error` in gdb and print the line number using:

```
p loc->m_line
p loc->m_filename->m_buffer
```

To print a debug representation of a tree:

```c
debug_tree(expr);
```

(defined in print-tree.h)

To print a debug representation of a gimple struct:

```c
debug_gimple_stmt(gimple_struct)
```

To get the `rustc` command to run in `gdb`, add the `--verbose` flag to `cargo build`.

To have the correct file paths in `gdb` instead of `/usr/src/debug/gcc/libstdc++-v3/libsupc++/eh_personality.cc`:

Maybe by calling the following at the beginning of gdb:

```
set substitute-path /usr/src/debug/gcc /path/to/gcc-repo/gcc
```

FIXME(antoyo): but that's not what I remember I was doing.

---

### Compiler Rustc Codegen Gcc Doc Debugging (`compiler/rustc_codegen_gcc/doc/debugging.md`)

# Debugging

## How to debug GCC LTO

Run the command with `-v -save-temps` and then extract the `lto1` line from the output and run that under the debugger.

## How to debug stdarch tests that cannot be run locally

First, run the tests normally:

----
cd build/build_sysroot/sysroot_src/library/stdarch/
STDARCH_TEST_EVERYTHING=1 CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="sde -future -rtm_mode full --" TARGET=x86_64-unknown-linux-gnu ../../../../../y.sh cargo test
----

It will show the command it ran, something like this:

----
  process didn't exit successfully: `sde -future -rtm_mode full -- /home/user/projects/rustc_codegen_gcc/build/build_sysroot/sysroot_src/library/stdarch/target/debug/deps/core_arch-fd2d75f89baae5c6` (signal: 11, SIGSEGV: invalid memory reference)
----

Then add the `-debug` flag to it:

----
sde -debug -future -rtm_mode full -- /home/user/projects/rustc_codegen_gcc/build/build_sysroot/sysroot_src/library/stdarch/target/debug/deps/core_arch-fd2d75f89baae5c6
----

To see the symbols in `gdb`, specify the executable in your command:

----
gdb /home/user/projects/rustc_codegen_gcc/build/build_sysroot/sysroot_src/library/stdarch/target/debug/deps/core_arch-fd2d75f89baae5c6
----

and then write the `gdb` command that `sde` tells you to use, something like:

----
target remote :51299
----

---

### Compiler Rustc Codegen Gcc Doc Errors (`compiler/rustc_codegen_gcc/doc/errors.md`)

# Common errors

This file lists errors that were encountered and how to fix them.

### `failed to build archive` error

When you get this error:

```
error: failed to build archive: failed to open object file: No such file or directory (os error 2)
```

That can be caused by the fact that you try to compile with `lto = "fat"`, but you didn't compile the sysroot with LTO.
(Not sure if that's the reason since I cannot reproduce anymore. Maybe it happened when forgetting setting `FAT_LTO`.)

### ld: cannot find crtbegin.o

When compiling an executable with libgccjit, if setting the `*LIBRARY_PATH` variables to the install directory, you will get the following errors:

```
ld: cannot find crtbegin.o: No such file or directory
ld: cannot find -lgcc: No such file or directory
ld: cannot find -lgcc: No such file or directory
libgccjit.so: error: error invoking gcc driver
```

To fix this, set the variables to `gcc-build/build/gcc`.

---

### Compiler Rustc Codegen Gcc Doc Gimple (`compiler/rustc_codegen_gcc/doc/gimple.md`)

# GIMPLE

You can see the full documentation about what GIMPLE is [here](https://gcc.gnu.org/onlinedocs/gccint/GIMPLE.html). In this document we will explain how to generate it.

First, we'll copy the content from `gcc/gcc/testsuite/jit.dg/test-const-attribute.c` into a
file named `local.c` and remove the content we're not interested in:

```diff
- /* { dg-do compile { target x86_64-*-* } } */
...
- /* We don't want set_options() in harness.h to set -O3 to see that the const
-    attribute affects the optimizations. */
- #define TEST_ESCHEWS_SET_OPTIONS
- static void set_options (gcc_jit_context *ctxt, const char *argv0)
- {
-   // Set "-O3".
-   gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);
- }
-
- #define TEST_COMPILING_TO_FILE
- #define OUTPUT_KIND      GCC_JIT_OUTPUT_KIND_ASSEMBLER
- #define OUTPUT_FILENAME  "output-of-test-const-attribute.c.s"
- #include "harness.h"
...
- /* { dg-final { jit-verify-output-file-was-created "" } } */
- /* Check that the loop was optimized away */
- /* { dg-final { jit-verify-assembler-output-not "jne" } } */
```

Then we'll add a `main` function which will call the `create_code` function but
also add the calls we need to generate the GIMPLE:

```C
int main() {
    gcc_jit_context *ctxt = gcc_jit_context_acquire();
    // To set `-O3`, update it depending on your needs.
    gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);
    // Very important option to generate the gimple format.
    gcc_jit_context_set_bool_option(ctxt, GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1);
    create_code(ctxt, NULL);

    gcc_jit_context_compile(ctxt);
    // If you want to compile to assembly (or any other format) directly, you can
    // use the following call instead:
    // gcc_jit_context_compile_to_file(ctxt, GCC_JIT_OUTPUT_KIND_ASSEMBLER, "out.s");

    return 0;
}
```

Then we can compile it by using:

```console
gcc local.c -I `pwd`/gcc/gcc/jit/ -L `pwd`/gcc-build/gcc -lgccjit -o out
```

And finally when you run it:

```console
LD_LIBRARY_PATH=`pwd`/gcc-build/gcc LIBRARY_PATH=`pwd`/gcc-build/gcc ./out
```

It should display:

```c
__attribute__((const))
int xxx ()
{
  int D.3394;
  int sum;
  int x;

  <D.3377>:
  x = 45;
  sum = 0;
  goto loop_cond;
  loop_cond:
  x = x >> 1;
  if (x != 0) goto after_loop; else goto loop_body;
  loop_body:
  _1 = foo (x);
  _2 = _1 * 2;
  x = x + _2;
  goto loop_cond;
  after_loop:
  D.3394 = sum;
  return D.3394;
}
```

An alternative way to generate the GIMPLE is to replace:

```c
    gcc_jit_context_set_bool_option(ctxt, GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1);
```

with:

```c
    gcc_jit_context_add_command_line_option(ctxt, "-fdump-tree-gimple");
```

(although you can have both at the same time too). Then you can compile it like previously. Only one difference: before executing it, I recommend to run:

```console
rm -rf /tmp/libgccjit-*
```

to make it easier for you to know which folder to look into.

Once the execution is done, you should now have a file with path looking like `/tmp/libgccjit-9OFqkD/fake.c.006t.gimple` which contains the GIMPLE format.

---

### Compiler Rustc Codegen Gcc Doc Sending Gcc Patch (`compiler/rustc_codegen_gcc/doc/sending-gcc-patch.md`)

This guide explains what to do to send a GCC patch for review.

All the commands are supposed to be run in the folder where you cloned GCC.

```bash
./contrib/gcc-changelog/git_check_commit.py
```

You can provide a specific commit hash:

```bash
./contrib/gcc-changelog/git_check_commit.py abdef78989
```

a range:

```bash
./contrib/gcc-changelog/git_check_commit.py HEAD~2
```

or even a comparison with a remote branch:

```bash
./contrib/gcc-changelog/git_check_commit.py upstream/master..HEAD
```

When there is no more errors, generate the git patch:

```bash
git format-patch -1 `git rev-parse --short HEAD`
```

Then you can run the remaining checks using:

```bash
contrib/check_GNU_style.sh 0001-your-patch.patch
```

When you have no more errors, you can send the `.patch` file to GCC by sending an
email to `gcc-patches@gcc.gnu.org` and to the relevant GCC mailing lists
depending on what your patch changes. You can find the list of the mailing lists
[here](https://gcc.gnu.org/lists.html).

You can find more information about "contributing to GCC" [here](https://gcc.gnu.org/contribute.html).

---

### Compiler Rustc Codegen Gcc Doc Subtree (`compiler/rustc_codegen_gcc/doc/subtree.md`)

# git subtree sync

`rustc_codegen_gcc` is a subtree of the rust compiler. As such, it needs to be
synced from time to time to ensure changes that happened on their side are also
included on our side.

### How to install a forked git-subtree

Using git-subtree with `rustc` requires a patched git to make it work.
The PR that is needed is [here](https://github.com/gitgitgadget/git/pull/493).
Use the following instructions to install it:

```bash
git clone git@github.com:tqc/git.git
cd git
git checkout tqc/subtree
make
make install
cd contrib/subtree
make
cp git-subtree ~/bin
```

### Syncing with rust compiler

Do a sync with this command:

```bash
PATH="$HOME/bin:$PATH" ~/bin/git-subtree push -P compiler/rustc_codegen_gcc/ ../rustc_codegen_gcc/ sync_branch_name
cd ../rustc_codegen_gcc
git checkout master
git pull
git checkout sync_branch_name
git merge master
```

To send the changes to the rust repo:

```bash
cd ../rust
git pull origin master
git checkout -b subtree-update_cg_gcc_YYYY-MM-DD
PATH="$HOME/bin:$PATH" ~/bin/git-subtree pull --prefix=compiler/rustc_codegen_gcc/ https://github.com/rust-lang/rustc_codegen_gcc.git master
# Don't forget to update the `gcc` submodule to the same version as the
# one in `rustc_codegen_gcc/libgccjit.version`.
git push

# Immediately merge the merge commit into cg_gcc to prevent merge conflicts when syncing from rust-lang/rust later.
PATH="$HOME/bin:$PATH" ~/bin/git-subtree push -P compiler/rustc_codegen_gcc/ ../rustc_codegen_gcc/ sync_branch_name
```

FIXME: write a script that does the above.

https://rust-lang.zulipchat.com/#narrow/stream/301329-t-devtools/topic/subtree.20madness/near/258877725

---

### Compiler Rustc Codegen Gcc Doc Tests (`compiler/rustc_codegen_gcc/doc/tests.md`)

# Tests

## Show the rustc command for UI tests

Add ` --test-args "--verbose"` to `./x.py test`.

---

### Compiler Rustc Codegen Gcc Doc Tips (`compiler/rustc_codegen_gcc/doc/tips.md`)

# Tips

The following shows how to do different random small things we encountered and thought could
be useful.

### How to send arguments to the GCC linker

```
CG_RUSTFLAGS="-Clink-args=-save-temps -v" ../y.sh cargo build
```

### How to send arguments to GCC

The `-Cllvm-args` `rustc` flag is repurposed by `rustc_codegen_gcc` to pass arguments directly to the GCC backend. You can use it via the `CG_RUSTFLAGS` environment variable. For example, to pass a `-f` flag to GCC:

```
CG_RUSTFLAGS="-Cllvm-args=-fflag-name" ../y.sh cargo build
```

### How to see the personality functions in the asm dump

```
CG_RUSTFLAGS="-Clink-arg=-save-temps -v -Clink-arg=-dA" ../y.sh cargo build
```

### How to see the LLVM IR for a sysroot crate

```
cargo build -v --target x86_64-unknown-linux-gnu -Zbuild-std
# Take the command from the output and add --emit=llvm-ir
```

### To prevent the linker from unmangling symbols

Run with:

```
COLLECT_NO_DEMANGLE=1
```

### How to use a custom-build rustc

 * Build the stage2 compiler (`rustup toolchain link debug-current build/x86_64-unknown-linux-gnu/stage2`).
 * Clean and rebuild the codegen with `debug-current` in the file `rust-toolchain.toml`.

### How to use a custom sysroot source path

If you wish to build a custom sysroot, pass the path of your sysroot source to `--sysroot-source` during the `prepare` step, like so:

```
./y.sh prepare --sysroot-source /path/to/custom/source
```

### How to use [mem-trace](https://github.com/antoyo/mem-trace)

`rustc` needs to be built without `jemalloc` so that `mem-trace` can overload `malloc` since `jemalloc` is linked statically, so a `LD_PRELOAD`-ed library won't have a chance to intercept the calls to `malloc`.

### How to generate GIMPLE

If you need to check what gccjit is generating (GIMPLE), then take a look at how to
generate it in [gimple.md](./gimple.md).

### How to build a cross-compiling libgccjit

#### Building libgccjit

 * Follow the instructions on [this repo](https://github.com/cross-cg-gcc-tools/cross-gcc).

#### Configuring rustc_codegen_gcc

 * Run `./y.sh prepare --cross` so that the sysroot is patched for the cross-compiling case.
 * Set the path to the cross-compiling libgccjit in `gcc-path` (in `config.toml`).
 * Make sure you have the linker for your target (for instance `m68k-unknown-linux-gnu-gcc`) in your `$PATH`. You can specify which linker to use via `CG_RUSTFLAGS="-Clinker=<linker>"`, for instance: `CG_RUSTFLAGS="-Clinker=m68k-unknown-linux-gnu-gcc"`. Specify the target when building the sysroot: `./y.sh build --sysroot --target-triple m68k-unknown-linux-gnu`.
 * Build your project by specifying the target and the linker to use: `CG_RUSTFLAGS="-Clinker=m68k-unknown-linux-gnu-gcc" ../y.sh cargo build --target m68k-unknown-linux-gnu`.

If the target is not yet supported by the Rust compiler, create a [target specification file](https://docs.rust-embedded.org/embedonomicon/custom-target.html) (note that the `arch` specified in this file must be supported by the rust compiler).
Then, you can use it the following way:

 * Add the target specification file using `--target` as an **absolute** path to build the sysroot: `./y.sh build --sysroot --target-triple m68k-unknown-linux-gnu --target $(pwd)/m68k-unknown-linux-gnu.json`
 * Build your project by specifying the target specification file: `../y.sh cargo build --target path/to/m68k-unknown-linux-gnu.json`.

If you get the following error:

```
/usr/bin/ld: unrecognised emulation mode: m68kelf
```

Make sure you set `gcc-path` (in `config.toml`) to the install directory.

---

### Src Doc Rustc Dev Guide CODE OF CONDUCT (`src/doc/rustc-dev-guide/CODE_OF_CONDUCT.md`)

# The Rust Code of Conduct

This repository follows the [Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct) of the Rust organization.

---

### Src Doc Rustc Dev Guide Src SUMMARY (`src/doc/rustc-dev-guide/src/SUMMARY.md`)

# Summary

[Getting Started](./getting-started.md)

[About this guide](./about-this-guide.md)

---

# Building and debugging `rustc`

- [How to build and run the compiler](./building/how-to-build-and-run.md)
    - [Quickstart](./building/quickstart.md)
    - [Prerequisites](./building/prerequisites.md)
    - [Suggested workflows](./building/suggested.md)
    - [Distribution artifacts](./building/build-install-distribution-artifacts.md)
    - [Building documentation](./building/compiler-documenting.md)
    - [Rustdoc overview](./rustdoc.md)
    - [Adding a new target](./building/new-target.md)
    - [Optimized build](./building/optimized-build.md)
- [Testing the compiler](./tests/intro.md)
    - [Running tests](./tests/running.md)
        - [Testing with Docker](./tests/docker.md)
        - [Testing with CI](./tests/ci.md)
    - [Adding new tests](./tests/adding.md)
    - [Best practices](./tests/best-practices.md)
    - [Compiletest](./tests/compiletest.md)
        - [UI tests](./tests/ui.md)
        - [Test directives](./tests/directives.md)
        - [Minicore](./tests/minicore.md)
    - [Ecosystem testing](./tests/ecosystem.md)
        - [Crater](./tests/crater.md)
        - [Fuchsia](./tests/ecosystem-test-jobs/fuchsia.md)
        - [Rust for Linux](./tests/ecosystem-test-jobs/rust-for-linux.md)
    - [Codegen backend testing](./tests/codegen-backend-tests/intro.md)
        - [Cranelift codegen backend (stub)](./tests/codegen-backend-tests/cg_clif.md)
        - [GCC codegen backend](./tests/codegen-backend-tests/cg_gcc.md)
    - [Performance testing](./tests/perf.md)
    - [Autodiff CI job](./tests/autodiff-ci-job.md)
    - [Pre-stabilization CI job for the next solver and polonius alpha](./tests/x86_64-gnu-next-trait-solver-polonius-ci-job.md)
    - [Parallel frontend CI job](./tests/optional-x86_64-gnu-parallel-frontend.md)
    - [Standard library semver breakage test](./tests/stdlib-semver-check.md)
    - [Misc info](./tests/misc.md)
- [Debugging the compiler](./compiler-debugging.md)
    - [Using the tracing/logging instrumentation](./tracing.md)
- [Profiling the compiler](./profiling.md)
    - [with the linux perf tool](./profiling/with-perf.md)
    - [with Windows Performance Analyzer](./profiling/wpa-profiling.md)
    - [with the Rust benchmark suite](./profiling/with-rustc-perf.md)
- [crates.io dependencies](./crates-io.md)

# Contributing to Rust

- [Contribution procedures](./contributing.md)
- [PR lifecycle](./pr-lifecycle.md)
- [Writing rustc-dev-guide documentation](./contributing-to-guide.md)
- [About the compiler team](./compiler-team.md)
- [Using Git](./git.md)
- [Mastering @rustbot](./rustbot.md)
- [Running LLMs](./llm-guidance.md)
    - [Writing code with LLMs](./llm-guidance/writing.md)
    - [Reviewing code with LLMs](./llm-guidance/reviewing.md)
- [Walkthrough: adding a new test](./walkthroughs/test.md)
- [Implementing new language features](./implementing-new-features.md)
- [Stability guarantees](./stability-guarantees.md)
- [Stability attributes](./stability.md)
- [Stabilizing language features](./stabilization-guide.md)
    - [Stabilization report template](./stabilization-report-template.md)
- [Feature Gates](./feature-gates.md)
- [Walkthrough: a new language feature, from design to stabilization](./walkthroughs/lang-feature.md)
- [Coding conventions](./conventions.md)
- [Procedures for breaking changes](./bug-fix-procedure.md)
- [Using external repositories](./external-repos.md)
- [Fuzzing](./fuzzing.md)
- [Notification groups](notification-groups/about.md)
    - [Apple](notification-groups/apple.md)
    - [ARM](notification-groups/arm.md)
    - [Emscripten](notification-groups/emscripten.md)
    - [Fuchsia](notification-groups/fuchsia.md)
    - [LoongArch](notification-groups/loongarch.md)
    - [RISC-V](notification-groups/risc-v.md)
    - [Rust for Linux](notification-groups/rust-for-linux.md)
    - [WASI](notification-groups/wasi.md)
    - [WebAssembly](notification-groups/wasm.md)
    - [Windows](notification-groups/windows.md)
    - [GPU target](notification-groups/gpu-target.md)
- [Licenses](./licenses.md)
- [Editions](guides/editions.md)

# Bootstrapping

- [Prologue](./building/bootstrapping/intro.md)
- [What Bootstrapping does](./building/bootstrapping/what-bootstrapping-does.md)
- [How Bootstrap does it](./building/bootstrapping/how-bootstrap-does-it.md)
- [Writing tools in Bootstrap](./building/bootstrapping/writing-tools-in-bootstrap.md)
- [Debugging bootstrap](./building/bootstrapping/debugging-bootstrap.md)
- [cfg(bootstrap) in dependencies](./building/bootstrapping/bootstrap-in-dependencies.md)

# High-level compiler architecture

- [Prologue](./part-2-intro.md)
- [Overview of the compiler](./overview.md)
- [The compiler source code](./compiler-src.md)
- [Queries: demand-driven compilation](./query.md)
    - [The Query Evaluation Model in detail](./queries/query-evaluation-model-in-detail.md)
    - [Incremental compilation](./queries/incremental-compilation.md)
    - [Incremental compilation in detail](./queries/incremental-compilation-in-detail.md)
    - [Debugging and testing](./incrcomp-debugging.md)
    - [Salsa](./queries/salsa.md)
- [Memory management in rustc](./memory.md)
- [Serialization in rustc](./serialization.md)
- [Parallel compilation](./parallel-rustc.md)
- [Rustdoc internals](./rustdoc-internals.md)
    - [Search](./rustdoc-internals/search.md)
    - [The `rustdoc-html` test suite](./rustdoc-internals/rustdoc-html-test-suite.md)
    - [The `rustdoc-gui` test suite (stub)](./rustdoc-internals/rustdoc-gui-test-suite.md)
    - [The `rustdoc-json` test suite](./rustdoc-internals/rustdoc-json-test-suite.md)
- [GPU offload internals](./offload/internals.md)
    - [Installation](./offload/installation.md)
    - [Usage](./offload/usage.md)
    - [Contributing](./offload/contributing.md)
- [Autodiff internals](./autodiff/internals.md)
    - [Installation](./autodiff/installation.md)
    - [How to debug](./autodiff/debugging.md)
    - [Autodiff flags](./autodiff/flags.md)
    - [Type Trees](./autodiff/type-trees.md)

# Source code representation

- [Prologue](./part-3-intro.md)
- [Syntax and the AST](./syntax-intro.md)
    - [Lexing and parsing](./the-parser.md)
    - [Macro expansion](./macro-expansion.md)
    - [Name resolution](./name-resolution.md)
    - [Attributes](./attributes.md)
    - [`#[test]` implementation](./test-implementation.md)
    - [Panic implementation](./panic-implementation.md)
    - [AST validation](./ast-validation.md)
    - [Feature gate checking](./feature-gate-check.md)
    - [Lang Items](./lang-items.md)
- [The HIR (High-level IR)](./hir.md)
    - [Lowering AST to HIR](./hir/lowering.md)
    - [Attribute Parsing](./hir/attribute-parsing.md)
    - [Debugging](./hir/debugging.md)
- [Ambig/Unambig Types and Consts](./ambig-unambig-ty-and-consts.md)
- [The THIR (Typed High-level IR)](./thir.md)
- [The MIR (Mid-level IR)](./mir/index.md)
    - [MIR construction](./mir/construction.md)
    - [MIR visitor and traversal](./mir/visitor.md)
    - [MIR queries and passes: getting the MIR](./mir/passes.md)
- [Inline assembly](./asm.md)

# Supporting infrastructure

- [Command-line arguments](./cli.md)
- [rustc_driver and rustc_interface](./rustc-driver/intro.md)
    - [External rustc_drivers](./rustc-driver/external-rustc-drivers.md)
    - [Example: Type checking](./rustc-driver/interacting-with-the-ast.md)
    - [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.md)
- [Errors and lints](diagnostics.md)
    - [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md)
    - [Translation](./diagnostics/translation.md)
    - [`LintStore`](./diagnostics/lintstore.md)
    - [Error codes](./diagnostics/error-codes.md)
    - [Diagnostic items](./diagnostics/diagnostic-items.md)
    - [`ErrorGuaranteed`](./diagnostics/error-guaranteed.md)

# Analysis

- [Prologue](./part-4-intro.md)
- [Generic parameter definitions](./generic-parameters-summary.md)
    - [`EarlyBinder` and instantiating parameters](./ty-module/early-binder.md)
- [Binders and Higher ranked regions](./ty-module/binders.md)
    - [Instantiating binders](./ty-module/instantiating-binders.md)
- [Early vs Late bound parameters](./early-late-parameters.md)
- [The `ty` module: representing types](./ty.md)
    - [ADTs and Generic Arguments](./ty-module/generic-arguments.md)
    - [Parameter types/consts/regions](./ty-module/param-ty-const-regions.md)
- [`TypeFolder` and `TypeFoldable`](./ty-fold.md)
- [Aliases and normalization](./normalization.md)
- [Typing/Param envs](./typing-parameter-envs.md)
- [Type inference](./type-inference.md)
- [Trait solving](./traits/resolution.md)
    - [Higher-ranked trait bounds](./traits/hrtb.md)
    - [Caching subtleties](./traits/caching.md)
    - [Implied bounds](./traits/implied-bounds.md)
    - [Specialization](./traits/specialization.md)
    - [Chalk-based trait solving](./traits/chalk.md)
        - [Lowering to logic](./traits/lowering-to-logic.md)
        - [Goals and clauses](./traits/goals-and-clauses.md)
        - [Canonical queries](./traits/canonical-queries.md)
        - [Canonicalization](./traits/canonicalization.md)
    - [Next-gen trait solving](./solve/trait-solving.md)
        - [Invariants of the type system](./solve/invariants.md)
        - [The solver](./solve/the-solver.md)
        - [Candidate preference](./solve/candidate-preference.md)
        - [Canonicalization](./solve/canonicalization.md)
        - [Coinduction](./solve/coinduction.md)
        - [Caching](./solve/caching.md)
        - [Proof trees](./solve/proof-trees.md)
        - [Opaque types](./solve/opaque-types.md)
        - [Significant changes and quirks](./solve/significant-changes.md)
        - [Sharing the trait solver with rust-analyzer](./solve/sharing-crates-with-rust-analyzer.md)
    - [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md)
    - [Having separate `Trait` and `Projection` bounds](./traits/separate-projection-bounds.md)
- [Well-formedness](./analysis/well-formed.md)
- [Variance](./variance.md)
- [Coherence checking](./coherence.md)
- [HIR Type checking](./hir-typeck/summary.md)
    - [Coercions](./hir-typeck/coercions.md)
    - [Method lookup](./hir-typeck/method-lookup.md)
- [Const generics](./const-generics.md)
- [Opaque types](./opaque-types-type-alias-impl-trait.md)
    - [Inference details](./opaque-types-impl-trait-inference.md)
    - [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md)
    - [Region inference restrictions](./borrow-check/opaque-types-region-inference-restrictions.md)
- [Const traits and const condition checking](./effects.md)
- [Pattern and exhaustiveness checking](./pat-exhaustive-checking.md)
- [Unsafety checking](./unsafety-checking.md)
- [MIR dataflow](./mir/dataflow.md)
- [Drop elaboration](./mir/drop-elaboration.md)
- [The borrow checker](./borrow-check.md)
    - [Tracking moves and initialization](./borrow-check/moves-and-initialization.md)
        - [Move paths](./borrow-check/moves-and-initialization/move-paths.md)
    - [MIR type checker](./borrow-check/type-check.md)
    - [Drop check](./borrow-check/drop-check.md)
    - [Region inference](./borrow-check/region-inference.md)
        - [Constraint propagation](./borrow-check/region-inference/constraint-propagation.md)
        - [Lifetime parameters](./borrow-check/region-inference/lifetime-parameters.md)
        - [Member constraints](./borrow-check/region-inference/member-constraints.md)
        - [Placeholders and universes](./borrow-check/region-inference/placeholders-and-universes.md)
        - [Closure constraints](./borrow-check/region-inference/closure-constraints.md)
        - [Error reporting (stub)](./borrow-check/region-inference/error-reporting.md)
    - [Two-phase-borrows](./borrow-check/two-phase-borrows.md)
    - [Debugging the borrow checker](./borrow-check/debugging.md)
- [Closure capture inference](./closure.md)
- [Async closures/"coroutine-closures"](coroutine-closures.md)

# MIR to binaries

- [Prologue](./part-5-intro.md)
- [MIR optimizations](./mir/optimizations.md)
- [Debugging MIR](./mir/debugging.md)
- [Constant evaluation](./const-eval.md)
    - [Interpreter](./const-eval/interpret.md)
- [Monomorphization](./backend/monomorph.md)
- [Lowering MIR](./backend/lowering-mir.md)
- [Code generation](./backend/codegen.md)
    - [Updating LLVM](./backend/updating-llvm.md)
    - [Debugging LLVM](./backend/debugging.md)
    - [Backend Agnostic Codegen](./backend/backend-agnostic.md)
    - [Implicit caller location](./backend/implicit-caller-location.md)
- [Debug info](./debuginfo/intro.md)
    - [Rust codegen](./debuginfo/rust-codegen.md)
    - [LLVM codegen](./debuginfo/llvm-codegen.md)
    - [Debugger internals](./debuginfo/debugger-internals.md)
        - [LLDB internals](./debuginfo/lldb-internals.md)
        - [GDB internals (stub)](./debuginfo/gdb-internals.md)
    - [Debugger visualizers](./debuginfo/debugger-visualizers.md)
        - [LLDB - Python Providers](./debuginfo/lldb-visualizers.md)
        - [GDB - Python Providers](./debuginfo/gdb-visualizers.md)
        - [CDB - Natvis (stub)](./debuginfo/natvis-visualizers.md)
    - [Testing (stub)](./debuginfo/testing.md)
    - [(Lecture notes) Debugging support in the Rust compiler](./debugging-support-in-rustc.md)
- [Libraries and metadata](./backend/libs-and-metadata.md)
- [Profile-guided optimization](./profile-guided-optimization.md)
- [LLVM source-based code coverage](./llvm-coverage-instrumentation.md)
- [Sanitizers support](./sanitizers.md)

---

[Appendix A: Background topics](./appendix/background.md)

[Appendix B: Glossary](./appendix/glossary.md)

[Appendix C: Code Index](./appendix/code-index.md)

[Appendix D: Compiler Lecture Series](./appendix/compiler-lecture.md)

[Appendix E: Bibliography](./appendix/bibliography.md)

[Appendix F: Reading club sessions](./appendix/reading-club.md)

[Appendix Z: HumorRust](./appendix/humorust.md)

---

### Src Doc Rustc Dev Guide Src About This Guide (`src/doc/rustc-dev-guide/src/about-this-guide.md`)

# About this guide



This guide is meant to help document how rustc – the Rust compiler – works,
as well as to help new contributors get involved in rustc development.

Note that this guide is intended as a reference; it's recommended that you search
for the docs you're looking for instead of reading them top to bottom.

There are several parts to this guide:

1. [Building and debugging `rustc`][p1]:
   Contains information that should be useful no matter how you are contributing,
   about building, debugging, profiling, etc.
1. [Contributing to Rust][p2]:
   Contains information that should be useful no matter how you are contributing,
   about procedures for contribution, using git and GitHub, stabilizing features, etc.
1. [Bootstrapping][p3]:
   Describes how the Rust compiler builds itself using previous versions, including
   an introduction to the bootstrap process and debugging methods.
1. [High-level compiler architecture][p4]:
   Discusses the high-level architecture of the compiler and stages of the compile process.
1. [Source code representation][p5]:
   Describes the process of taking raw source code from the user
   and transforming it into various forms that the compiler can work with easily.
1. [Supporting infrastructure][p6]:
   Covers command-line argument conventions, compiler entry points like rustc_driver and
   rustc_interface, and the design and implementation of errors and lints.
1. [Analysis][p7]:
   Discusses the analyses that the compiler uses to check various properties of the code
   and inform later stages of the compile process (e.g., type checking).
1. [Mir to binaries][p8]: How linked executable machine code is generated.
1. [Appendices][p9] at the end with useful reference information.
   There are a few of these with different information, including a glossary.

[p1]: ./building/how-to-build-and-run.md
[p2]: ./getting-started.md
[p3]: ./building/bootstrapping/intro.md
[p4]: ./part-2-intro.md
[p5]: ./part-3-intro.md
[p6]: ./cli.md
[p7]: ./part-4-intro.md
[p8]: ./part-5-intro.md
[p9]: ./appendix/background.md

### Constant change

Keep in mind that `rustc` is a real production-quality product,
being worked upon continuously by a sizeable set of contributors.
As such, it has its fair share of codebase churn and technical debt.
In addition, many of the ideas discussed throughout this guide are idealized designs
that are not fully realized yet.
All this makes keeping this guide completely up to date on everything very hard!

The guide itself is of course open source as well,
and the sources are hosted on [a GitHub repository].
If you find any mistakes in the guide, please file an issue.
Even better, open a PR with a correction!

If you do contribute to the guide,
please see the corresponding [subsection on writing documentation in this guide].

[subsection on writing documentation in this guide]: contributing-to-guide.md

> “‘All conditioned things are impermanent’ —
> when one sees this with wisdom, one turns away from suffering.”
> _The Dhammapada, verse 277_

## Other places to find information

This guide, the one you are currently reading,
contains information about how various parts of the compiler work,
and how to contribute to the compiler.

You might also find the following sites useful:

- [rustc API docs] -- rustdoc documentation for the compiler, devtools, and internal tools
- [Forge] -- contains documentation about Rust infrastructure, team procedures, and more
- [`rust-lang/rust`]'s [LLM policy]
- [compiler-team] -- the home-base for the Rust compiler team, with description
  of the team procedures, active working groups, and the team calendar.
- [std-dev-guide] -- a similar guide for developing the standard library.
- [rust-analyzer book] -- documentation for the rust-analyzer.
- [The t-compiler Zulip][z]
- The [Rust Internals forum][rif], a place to ask questions and discuss Rust's internals
- The [Rust reference][rr], even though it doesn't specifically talk about
  Rust's internals, is a great resource nonetheless
- Although out of date, [Tom Lee's great blog article][tlgba] is very helpful
- The [Rust Compiler Testing Docs][rctd]
- For [@bors], [this cheat sheet][cheatsheet] is helpful
- Google is always helpful when programming.
  You can [search all Rust documentation][gsearchdocs] (the standard library,
  the compiler, the books, the references, and the guides) to quickly find
  information about the language and compiler.
- You can also use Rustdoc's built-in search feature to find documentation on
  types and functions within the crates you're looking at.
  You can also search by type signature!
  For example, searching for `* -> vec` should find all functions that return a `Vec<T>`.
  _Hint:_ Find more tips and keyboard shortcuts by typing `?` on any Rustdoc page!

[LLM policy]: https://forge.rust-lang.org/policies/llm-usage.html
[rustc dev guide]: about-this-guide.md
[gsearchdocs]: https://www.google.com/search?q=site:doc.rust-lang.org+your+query+here
[stddocs]: https://doc.rust-lang.org/std
[rif]: http://internals.rust-lang.org
[rr]: https://doc.rust-lang.org/reference/
[rustforge]: https://forge.rust-lang.org/
[tlgba]: https://tomlee.co/2014/04/a-more-detailed-tour-of-the-rust-compiler/
[ro]: https://www.rustaceans.org/
[rctd]: tests/intro.md
[cheatsheet]: https://bors.rust-lang.org/help
[Miri]: https://github.com/rust-lang/miri
[@bors]: https://github.com/rust-lang/bors
[a GitHub repository]: https://github.com/rust-lang/rustc-dev-guide/
[rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle
[Forge]: https://forge.rust-lang.org/
[compiler-team]: https://github.com/rust-lang/compiler-team/
[std-dev-guide]: https://std-dev-guide.rust-lang.org/
[rust-analyzer book]: https://rust-analyzer.github.io/book/
[z]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler
[`rust-lang/rust`]: https://github.com/rust-lang/rust/

---

### Src Doc Rustc Dev Guide Src Ambig Unambig Ty And Consts (`src/doc/rustc-dev-guide/src/ambig-unambig-ty-and-consts.md`)

# Ambig/Unambig Types and Consts

Types and Consts args in the AST/HIR can be in two kinds of positions ambiguous (ambig) or unambiguous (unambig).
Ambig positions are where it would be valid to parse either a type or a const.
Unambig positions are where only one kind would be valid to parse.

```rust
fn func<T, const N: usize>(arg: T) {
    //                          ^ Unambig type position
    let a: _ = arg;
    //     ^ Unambig type position

    func::<T, N>(arg);
    //     ^  ^
    //     ^^^^ Ambig position

    let _: [u8; 10];
    //      ^^  ^^ Unambig const position
    //      ^^ Unambig type position
}

```

Most types/consts in ambig positions are able to be disambiguated as either a type or const during parsing.
The only exceptions to this are paths and inferred generic arguments.

## Paths

```rust
struct Foo<const N: usize>;

fn foo<const N: usize>(_: Foo<N>) {}
```

At parse time we parse all unbraced generic arguments as *types* (ie they wind up as [`ast::GenericArg::Ty`]).
In the above example this means we would parse the generic argument to `Foo` as an `ast::GenericArg::Ty` wrapping a [`ast::Ty::Path(N)`].

Then during name resolution:
- When encountering a single segment path with no generic arguments in generic argument position, we will first try to resolve it in the type namespace and if that fails we then attempt to resolve in the value namespace.
- All other kinds of paths we only try to resolve in the type namespace

See [`LateResolutionVisitor::visit_generic_arg`] for where this is implemented.

Finally during AST lowering when we attempt to lower a type argument, we first check if it is a `Ty::Path` and if it resolved to something in the value namespace.
If it did, then we create an *anon const* and lower to a const argument instead of a type argument.

See [`LoweringContext::lower_generic_arg`] for where this is implemented.

Note that the ambiguity for paths is not propgated into the HIR; there's no `hir::GenericArg::Path` which is turned into either a `Ty` or `Const` during HIR ty lowering (though we could do such a thing).

## Inferred arguments (`_`)

```rust
struct Foo<const N: usize>;

fn foo() {
    let _unused: Foo<_>;
}
```

The only generic arguments which remain ambiguous after lowering are inferred generic arguments (`_`) in path segments.
In the above example,
it is not clear at parse time whether the `_` argument to `Foo` is an inferred type argument,
or an inferred const argument.

In ambig AST positions, inferred arguments are parsed as an [`ast::GenericArg::Ty`] wrapping a [`ast::Ty::Infer`].
Then, during AST lowering, when lowering an `ast::GenericArg::Ty`,
we check if it is an inferred type, and if so, lower to a [`hir::GenericArg::Infer`].

In unambig AST positions, inferred arguments are parsed as either `ast::Ty::Infer` or [`ast::AnonConst`].
The `AnonConst` case is quite strange;
we use [`ast::ExprKind::Underscore`] to represent the "body" of the "anon const",
although in reality we do not actually lower this to an anon const in the HIR.

It may be worth seeing if we can refactor the AST to have `ast::GenericArg::Infer` and then get rid of this overloaded meaning of `AnonConst`,
as well as the reuse of `ast::Ty::Infer` in ambig positions.

In unambig AST positions, during AST lowering we lower inferred arguments to [`hir::TyKind::Infer`][ty_infer] or [`hir::ConstArgKind::Infer`][const_infer] depending on whether it is a type or const position respectively.
In ambig AST positions, during AST lowering we lower inferred arguments to [`hir::GenericArg::Infer`][generic_arg_infer].
See [`LoweringContext::lower_generic_arg`] for where this is implemented.

A naive implementation of this would result in there being potentially 5 places where you might think an inferred type/const could be found in the HIR from looking at the structure of the HIR:
1. In unambig type position as a `TyKind::Infer`
2. In unambig const arg position as a `ConstArgKind::Infer`
3. In an ambig position as a [`GenericArg::Type(TyKind::Infer)`][generic_arg_ty]
4. In an ambig position as a [`GenericArg::Const(ConstArgKind::Infer)`][generic_arg_const]
5. In an ambig position as a `GenericArg::Infer`

Note that places 3 and 4 would never actually be possible to encounter as we always lower to `GenericArg::Infer` in generic arg position.

This has a few failure modes:
- People may write visitors which check for `GenericArg::Infer` but forget to check for `hir::TyKind/ConstArgKind::Infer`, only handling infers in ambig positions by accident.
- People may write visitors which check for `TyKind/ConstArgKind::Infer` but forget to check for `GenericArg::Infer`, only handling infers in unambig positions by accident.
- People may write visitors which check for `GenericArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenericArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`.
- People may write visitors which check for *only* `TyKind::Infer` and not `ConstArgKind::Infer` forgetting that there are also inferred const arguments (and vice versa).

To make writing HIR visitors less error prone when caring about inferred types/consts we have a relatively complex system:

1. We have different types in the compiler for when a type or const is in an unambig or ambig position, `Ty<AmbigArg>` and `Ty<()>`.
   [`AmbigArg`][ambig_arg] is an uninhabited type which we use in the `Infer` variant of `TyKind` and `ConstArgKind` to selectively "disable" it if we are in an ambig position.

2. The [`visit_ty`][visit_ty] and [`visit_const_arg`][visit_const_arg] methods on HIR visitors only accept the ambig position versions of types/consts.
   Unambig types/consts are implicitly converted to ambig types/consts during the visiting process, with the `Infer` variant handled by a dedicated [`visit_infer`][visit_infer] method.

This has a number of benefits:
- It's clear that `GenericArg::Type/Const` cannot represent inferred type/const arguments
- Implementors of `visit_ty` and `visit_const_arg` will never encounter inferred types/consts making it impossible to write a visitor that seems to work right but handles edge cases wrong
- The `visit_infer` method handles *all* cases of inferred type/consts in the HIR making it easy for visitors to handle inferred type/consts in one dedicated place and not forget cases

[ty_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.TyKind.html#variant.Infer
[const_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.ConstArgKind.html#variant.Infer
[generic_arg_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.GenericArg.html#variant.Type
[generic_arg_const]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.GenericArg.html#variant.Const
[generic_arg_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.GenericArg.html#variant.Infer
[ambig_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.AmbigArg.html
[visit_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_ty
[visit_const_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_const_arg
[visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer
[`LateResolutionVisitor::visit_generic_arg`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.LateResolutionVisitor.html#method.visit_generic_arg
[`LoweringContext::lower_generic_arg`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/struct.LoweringContext.html#method.lower_generic_arg
[`ast::GenericArg::Ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.GenericArg.html#variant.Type
[`ast::Ty::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.TyKind.html#variant.Infer
[`ast::AnonConst`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/struct.AnonConst.html
[`hir::GenericArg::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.GenericArg.html#variant.Infer
[`ast::ExprKind::Underscore`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.ExprKind.html#variant.Underscore
[`ast::Ty::Path(N)`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.TyKind.html#variant.Path

---

### Src Doc Rustc Dev Guide Src Asm (`src/doc/rustc-dev-guide/src/asm.md`)

# Inline assembly

## Overview

Inline assembly in rustc mostly revolves around taking an `asm!` macro invocation and plumbing it
through all of the compiler layers down to LLVM codegen.
Throughout the various stages,
an `InlineAsm` generally consists of 3 components:

- The template string, which is stored as an array of `InlineAsmTemplatePiece`.
  Each piece represents either a literal or a placeholder for an operand
  (just like format strings).

  ```rust
  pub enum InlineAsmTemplatePiece {
      String(String),
      Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
  }
  ```

- The list of operands to the `asm!` (`in`, `[late]out`, `in[late]out`, `sym`, `const`).
  These are represented differently at each stage of lowering,
  but follow a common pattern:
  - `in`, `out`, and `inout` all have an associated register class (`reg`)
    or explicit register (`"eax"`).
  - `inout` has 2 forms:
    one with a single expression that is both read from and written to,
    and one with two separate expressions for the input and output parts.
  - `out` and `inout` have a `late` flag (`lateout` / `inlateout`) to indicate that the register
    allocator is allowed to reuse an input register for this output.
  - `out` and the split variant of `inout` allow `_` to be specified for an output,
    which means that the output is discarded.
    This is used to allocate scratch registers for assembly code.
  - `const` refers to an anonymous constants,
    and generally works like an inline const.
  - `sym` is a bit special since it only accepts a path expression,
    which must point to a `static` or a `fn`.

- The options set at the end of the `asm!` macro.
  The only ones that are of particular interest to
  rustc are `NORETURN` which makes `asm!` return `!` instead of `()`,
  and `RAW` which disables format string parsing.
  The remaining options are mostly passed through to LLVM with little processing.

  ```rust
  bitflags::bitflags! {
      pub struct InlineAsmOptions: u16 {
          const PURE = 1 << 0;
          const NOMEM = 1 << 1;
          const READONLY = 1 << 2;
          const PRESERVES_FLAGS = 1 << 3;
          const NORETURN = 1 << 4;
          const NOSTACK = 1 << 5;
          const ATT_SYNTAX = 1 << 6;
          const RAW = 1 << 7;
          const MAY_UNWIND = 1 << 8;
      }
  }
  ```

## AST

`InlineAsm` is represented as an expression in the AST with the [`ast::InlineAsm` type][inline_asm_ast].

The `asm!` macro is implemented in `rustc_builtin_macros` and outputs an `InlineAsm` AST node.
The template string is parsed using `fmt_macros`,
positional and named operands are resolved to explicit operand indices.
Since target information is not available to macro invocations,
validation of the registers and register classes is deferred to AST lowering.

[inline_asm_ast]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/struct.InlineAsm.html

## HIR

`InlineAsm` is represented as an expression in the HIR with the [`hir::InlineAsm` type][inline_asm_hir].

AST lowering is where `InlineAsmRegOrRegClass` is converted from `Symbol`s to an actual register or
register class.
If any modifiers are specified for a template string placeholder, these are
validated against the set allowed for that operand type.
Finally, explicit registers for inputs and
outputs are checked for conflicts (same register used for different operands).

[inline_asm_hir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.InlineAsm.html

## Type checking

Each register class has an allowlist of types that it may be used with.
After the types of all operands have been determined,
the `intrinsicck` pass will check that these types are in the allowlist.
It also checks that split `inout` operands have compatible types and that `const`
operands are integers or floats.
Suggestions are emitted where needed if a template modifier should
be used for an operand based on the type that was passed into it.

## THIR

`InlineAsm` is represented as an expression in the THIR with the [`InlineAsmExpr` type][inline_asm_thir].

The only significant change compared to HIR is that `Sym` has been lowered to either a `SymFn`
whose `expr` is a `Literal` ZST of the `fn`,
or a `SymStatic` which points to the `DefId` of a `static`.

[inline_asm_thir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/thir/struct.InlineAsmExpr.html

## MIR

`InlineAsm` is represented as a `Terminator` in the MIR with the [`TerminatorKind::InlineAsm` variant][inline_asm_mir]

As part of THIR lowering, `InOut` and `SplitInOut` operands are lowered to a split form with a
separate `in_value` and `out_place`.

Semantically, the `InlineAsm` terminator is similar to the `Call` terminator except that it has
multiple output places where a `Call` only has a single return place output.

[inline_asm_mir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.TerminatorKind.html#variant.InlineAsm

## Codegen

Operands are lowered one more time before being passed to LLVM codegen.
This is represented by the [`InlineAsmOperandRef` type][inline_asm_codegen] from `rustc_codegen_ssa`.

The operands are lowered to LLVM operands and constraint codes as follows:
- `out` and the output part of `inout` operands are added first, as required by LLVM.
  Late output operands have a `=` prefix added to their constraint code,
  and non-late output operands have a `=&` prefix added to their constraint code.
- `in` operands are added normally.
- `inout` operands are tied to the matching output operand.
- `sym` operands are passed as function pointers or pointers,
  using the `"s"` constraint.
- `const` operands are formatted to a string and directly inserted in the template string.

The template string is converted to LLVM form:
- `$` characters are escaped as `$$`.
- `const` operands are converted to strings and inserted directly.
- Placeholders are formatted as `${X:M}`,
  where `X` is the operand index and `M` is the modifier character.
  Modifiers are converted from the Rust form to the LLVM form.

The various options are converted to clobber constraints or LLVM attributes;
refer to the [RFC] for more details.

Note that LLVM is sometimes rather picky about what types it accepts for certain constraint codes
so we sometimes need to insert conversions to/from a supported type.
See the target-specific ISelLowering.cpp files in LLVM
for details of what types are supported for each register class.

[inline_asm_codegen]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/traits/enum.InlineAsmOperandRef.html
[RFC]: https://github.com/Amanieu/rfcs/blob/inline-asm/text/0000-inline-asm.md#mapping-to-llvm-ir

## Adding support for new architectures

Adding inline assembly support to an architecture is mostly a matter of defining the registers and
register classes for that architecture.
All the definitions for register classes are located in
`compiler/rustc_target/asm/`.

Additionally you will need to implement lowering of these register classes to LLVM constraint codes
in `compiler/rustc_codegen_llvm/asm.rs`.

When adding a new architecture, make sure to cross-reference with the LLVM source code:
- LLVM has restrictions on which types can be used with a particular constraint code.
  Refer to the `getRegForInlineAsmConstraint` function
  in `lib/Target/${ARCH}/${ARCH}ISelLowering.cpp`.
- LLVM reserves certain registers for its internal use,
  which causes them to not be saved/restored properly around inline assembly blocks.
  These registers are listed in the `getReservedRegs`
  function in `lib/Target/${ARCH}/${ARCH}RegisterInfo.cpp`.
  Any "conditionally" reserved register,
  such as the frame/base pointer,
  must always be treated as reserved for Rust purposes because we
  can't know ahead of time whether a function will require a frame/base pointer.

## Tests

Various tests for inline assembly are available:

- `tests/assembly-llvm/asm`
- `tests/ui/asm`
- `tests/codegen-llvm/asm-*`

Every architecture supported by inline assembly must have exhaustive tests in
`tests/assembly-llvm/asm` which test all combinations of register classes and types.

---

### Src Doc Rustc Dev Guide Src Ast Validation (`src/doc/rustc-dev-guide/src/ast-validation.md`)

# AST validation

_AST validation_ is a separate AST pass that visits each
item in the tree and performs simple checks.
This pass doesn't perform any complex analysis, type checking or
name resolution.

Before performing any validation, the compiler first expands the macros.
Then this pass performs validations to check that each AST item is in the correct state.
And when this pass is done, the compiler runs the crate resolution pass.

## Validations

Validations are defined in `AstValidator` type, which 
itself is located in `rustc_ast_passes` crate.
This type implements various simple checks which emit errors
when certain language rules are broken.

In addition, `AstValidator` implements `Visitor` trait
that defines how to visit AST items (which can be functions,
traits, enums, etc).

For each item, visitor performs specific checks.
For example, when visiting a function declaration,
`AstValidator` checks that the function has:

* no more than `u16::MAX` parameters;
* c-variadic argument goes the last in the declaration;
* documentation comments aren't applied to function parameters;
* and other validations.

---

### Src Doc Rustc Dev Guide Src Attributes (`src/doc/rustc-dev-guide/src/attributes.md`)

# Attributes

Attributes come in two types: *inert* (or *built-in*) and *active* (*non-builtin*).

## Builtin/inert attributes

These attributes are defined in the compiler itself, in
[`compiler/rustc_feature/src/builtin_attrs.rs`][builtin_attrs] and in the [attribute parsers][attr_parsing].

Examples include `#[allow]` and `#[macro_use]`.

[builtin_attrs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_feature/builtin_attrs/index.html
[attr_parsing]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html

These attributes have several important characteristics:
* They are always in scope, and do not participate in typical path-based resolution.
* They cannot be renamed.
  For example, `use allow as foo` will compile, but writing `#[foo]` will produce an error.
* They are 'inert', meaning they are left as-is by the macro expansion code.
  As a result, any behavior comes as a result of the compiler explicitly checking for their presence.
  For example, lint-related code explicitly checks for `#[allow]`, `#[warn]`, `#[deny]`, and
  `#[forbid]`, rather than the behavior coming from the expansion of the attributes themselves.

For more information on these attributes, see the chapter about [attribute parsing][attr-parsing-chapter].

[attr-parsing-chapter]: ./hir/attribute-parsing.md

### Note on adding new builtin attributes

<div class="warning">

**Warning: Name resolution ambiguity potential when adding new builtin attributes**

Please note that adding **new builtin attributes** (whose name is not reserved, i.e. a new builtin
attribute whose name does not start with `rustc`), even if *unstable*-gated, can introduce breakage
from name resolution ambiguity in stable code if (1) the stable code has a macro of the same name
which gets re-exported, or (2) or a proc-macro derive helper attribute of the same name.

Typically, the builtin attributes probably has to start out as `#[rustc_foo]` instead of `#[foo]` to
avoid colliding with user-defined macros and proc-macro helper attributes.
Then, prior to stabilization,
a rename to `#[foo]` should be done separately with a crater run to assess fallout,
with a deliberate breakage FCP proposal for T-lang to consider.

Remember also that crater is *not* exhaustive and does not contain all existing stable code.

See:
- [Built-in attributes are treated differently vs prelude attributes, unstable built-in attributes
  can name-collide with stable macro, and built-in attributes can break back-compat
  #134963](https://github.com/rust-lang/rust/issues/134963) and backlinks within this issue,
  including design discussions on how to fix this kind of breakage hazard.
- [Broken build after updating: coverage is ambiguous; ambiguous because of a name conflict with a
  builtin attribute #121157](https://github.com/rust-lang/rust/issues/121157).
- [Regression: align is ambiguous #143834](https://github.com/rust-lang/rust/issues/143834).
</div>

## 'Non-builtin'/'active' attributes

These attributes are defined by a crate - either the standard library, or a proc-macro crate.

**Important**: Many non-builtin attributes, such as `#[derive]`, are still considered part of the
core Rust language.
However, they are **not** called 'builtin attributes', since they have a
corresponding definition in the standard library.

Definitions of non-builtin attributes take two forms:

1. Proc-macro attributes, defined via a function annotated with `#[proc_macro_attribute]` in a
   proc-macro crate.
2. AST-based attributes, defined in the standard library.
   These attributes have special 'stub'
   macros defined in places like [`library/core/src/macros/mod.rs`][core_macros].

[core_macros]:  https://github.com/rust-lang/rust/blob/HEAD/library/core/src/macros/mod.rs

These definitions exist to allow the macros to participate in typical path-based resolution - they
can be imported, re-exported, and renamed just like any other item definition.
However, the body of the definition is empty.
Instead, the macro is annotated with the `#[rustc_builtin_macro]`
attribute, which tells the compiler to run a corresponding function in `rustc_builtin_macros`.

All non-builtin attributes have the following characteristics:
* Like all other definitions (e.g. structs), they must be brought into scope via an import.
  Many standard library attributes are included in the prelude - this is why writing `#[derive]`
  works without an import.
* They participate in macro expansion.
  The implementation of the macro may leave the attribute
  target unchanged, modify the target, produce new AST nodes, or remove the target entirely.

---

### Src Doc Rustc Dev Guide Src Borrow Check (`src/doc/rustc-dev-guide/src/borrow-check.md`)

# MIR borrow check

The borrow check is Rust's "secret sauce" – it is tasked with enforcing a number of properties:

- That all variables are initialized before they are used.
- That you can't move the same value twice.
- That you can't move a value while it is borrowed.
- That you can't access a place while it is mutably borrowed (except through the reference).
- That you can't mutate a place while it is immutably borrowed.
- etc

The borrow checker operates on the MIR.
An older implementation operated on the HIR.
Doing borrow checking on MIR has several advantages:

- The MIR is *far* less complex than the HIR; the radical desugaring
  helps prevent bugs in the borrow checker.
  (If you're curious, you can see
  [a list of bugs that the MIR-based borrow checker fixes here][47366].)
- Even more importantly, using the MIR enables ["non-lexical lifetimes"][nll],
  which are regions derived from the control-flow graph.

[47366]: https://github.com/rust-lang/rust/issues/47366
[nll]: https://rust-lang.github.io/rfcs/2094-nll.html

## Major phases of the borrow checker

The borrow checker source is found in [the `rustc_borrowck` crate][b_c].
The main entry point is the [`mir_borrowck`] query.

[b_c]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/index.html
[`mir_borrowck`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/fn.mir_borrowck.html

- We first create a **local copy** of the MIR.
  In the coming steps,
  we will modify this copy in place to modify the types and things to
  include references to the new regions that we are computing.
- We then invoke [`replace_regions_in_mir`] to modify our local MIR.
  Among other things, this function will replace all of the [regions](./appendix/glossary.md#region)
  in the MIR with fresh [inference variables](./appendix/glossary.md#inf-var).
- Next, we perform a number of [dataflow analyses](./appendix/background.md#dataflow) that
  compute what data is moved and when.
- We then do a [second type check](borrow-check/type-check.md) across the MIR:
  the purpose of this type check is to determine all of the constraints between different regions.
- Next, we do [region inference](borrow-check/region-inference.md), which computes
  the values of each region — basically, the points in the control-flow graph where
  each lifetime must be valid according to the constraints we collected.
- At this point, we can compute the "borrows in scope" at each point.
- Finally, we do a second walk over the MIR, looking at the actions it does and reporting errors.
  For example, if we see a statement like `*a + 1`,
  we would check that the variable `a` is initialized and that it is not mutably borrowed,
  as either of those would require an error to be reported.
  Doing this check requires the results of all the previous analyses.

[`replace_regions_in_mir`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/nll/fn.replace_regions_in_mir.html


## Debugging the borrow checker

See [Debugging the borrow checker](borrow-check/debugging.md) and [MIR Debugging](mir/debugging.md).

---

### Src Doc Rustc Dev Guide Src Bug Fix Procedure (`src/doc/rustc-dev-guide/src/bug-fix-procedure.md`)

# Procedures for breaking changes

This page defines the best practices procedure for making bug fixes or soundness
corrections in the compiler that can cause existing code to stop compiling.
This text is based on [RFC 1589].

# Motivation

[motivation]: #motivation

From time to time, we encounter the need to make a bug fix, soundness
correction, or other change in the compiler which will cause existing code to stop compiling.
When this happens, it is important that we handle the change in
a way that gives users of Rust a smooth transition.
What we want to avoid is that existing programs suddenly stop compiling with opaque error messages:
we would prefer to have a gradual period of warnings, with clear guidance as to
what the problem is, how to fix it, and why the change was made.
This RFC describes the procedure that we have been developing for handling breaking
changes that aims to achieve that kind of smooth transition.

One of the key points of this policy is that (a) warnings should be issued
initially rather than hard errors if at all possible and (b) every change that
causes existing code to stop compiling will have an associated tracking issue.
This issue provides a point to collect feedback on the results of that change.
Sometimes changes have unexpectedly large consequences or there may be a way to
avoid the change that was not considered.
In those cases,
we may decide to change course and roll back the change,
or find another solution (and if warnings are being used, this is particularly easy to do).

### What qualifies as a bug fix?

Note that this RFC does not try to define when a breaking change is permitted.
That is already covered under [RFC 1122].
This document assumes that the change being made is in accordance with those policies.
Here is a summary of the conditions from RFC 1122:

- **Soundness changes:** Fixes to holes uncovered in the type system.
- **Compiler bugs:** Places where the compiler is not implementing the specified
  semantics found in an RFC or lang-team decision.
- **Underspecified language semantics:** Clarifications to grey areas where the
  compiler behaves inconsistently and no formal behavior had been previously decided.

Please see [the RFC][rfc 1122] for full details!

# Detailed design

[design]: #detailed-design

The procedure for making a breaking change is as follows (each of these steps is
described in more detail below):

1. Do a **crater run** to assess the impact of the change.
2. Make a **special tracking issue** dedicated to the change.
3. Do not report an error right away.
   Instead, **issue forwards-compatibility lint warnings**.
   - Sometimes this is not straightforward.
     See the text below for suggestions on different techniques we have employed in the past.
   - For cases where warnings are infeasible:
     - Report errors, but make every effort to give a targeted error message
       that directs users to the tracking issue
     - Submit PRs to all known affected crates that fix the issue
       - or, at minimum, alert the owners of those crates to the problem and
         direct them to the tracking issue
4. Once the change has been in the wild for at least one cycle, we can
   **stabilize the change**, converting those warnings into errors.

Finally, for changes to `rustc_ast` that will affect plugins, the general policy
is to batch these changes.
That is discussed below in more detail.

### Tracking issue

Every breaking change should be accompanied by a **dedicated tracking issue** for that change.
The main text of this issue should describe the change being
made, with a focus on what users must do to fix their code.
The issue should be approachable and practical; it may make sense to direct users to an RFC or some
other issue for the full details.
The issue also serves as a place where users can comment with questions or other concerns.

A template for these breaking-change tracking issues can be found [here][template].
An example of how such an issue should look can be [found here][breaking-change-issue].

[template]: https://github.com/rust-lang/rust/issues/new?template=tracking_issue_future.md

### Issuing future compatibility warnings

The best way to handle a breaking change is to begin by issuing future-compatibility warnings.
These are a special category of lint warning.
Adding a new future-compatibility warning can be done as follows.

```rust
// 1. Define the lint in `compiler/rustc_lint/src/builtin.rs` and
//    add the metadata for the future incompatibility:
declare_lint! {
    pub YOUR_LINT_HERE,
    Warn,
    "illegal use of foo bar baz"
    @future_incompatible = FutureIncompatibleInfo {
        reason: fcw!(FutureReleaseError #1234) // your tracking issue here!
    },
}

// 2. Add a dedicated lint pass for it.
//    This step can be skipped if you emit the lint as part of an existing pass.

#[derive(Default)]
pub struct MyLintPass {
    ...
}

impl {Early,Late}LintPass for MyLintPass {
    ...
}

impl_lint_pass!(MyLintPass => [YOUR_LINT_HERE]);

// 3. emit the lint somewhere in your lint pass:
cx.emit_span_lint(
    YOUR_LINT_HERE,
    pat.span,
    // some diagnostic struct
    MyDiagnostic {
        ...
    },
);

```

Finally, register the lint in `compiler/rustc_lint/src/lib.rs`.
There are many examples in that file that already show how to do so.

#### Helpful techniques

It can often be challenging to filter out new warnings from older, pre-existing errors.
One technique that has been used in the past is to run the older code
unchanged and collect the errors it would have reported.
You can then issue warnings for any errors you would give which do not appear in that original set.
Another option is to abort compilation after the original code completes if
errors are reported: then you know that your new code will only execute when
there were no errors before.

#### Crater and crates.io

[Crater] is a bot that will compile all crates.io crates and many
public github repos with the compiler with your changes.
A report will then be generated with crates that ceased to compile with,
or began to compile with your changes.
Crater runs can take a few days to complete.

[Crater]: ./tests/crater.md

We should always do a crater run to assess impact.
It is polite and considerate to notify the authors of crates affected by the breaking change.
It is even better to submit PRs fixing the breakage.

#### Is it ever acceptable to go directly to issuing errors?

Changes that are believed to have negligible impact can go directly to issuing an error.
One rule of thumb would be to check against `crates.io`: if fewer than
10 **total** affected projects are found (**not** root errors), we can move straight to an error.
In such cases, we should still make the "breaking change"
page as before, and we should ensure that the error directs users to this page.
In other words, everything should be the same except that users are getting an
error, and not a warning.
Moreover, we should submit PRs to the affected projects
(ideally before the PR implementing the change lands in rustc).

If the impact is not believed to be negligible (e.g., more than 10 crates are
affected), then warnings are required (unless the compiler team agrees to grant
a special exemption in some particular case).
If implementing warnings is not feasible,
then we should make an aggressive strategy of migrating crates before
we land the change so as to lower the number of affected crates.
Here are some techniques for approaching this scenario:

1. Issue warnings for subparts of the problem, and reserve the new errors for
   the smallest set of cases you can.
2. Try to give a very precise error message that suggests how to fix the problem
   and directs users to the tracking issue.
3. It may also make sense to layer the fix:
   - First, add warnings where possible and let those land before proceeding to issue errors.
   - Work with authors of affected crates to ensure that corrected versions are
     available _before_ the fix lands, so that downstream users can use them.

### Stabilization

After a change is made, we will **stabilize** the change using the same process
that we use for unstable features:

- After a new release is made, we will go through the outstanding tracking
  issues corresponding to breaking changes and nominate some of them for **final
  comment period** (FCP).
- The FCP for such issues lasts for one cycle.
  In the final week or two of the cycle, we will review comments and make a final determination:

  - Convert to error: the change should be made into a hard error.
  - Revert: we should remove the warning and continue to allow the older code to compile.
  - Defer: can't decide yet, wait longer, or try other strategies.

Ideally, breaking changes should have landed on the **stable branch** of the
compiler before they are finalized.

<a id="guide"></a>

### Removing a lint

Once we have decided to make a "future warning" into a hard error, we need a PR
that removes the custom lint.
As an example, here are the steps required to
remove the `overlapping_inherent_impls` compatibility lint.
First, convert the name of the lint to uppercase (`OVERLAPPING_INHERENT_IMPLS`);
search the source for that string.
We will basically by converting each place where this
lint name is mentioned (in the compiler, we use the upper-case name, and a macro
automatically generates the lower-case string; so searching for
`overlapping_inherent_impls` would not find much).

> NOTE: these exact files don't exist anymore, but the procedure is still the same.

#### Remove the lint.

The first reference you will likely find is the lint definition [in
`rustc_session/src/lint/builtin.rs` that resembles this][defsource]:

[defsource]: https://github.com/rust-lang/rust/blob/085d71c3efe453863739c1fb68fd9bd1beff214f/src/librustc/lint/builtin.rs#L171-L175

```rust
declare_lint! {
    pub OVERLAPPING_INHERENT_IMPLS,
    Deny, // this may also say Warning
    "two overlapping inherent impls define an item with the same name were erroneously allowed",
    @future_incompatible = FutureIncompatibleInfo {
        reason: fcw!(FutureReleaseError #1234), // your tracking issue here!
    },
}
```

This `declare_lint!` macro creates the relevant data structures.
Remove it.
You will also find that there is a mention of `OVERLAPPING_INHERENT_IMPLS` later in
the file as [part of a `lint_array!`][lintarraysource]; remove it too.

[lintarraysource]: https://github.com/rust-lang/rust/blob/085d71c3efe453863739c1fb68fd9bd1beff214f/src/librustc/lint/builtin.rs#L252-L290

#### Add the lint to the list of removed lints.

In `compiler/rustc_lint/src/lib.rs` there is a list of "renamed and removed lints".
You can add this lint to the list:

```rust
store.register_removed("overlapping_inherent_impls", "converted into hard error, see #36889");
```

where `#36889` is the tracking issue for your lint.

#### Update the places that issue the lint

Finally, the last class of references you will see are the places that actually
**trigger** the lint itself (i.e., what causes the warnings to appear). These
you do not want to delete.
Instead, you want to convert them into errors.
In this case, the [`add_lint` call][addlintsource] looks like this:

```rust
self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS,
                       node_id,
                       self.tcx.span_of_impl(item1).unwrap(),
                       msg);
```

You'll also often find `node_span_lint` used for this.

We want to convert this into an error.
In some cases, there may be an existing error for this scenario.
In others, we will need to allocate a fresh diagnostic code.
 [Instructions for allocating a fresh diagnostic
code can be found here.](./diagnostics/error-codes.md) You may want
to mention in the extended description that the compiler behavior
changed on this point, and include a reference to the tracking issue for the change.

Let's say that we've adopted `E0592` as our code.
Then we can change the `add_lint()` call above to something like:

```rust
struct_span_code_err!(self.dcx(), self.tcx.span_of_impl(item1).unwrap(), E0592, msg)
    .emit();
```

Or better: a structured diagnostic like this:

```rust
#[derive(Diagnostic)]
struct MyDiagnostic {
    #[label]
    span: Span,
    ...
}
```

#### Update tests

Finally, run the test suite.
These should be some tests that used to reference
the `overlapping_inherent_impls` lint; those will need to be updated.
In general, if the test used to have `#[deny(overlapping_inherent_impls)]`, that
can just be removed.

```
./x test
```

#### All done!

Open a PR.

[addlintsource]: https://github.com/rust-lang/rust/blob/085d71c3efe453863739c1fb68fd9bd1beff214f/src/librustc_typeck/coherence/inherent.rs#L300-L303
[futuresource]: https://github.com/rust-lang/rust/blob/085d71c3efe453863739c1fb68fd9bd1beff214f/src/librustc_lint/lib.rs#L202-L205



[rfc 1122]: https://github.com/rust-lang/rfcs/blob/master/text/1122-language-semver.md
[breaking-change-issue]: https://gist.github.com/nikomatsakis/631ec8b4af9a18b5d062d9d9b7d3d967
[RFC 1589]: https://github.com/rust-lang/rfcs/blob/master/text/1589-rustc-bug-fix-procedure.md

---

### Src Doc Rustc Dev Guide Src Cli (`src/doc/rustc-dev-guide/src/cli.md`)

# Command-line Arguments

Command-line flags are documented in the [rustc book][cli-docs].
All *stable* flags should be documented there.
Unstable flags should be documented in the [unstable book].

See the [forge guide for new options] for details on the *procedure* for
adding a new command-line argument.

## Guidelines

- Flags should be orthogonal to each other.
  For example, if we'd have a json-emitting variant of multiple actions `foo` and `bar`,
  an additional `--json` flag is better than adding `--foo-json` and `--bar-json`.
- Avoid flags with the `no-` prefix.
  Instead, use the [`parse_bool`] function,
  such as `-C embed-bitcode=no`.
- Consider the behavior if the flag is passed multiple times.
  In some situations, the values should be accumulated (in order!).
  In other situations, subsequent flags should override previous flags (for example,
  the lint-level flags).
  And some flags (like `-o`) should generate an error
  if it is too ambiguous what multiple flags would mean.
- Always give options a long descriptive name, if only for more understandable compiler scripts.
- The `--verbose` flag is for adding verbose information to `rustc` output.
  For example,
  using it with the `--version` flag gives information about the hashes of the compiler code.
- Experimental flags and options must be guarded behind the `-Z unstable-options` flag.

[cli-docs]: https://doc.rust-lang.org/rustc/command-line-arguments.html
[forge guide for new options]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#compiler-flags
[unstable book]: https://doc.rust-lang.org/nightly/unstable-book/
[`parse_bool`]: https://github.com/rust-lang/rust/blob/e5335592e78354e33d798d20c04bcd677c1df62d/src/librustc_session/options.rs#L307-L313

---

### Src Doc Rustc Dev Guide Src Closure (`src/doc/rustc-dev-guide/src/closure.md`)

# Closure Capture Inference

This section describes how rustc handles closures.
Closures in Rust are effectively "desugared" into structs that contain the values they use (or
references to the values they use) from their creator's stack frame.
rustc has the job of figuring out which values a closure uses and how, so it can decide
whether to capture a given variable by shared reference, mutable reference, or by move.
rustc also has to figure out which of the closure traits ([`Fn`][fn],
[`FnMut`][fn_mut], or [`FnOnce`][fn_once]) a closure is capable of implementing.

[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html
[fn_mut]:https://doc.rust-lang.org/std/ops/trait.FnMut.html
[fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html

Let's start with a few examples:

### Example 1

To start, let's take a look at how the closure in the following example is desugared:

```rust
fn closure(f: impl Fn()) {
    f();
}

fn main() {
    let x: i32 = 10;
    closure(|| println!("Hi {}", x));  // The closure just reads x.
    println!("Value of x after return {}", x);
}
```

Let's say the above is the content of a file called `immut.rs`.
If we compile `immut.rs` using the following command,
the [`-Z dump-mir=all`][dump-mir] flag will cause
`rustc` to generate and dump the [MIR] to a directory called `mir_dump`.

```console
> rustc +stage1 immut.rs -Z dump-mir=all
```

[mir]: ./mir/index.md
[dump-mir]: ./mir/passes.md

After we run this command, we will see a newly generated directory in our
current working directory called `mir_dump`, which will contain several files.
If we look at file `rustc.main.-------.mir_map.0.mir`, we will find, among other things,
it also contains this line:

```rust,ignore
_4 = &_1;
_3 = [closure@immut.rs:7:13: 7:36] { x: move _4 };
```

Note that in the MIR examples in this chapter, `_1` is `x`.

Here in first line `_4 = &_1;`,
the `mir_dump` tells us that `x` was borrowed as an immutable reference.
This is what we would hope as our closure just reads `x`.

### Example 2

Here is another example:

```rust
fn closure(mut f: impl FnMut()) {
    f();
}

fn main() {
    let mut x: i32 = 10;
    closure(|| {
        x += 10;  // The closure mutates the value of x
        println!("Hi {}", x)
    });
    println!("Value of x after return {}", x);
}
```

```rust,ignore
_4 = &mut _1;
_3 = [closure@mut.rs:7:13: 10:6] { x: move _4 };
```
This time along, in the line `_4 = &mut _1;`, we see that the borrow is changed to mutable borrow.
Fair enough!
The closure increments `x` by 10.

### Example 3

One more example:

```rust
fn closure(f: impl FnOnce()) {
    f();
}

fn main() {
    let x = vec![21];
    closure(|| {
        drop(x);  // Makes x unusable after the fact.
    });
    // println!("Value of x after return {:?}", x);
}
```

```rust,ignore
_6 = [closure@move.rs:7:13: 9:6] { x: move _1 }; // bb16[3]: scope 1 at move.rs:7:13: 9:6
```
Here, `x` is directly moved into the closure,
and the access to it will not be permitted after the closure.

## Inferences in the compiler

Now let's dive into rustc code and see how all these inferences are done by the compiler.

Let's start with defining a term that we will be using quite a bit in the rest of the discussion -
*upvar*.
An **upvar** is a variable that is local to the function where the closure is defined.
So, in the above examples, **x** will be an upvar to the closure.
They are also sometimes referred to as the *free variables*,
meaning they are not bound to the context of the closure.
[`compiler/rustc_passes/src/upvars.rs`][upvars] defines a query called *upvars_mentioned*
for this purpose.

[upvars]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_passes/upvars/index.html

Other than lazy invocation,
one other thing that distinguishes a closure from a normal function is that it can use the upvars.
It borrows these upvars from its surrounding
context; therefore the compiler has to determine the upvar's borrow type.
The compiler starts with assigning an immutable borrow type and lowers the restriction
(that is, changes it from **immutable** to **mutable** to **move**) as needed, based on the usage.
In the Example 1 above,
the closure only uses the variable for printing but does not modify it in any way and therefore,
in the `mir_dump`, we find the borrow type for the upvar `x` to be immutable.
In example 2, however, the closure modifies `x` and increments it by some value.
Because of this mutation, the compiler, which
started off assigning `x` as an immutable reference type, has to adjust it as a mutable reference.
Likewise in the third example, the closure drops the vector and therefore this requires the variable
`x` to be moved into the closure.
Depending on the borrow kind, the closure has to implement the
appropriate trait: `Fn` trait for immutable borrow, `FnMut` for mutable borrow,
and `FnOnce` for move semantics.

Most of the code related to the closure is in the
[`compiler/rustc_hir_typeck/src/upvar.rs`][upvar] file and the data structures are
declared in the file [`compiler/rustc_middle/src/ty/mod.rs`][ty].

[upvar]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/upvar/index.html
[ty]:https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/index.html

Before we go any further,
let's discuss how we can examine the flow of control through the rustc codebase.
For closures specifically,
set the `RUSTC_LOG` env variable as below and collect the output in a file:

```console
> RUSTC_LOG=rustc_hir_typeck::upvar rustc +stage1 -Z dump-mir=all \
    <.rs file to compile> 2> <file where the output will be dumped>
```

This uses the stage1 compiler and enables `debug!` logging for the `rustc_hir_typeck::upvar` module.

The other option is to step through the code using lldb or gdb.

1. `rust-lldb build/host/stage1/bin/rustc test.rs`
2. In lldb:
    1. `b upvar.rs:134`  // Setting the breakpoint on a certain line in the upvar.rs file
    2. `r`  // Run the program until it hits the breakpoint

Let's start with [`upvar.rs`][upvar].
This file has something called the [`euv::ExprUseVisitor`] which walks the source of the closure and
invokes a callback for each upvar that is borrowed, mutated, or moved.

[`euv::ExprUseVisitor`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/expr_use_visitor/struct.ExprUseVisitor.html

```rust
fn main() {
    let mut x = vec![21];
    let _cl = || {
        let y = x[0];  // 1.
        x[0] += 1;  // 2.
    };
}
```

In the above example, our visitor will be called twice, for the lines marked 1 and 2,
once for a shared borrow and another one for a mutable borrow.
It will also tell us what was borrowed.

The callbacks are defined by implementing the [`Delegate`] trait.
The [`InferBorrowKind`][ibk] type implements `Delegate` and keeps a map that
records for each upvar which mode of capture was required.
The modes of capture can be `ByValue` (moved) or `ByRef` (borrowed).
For `ByRef` borrows, the possible [`BorrowKind`]s are `ImmBorrow`,
`UniqueImmBorrow`, `MutBorrow` as defined in the
[`compiler/rustc_middle/src/ty/mod.rs`][middle_ty].

[`BorrowKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.BorrowKind.html
[middle_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/index.html

`Delegate` defines a few different methods (the different callbacks):
**consume** for *move* of a variable, **borrow** for a *borrow* of some kind (shared or mutable),
and **mutate** when we see an *assignment* of something.

All of these callbacks have a common argument *cmt* which stands for Category,
Mutability and Type and is defined in [`compiler/rustc_hir_typeck/src/expr_use_visitor.rs`][cmt].
Borrowing from the code comments, "`cmt` is a complete categorization of a value indicating where it
originated and how it is located, as well as the mutability of the memory in
which the value is stored". Based on the callback (consume, borrow etc.), we
will call the relevant `adjust_upvar_borrow_kind_for_<something>` and pass the `cmt` along.
Once the borrow type is adjusted, we store it in the table,
which basically says what borrows were made for each closure.

```rust,ignore
self.tables
    .borrow_mut()
    .upvar_capture_map
    .extend(delegate.adjust_upvar_captures);
```

[`Delegate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/expr_use_visitor/trait.Delegate.html
[ibk]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/upvar/struct.InferBorrowKind.html
[cmt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/expr_use_visitor/index.html

---

### Src Doc Rustc Dev Guide Src Coherence (`src/doc/rustc-dev-guide/src/coherence.md`)

# Coherence

> NOTE: this is based on [notes by @lcnr](https://github.com/rust-lang/rust/pull/121848)

Coherence checking is what detects both of trait impls and inherent impls overlapping with others.
(reminder: [inherent impls](https://doc.rust-lang.org/reference/items/implementations.html#inherent-implementations) are impls of concrete types like `impl MyStruct {}`)

Overlapping trait impls always produce an error,
while overlapping inherent impls result in an error only if they have methods with the same name.

Checking for overlaps is split in two parts.
First there's the [overlap check(s)](#overlap-checks),
which finds overlaps between traits and inherent implementations that the compiler currently knows about.

However, Coherence also results in an error if any other impls **could** exist,
even if they are currently unknown.
This affects impls which may get added to upstream crates in a backwards compatible way,
and impls from downstream crates.
This is called the Orphan check.

## Overlap checks

Overlap checks are performed for both inherent impls, and for trait impls.
This uses the same overlap checking code, really done as two separate analyses.
Overlap checks always consider pairs of implementations, comparing them to each other.

Overlap checking for inherent impl blocks is done through `fn check_item` (in coherence/inherent_impls_overlap.rs),
where you can very clearly see that (at least for small `n`), the check really performs `n^2`
comparisons between impls.

In the case of traits, this check is currently done as part of building the [specialization graph](traits/specialization.md),
to handle specializing impls overlapping with their parent, but this may change in the future.

In both cases, all pairs of impls are checked for overlap.

Overlapping is sometimes partially allowed:

1. for marker traits
2. under [specialization](traits/specialization.md)

It normally isn't.

The overlap check has various modes (see [`OverlapMode`]).
Importantly, there's the explicit negative impl check, and the implicit negative impl check.
Both try to prove that an overlap is definitely impossible.

[`OverlapMode`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_middle/traits/specialization_graph/enum.OverlapMode.html

### The explicit negative impl check

This check is done in [`impl_intersection_has_negative_obligation`].

This check tries to find a negative trait implementation.
For example:

```rust
struct MyCustomErrorType;

// both in your own crate
impl From<&str> for MyCustomErrorType {}
impl<E> From<E> for MyCustomErrorType where E: Error {}
```

In this example, we'd get:
`MyCustomErrorType: From<&str>` and `MyCustomErrorType: From<?E>`, giving `?E = &str`.

And thus, these two implementations would overlap.
However, libstd provides `&str: !Error`, and therefore guarantees that there
will never be a positive implementation of `&str: Error`, and thus there is no overlap.

Note that for this kind of negative impl check, we must have explicit negative implementations provided.
This is not currently stable.

[`impl_intersection_has_negative_obligation`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_trait_selection/traits/coherence/fn.impl_intersection_has_negative_obligation.html

### The implicit negative impl check

This check is done in [`impl_intersection_has_impossible_obligation`],
and does not rely on negative trait implementations and is stable.

Let's say there's a
```rust
impl From<MyLocalType> for Box<dyn Error> {}  // in your own crate
impl<E> From<E> for Box<dyn Error> where E: Error {} // in std
```

This would give: `Box<dyn Error>: From<MyLocalType>`, and `Box<dyn Error>: From<?E>`,
giving `?E = MyLocalType`.

In your crate there's no `MyLocalType: Error`, downstream crates cannot implement `Error` (a remote trait) for `MyLocalType` (a remote type).
Therefore, these two impls do not overlap.
Importantly, this works even if there isn't a `impl !Error for MyLocalType`.

[`impl_intersection_has_impossible_obligation`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_trait_selection/traits/coherence/fn.impl_intersection_has_impossible_obligation.html

---

### Src Doc Rustc Dev Guide Src Compiler Debugging (`src/doc/rustc-dev-guide/src/compiler-debugging.md`)

# Debugging the compiler

This chapter contains a few tips to debug the compiler.
These tips aim to be useful no matter what you are working on.
Some of the other chapters have
advice about specific parts of the compiler (e.g. the [Queries Debugging and
Testing chapter](./incrcomp-debugging.md) or the [LLVM Debugging chapter](./backend/debugging.md)).

## Configuring the compiler

By default, rustc is built without most debug information.
To enable debug info,
set `rust.debug = true` in your bootstrap.toml.

Setting `rust.debug = true` turns on many different debug options (e.g., `debug-assertions`,
`debug-logging`, etc.) which can be individually tweaked if you want to, but many people
simply set `rust.debug = true`.

If you want to use GDB to debug rustc, please set `bootstrap.toml` with options:

```toml
rust.debug = true
rust.debuginfo-level = 2
```

> NOTE:
> This will use a lot of disk space
> (upwards of  35GB),
> and will take a lot more compile time.
> With `debuginfo-level = 1` (the default when `debug = true`),
> you will be able to track the execution path,
> but will lose the symbol information for debugging.

The default configuration will enable `symbol-mangling-version` v0.
This requires at least GDB v10.2,
otherwise you need to disable new symbol-mangling-version in `bootstrap.toml`.

```toml
rust.new-symbol-mangling = false
```

> See the comments in `bootstrap.example.toml` for more info.

You will need to rebuild the compiler after changing any configuration option.

## Suppressing the ICE file

By default, if rustc encounters an Internal Compiler Error (ICE) it will dump the ICE contents to an
ICE file within the current working directory named `rustc-ice-<timestamp>-<pid>.txt`.
If this is not desirable, you can prevent the ICE file from being created with `RUSTC_ICE=0`.

## Getting a backtrace
[getting-a-backtrace]: #getting-a-backtrace

When you have an ICE (panic in the compiler),
you can set `RUST_BACKTRACE=1` to get the stack trace of the `panic!` like in normal Rust programs.
IIRC backtraces **don't work** on MinGW, sorry.
If you have trouble or the backtraces are full of `unknown`,
you might want to find some way to use Linux, Mac, or MSVC on Windows.

In the default configuration (without `debug` set to `true`), you don't have line numbers enabled,
so the backtrace looks like this:

```text
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::_print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: std::panicking::rust_panic_with_hook
   5: std::panicking::begin_panic
   (~~~~ LINES REMOVED BY ME FOR BREVITY ~~~~)
  32: rustc_typeck::check_crate
  33: <std::thread::local::LocalKey<T>>::with
  34: <std::thread::local::LocalKey<T>>::with
  35: rustc::ty::context::TyCtxt::create_and_enter
  36: rustc_driver::driver::compile_input
  37: rustc_driver::compiler_entrypoint
```

If you set `debug = true`, you will get line numbers for the stack trace.
Then the backtrace will look like this:

```text
stack backtrace:
   (~~~~ LINES REMOVED BY ME FOR BREVITY ~~~~)
             at /home/user/rust/compiler/rustc_typeck/src/check/cast.rs:110
   7: rustc_typeck::check::cast::CastCheck::check
             at /home/user/rust/compiler/rustc_typeck/src/check/cast.rs:572
             at /home/user/rust/compiler/rustc_typeck/src/check/cast.rs:460
             at /home/user/rust/compiler/rustc_typeck/src/check/cast.rs:370
   (~~~~ LINES REMOVED BY ME FOR BREVITY ~~~~)
  33: rustc_driver::driver::compile_input
             at /home/user/rust/compiler/rustc_driver/src/driver.rs:1010
             at /home/user/rust/compiler/rustc_driver/src/driver.rs:212
  34: rustc_driver::compiler_entrypoint
             at /home/user/rust/compiler/rustc_driver/src/lib.rs:253
```

## `-Z` flags

The compiler has a bunch of `-Z *` flags.
These are unstable flags that are only enabled on nightly.
Many of them are useful for debugging.
To get a full listing of `-Z` flags, use `-Z help`.

One useful flag is `-Z verbose-internals`,
which generally enables printing more info that could be useful for debugging.

Right below you can find elaborate explainers on a selected few.

### Getting a backtrace for errors
[getting-a-backtrace-for-errors]: #getting-a-backtrace-for-errors

If you want to get a backtrace to the point where the compiler emits an error message,
you can pass the `-Z treat-err-as-bug=n`, which will make the compiler panic on the `nth` error.
If you leave off `=n`,
the compiler will assume `1` for `n` and thus panic on the first error it encounters.

For example:

```bash
$ cat error.rs
```

```rust
fn main() {
    1 + ();
}
```

```
$ rustc +stage1 error.rs
error[E0277]: cannot add `()` to `{integer}`
 --> error.rs:2:7
  |
2 |       1 + ();
  |         ^ no implementation for `{integer} + ()`
  |
  = help: the trait `Add<()>` is not implemented for `{integer}`

error: aborting due to previous error
```

Now, where does the error above come from?

```
/* Detailed source-code truncated for AI context efficiency. */
```

Cool, now I have a backtrace for the error!

### Debugging delayed bugs

The `-Z eagerly-emit-delayed-bugs` option makes it easy to debug delayed bugs.
It turns them into normal errors, i.e. makes them visible. This can be used in
combination with `-Z treat-err-as-bug` to stop at a particular delayed bug and get a backtrace.

### Getting the error creation location

`-Z track-diagnostics` can help figure out where errors are emitted.
It uses `#[track_caller]` for this and prints its location alongside the error:

```
$ RUST_BACKTRACE=1 rustc +stage1 error.rs -Z track-diagnostics
error[E0277]: cannot add `()` to `{integer}`
 --> src\error.rs:2:7
  |
2 |     1 + ();
  |       ^ no implementation for `{integer} + ()`
-Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs:638:39
  |
  = help: the trait `Add<()>` is not implemented for `{integer}`
  = help: the following other types implement trait `Add<Rhs>`:
            <&'a f32 as Add<f32>>
            <&'a f64 as Add<f64>>
            <&'a i128 as Add<i128>>
            <&'a i16 as Add<i16>>
            <&'a i32 as Add<i32>>
            <&'a i64 as Add<i64>>
            <&'a i8 as Add<i8>>
            <&'a isize as Add<isize>>
          and 48 others

For more information about this error, try `rustc --explain E0277`.
```

This is similar but different to `-Z treat-err-as-bug`:
- it will print the locations for all errors emitted
- it does not require a compiler built with debug symbols
- you don't have to read through a big stack trace.

## Getting logging output

The compiler uses the [`tracing`] crate for logging.

[`tracing`]: https://docs.rs/tracing

For details, see [the chapter on tracing](./tracing.md).

## Narrowing (bisecting) regressions

The [cargo-bisect-rustc][bisect] tool can be used as a quick and easy way to
find exactly which PR caused a change in `rustc` behavior.
It automatically downloads `rustc` PR artifacts and tests them against a project you provide
until it finds the regression.
You can then look at the PR to get more context on *why* it was changed.
 See [this tutorial][bisect-tutorial] on how to use it.

[bisect]: https://github.com/rust-lang/cargo-bisect-rustc
[bisect-tutorial]: https://rust-lang.github.io/cargo-bisect-rustc/tutorial.html

## Downloading artifacts from Rust's CI

The [rustup-toolchain-install-master][rtim] tool by kennytm can be used to
download the artifacts produced by Rust's CI for a specific SHA1 -- this
basically corresponds to the successful landing of some PR -- and then sets
them up for your local use.
This also works for artifacts produced by `@bors try`.
This is helpful when you want to examine the resulting build of a PR
without doing the build yourself.

[rtim]: https://github.com/kennytm/rustup-toolchain-install-master

## `#[rustc_*]` TEST attributes

The compiler defines a whole lot of internal (perma-unstable) attributes some of which are useful
for debugging by dumping extra compiler-internal information.
These are prefixed with `rustc_` and
are gated behind the internal feature `rustc_attrs` (enabled via e.g. `#![feature(rustc_attrs)]`).

For a complete and up to date list, see [`builtin_attrs`].
More specifically, the ones marked `TEST`.
Here are some notable ones:

| Attribute | Description |
|----------------|-------------|
| `rustc_dump_def_parents` | Dumps the chain of `DefId` parents of certain definitions. |
| `rustc_dump_def_path` | Dumps the [`def_path_str`] of an item. |
| `rustc_dump_generics` | Dumps the generics of an item. |
| `rustc_dump_hidden_type_of_opaques` | Dumps the [hidden type of each opaque types][opaq] in the crate. |
| `rustc_dump_inferred_outlives` | Dumps implied bounds of an item. More precisely, the [`inferred_outlives_of`] an item. |
| `rustc_dump_item_bounds` | Dumps the [`item_bounds`] of an item. |
| `rustc_dump_layout` | [See this section](#debugging-type-layouts). |
| `rustc_dump_object_lifetime_defaults` | Dumps the [object lifetime defaults] of an item. |
| `rustc_dump_clauses` | Dumps the [`clauses_of`] an item. |
| `rustc_dump_symbol_name` | Dumps the mangled & demangled [`symbol_name`] of an item. |
| `rustc_dump_variances` | Dumps the [variances] of an item. |
| `rustc_dump_vtable` | Dumps the vtable layout of an impl, or a type alias of a dyn type. |
| `rustc_regions` | Dumps NLL closure region requirements. |

Right below you can find elaborate explainers on a selected few.

[`builtin_attrs`]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_feature/src/builtin_attrs.rs
[`def_path_str`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.def_path_str
[`inferred_outlives_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.inferred_outlives_of
[`item_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.item_bounds
[`clauses_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.clauses_of
[`symbol_name`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.symbol_name
[object lifetime defaults]: https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes
[opaq]: ./opaque-types-impl-trait-inference.md
[variances]: ./variance.md

### Formatting Graphviz output (.dot files)
[formatting-graphviz-output]: #formatting-graphviz-output

Some compiler options for debugging specific features yield graphviz graphs -
e.g. the `#[rustc_mir(borrowck_graphviz_postflow="suffix.dot")]` attribute
on a function dumps various borrow-checker dataflow graphs in conjunction with
`-Zdump-mir-dataflow`.

These all produce `.dot` files. To view these files, install graphviz (e.g.
`apt-get install graphviz`) and then run the following commands:

```bash
$ dot -T pdf maybe_init_suffix.dot > maybe_init_suffix.pdf
$ firefox maybe_init_suffix.pdf # Or your favorite pdf viewer
```

Graphviz also comes with a preprocessor program,
[`unflatten`](https://graphviz.org/docs/cli/unflatten/),
that sometimes helps making the outputs look less oddly spread out.
It reads a dot file and outputs another dot file, so you can use it in a pipe,
e.g:
```
$ unflatten mir_dump/*.foo.-------.nll.0.regioncx.all.dot | dot -Tpdf  -o foo-outlives.pdf
```

This is particularly useful for complicated region outlives graphs from 
[the borrow checker](borrow-check/debugging.md).

[An online Graphviz editor and visualiser is
also available](https://dreampuf.github.io/GraphvizOnline).


## Narrowing (Bisecting) Regressions

The internal attribute `#[rustc_dump_layout(...)]` can be used to dump the
[`Layout`] of the type it is attached to.
For example:

```rust
#![feature(rustc_attrs)]

#[rustc_dump_layout(debug)]
type T<'a> = &'a u32;
```

Will emit the following:

```text
error: layout_of(&u32) = Layout {
           size: Size(8 bytes),
           align: AbiAlign {
               abi: Align(8 bytes),
           },
           backend_repr: Scalar(
               Initialized {
                   value: Pointer(
                       AddressSpace(
                           0,
                       ),
                   ),
                   valid_range: 1..=18446744073709551615,
               },
           ),
           fields: Primitive,
           largest_niche: Some(
               Niche {
                   offset: Size(0 bytes),
                   value: Pointer(
                       AddressSpace(
                           0,
                       ),
                   ),
                   valid_range: 1..=18446744073709551615,
               },
           ),
           uninhabited: false,
           variants: Single {
               index: 0,
           },
           max_repr_align: None,
           unadjusted_abi_align: Align(8 bytes),
           randomization_seed: 281492156579847,
       }
 --> src/lib.rs:4:1
  |
4 | type T<'a> = &'a u32;
  | ^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error
```

[`Layout`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_public/abi/struct.Layout.html

## Debugging borrowcheck

Debugging the borrow checker has [its own chapter](borrow-check/debugging.md).

## Configuring CodeLLDB for debugging `rustc`

If you are using VSCode, and have edited your `bootstrap.toml` to request debugging
level 1 or 2 for the parts of the code you're interested in,
then you should be able to use the [CodeLLDB] extension in VSCode to debug it.

Here is a sample `launch.json` file, being used to run a stage 1 compiler direct
from the directory where it is built (does not have to be "installed"):

```javascript
// .vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
      {
        "type": "lldb",
        "request": "launch",
        "name": "Launch",
        "args": [],  // array of string command-line arguments to pass to compiler
        "program": "${workspaceFolder}/build/host/stage1/bin/rustc",
        "windows": {  // applicable if using windows
            "program": "${workspaceFolder}/build/host/stage1/bin/rustc.exe"
        },
        "cwd": "${workspaceFolder}",  // current working directory at program start
        "stopOnEntry": false,
        "sourceLanguages": ["rust"]
      }
    ]
  }
```

[CodeLLDB]: https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb

---

### Src Doc Rustc Dev Guide Src Compiler Src (`src/doc/rustc-dev-guide/src/compiler-src.md`)

# High-level overview of the compiler source

Now that we have [seen what the compiler does][orgch],
let's take a look at the structure of the [`rust-lang/rust`] repository,
where the rustc source code lives.

[`rust-lang/rust`]: https://github.com/rust-lang/rust

> You may find it helpful to read the ["Overview of the compiler"][orgch]
> chapter, which introduces how the compiler works, before this one.

[orgch]: ./overview.md

## Workspace structure

The [`rust-lang/rust`] repository consists of a single large cargo workspace
containing the compiler, the standard libraries ([`core`], [`alloc`], [`std`],
[`proc_macro`], [`etc`]), and [`rustdoc`], along with the build system and a
bunch of tools and submodules for building a full Rust distribution.

The repository consists of three main directories:

- [`compiler/`] contains the source code for `rustc`. It consists of many crates
  that together make up the compiler.
  
- [`library/`] contains the standard libraries ([`core`], [`alloc`], [`std`],
  [`proc_macro`], [`test`]), as well as the Rust runtime ([`backtrace`], [`rtstartup`],
  [`lang_start`]).
  
- [`tests/`] contains the compiler tests.
  
- [`src/`] contains the source code for [`rustdoc`], [`clippy`], [`cargo`], the build system,
  language docs, etc.

[`alloc`]: https://github.com/rust-lang/rust/tree/HEAD/library/alloc
[`backtrace`]: https://github.com/rust-lang/backtrace-rs/
[`cargo`]: https://github.com/rust-lang/cargo
[`clippy`]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/clippy
[`compiler/`]: https://github.com/rust-lang/rust/tree/HEAD/compiler
[`core`]: https://github.com/rust-lang/rust/tree/HEAD/library/core
[`etc`]: https://github.com/rust-lang/rust/tree/HEAD/src/etc
[`lang_start`]: https://github.com/rust-lang/rust/blob/HEAD/library/std/src/rt.rs
[`library/`]: https://github.com/rust-lang/rust/tree/HEAD/library
[`proc_macro`]: https://github.com/rust-lang/rust/tree/HEAD/library/proc_macro
[`rtstartup`]: https://github.com/rust-lang/rust/tree/HEAD/library/rtstartup
[`rust-lang/rust`]: https://github.com/rust-lang/rust
[`rustdoc`]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/rustdoc
[`src/`]: https://github.com/rust-lang/rust/tree/HEAD/src
[`std`]: https://github.com/rust-lang/rust/tree/HEAD/library/std
[`test`]: https://github.com/rust-lang/rust/tree/HEAD/library/test
[`tests/`]: https://github.com/rust-lang/rust/tree/HEAD/tests

## Compiler

The compiler is implemented in the various [`compiler/`] crates.
The [`compiler/`] crates all have names starting with `rustc_*`. These are a
collection of around 50 interdependent crates ranging in size from tiny to
huge. There is also the `rustc` crate which is the actual binary (i.e. the
`main` function); it doesn't actually do anything besides calling the
[`rustc_driver`] crate, which drives the various parts of compilation in other
crates.

The dependency order of these crates is complex, but roughly it is
something like this:

1. `rustc` (the binary) calls [`rustc_driver::main`][main].
1. [`rustc_driver`] depends on a lot of other crates, but the main one is
   [`rustc_interface`].
1. [`rustc_interface`] depends on most of the other compiler crates. It is a
   fairly generic interface for driving the whole compilation.
1. Most of the other `rustc_*` crates depend on [`rustc_middle`], which defines
   a lot of central data structures in the compiler.
1. [`rustc_middle`] and most of the other crates depend on a handful of crates
   representing the early parts of the compiler (e.g. the parser), fundamental
   data structures (e.g. [`Span`]), or error reporting:
   [`rustc_data_structures`], [`rustc_span`], [`rustc_errors`], etc.

[`rustc_data_structures`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/index.html
[`rustc_driver`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/index.html
[`rustc_errors`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html
[`rustc_interface`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/index.html
[`rustc_middle`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/index.html
[`rustc_span`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/index.html
[`Span`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html
[main]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/fn.main.html

You can see the exact dependencies by running `cargo tree`,
just like you would for any other Rust package:

```console
cargo tree --package rustc_driver
```

One final thing: [`src/llvm-project`] is a submodule for our fork of LLVM.
During bootstrapping, LLVM is built and the [`compiler/rustc_llvm`] crate
contains Rust wrappers around LLVM (which is written in C++), so that the
compiler can interface with it.

Most of this book is about the compiler, so we won't have any further
explanation of these crates here.

[`compiler/rustc_llvm`]: https://github.com/rust-lang/rust/tree/HEAD/compiler/rustc_llvm
[`src/llvm-project`]: https://github.com/rust-lang/rust/tree/HEAD/src/
[`Cargo.toml`]: https://github.com/rust-lang/rust/blob/HEAD/Cargo.toml

### Big picture

The dependency structure of the compiler is influenced by two main factors:

1. Organization. The compiler is a _huge_ codebase; it would be an impossibly
   large crate. In part, the dependency structure reflects the code structure
   of the compiler.
2. Compile-time. By breaking the compiler into multiple crates, we can take
   better advantage of incremental/parallel compilation using cargo. In
   particular, we try to have as few dependencies between crates as possible so
   that we don't have to rebuild as many crates if you change one.

At the very bottom of the dependency tree are a handful of crates that are used
by the whole compiler (e.g. [`rustc_span`]). The very early parts of the
compilation process (e.g. [parsing and the Abstract Syntax Tree (`AST`)][parser]) 
depend on only these.

After the [`AST`][parser] is constructed and other early analysis is done, the
compiler's [query system][query] gets set up. The query system is set up in a
clever way using function pointers. This allows us to break dependencies
between crates, allowing more parallel compilation. The query system is defined
in [`rustc_middle`], so nearly all subsequent parts of the compiler depend on
this crate. It is a really large crate, leading to long compile times. Some
efforts have been made to move stuff out of it with varying success. Another
side-effect is that sometimes related functionality gets scattered across
different crates. For example, linting functionality is found across earlier
parts of the crate, [`rustc_lint`], [`rustc_middle`], and other places.

Ideally there would be fewer, more cohesive crates, with incremental and
parallel compilation making sure compile times stay reasonable. However,
incremental and parallel compilation haven't gotten good enough for that yet,
so breaking things into separate crates has been our solution so far.

At the top of the dependency tree is [`rustc_driver`] and [`rustc_interface`]
which is an unstable wrapper around the query system helping drive various
stages of compilation. Other consumers of the compiler may use this interface
in different ways (e.g. [`rustdoc`] or maybe eventually `rust-analyzer`). The
[`rustc_driver`] crate first parses command line arguments and then uses
[`rustc_interface`] to drive the compilation to completion.

[parser]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
[`rustc_lint`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/index.html
[query]: ./query.md

## rustdoc

The bulk of [`rustdoc`] is in [`librustdoc`]. However, the [`rustdoc`] binary
itself is [`src/tools/rustdoc`], which does nothing except call [`rustdoc::main`].

There is also `JavaScript` and `CSS` for the docs in [`src/tools/rustdoc-js`]
and [`src/tools/rustdoc-themes`]. The type definitions for `--output-format=json`
are in a separate crate in [`src/rustdoc-json-types`].

You can read more about [`rustdoc`] in [this chapter][rustdoc-chapter].

[`librustdoc`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc/index.html
[`rustdoc::main`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc/fn.main.html
[`src/tools/rustdoc-js`]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/rustdoc-js
[`src/tools/rustdoc-themes`]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/rustdoc-themes
[`src/tools/rustdoc`]:  https://github.com/rust-lang/rust/tree/HEAD/src/tools/rustdoc
[`src/rustdoc-json-types`]: https://github.com/rust-lang/rust/tree/HEAD/src/rustdoc-json-types
[rustdoc-chapter]: ./rustdoc.md

## Tests

The test suite for all of the above is in [`tests/`]. You can read more
about the test suite [in this chapter][testsch].

The test harness is in [`src/tools/compiletest/`][`compiletest/`].

[`tests/`]: https://github.com/rust-lang/rust/tree/HEAD/tests
[testsch]: ./tests/intro.md

## Build System

There are a number of tools in the repository just for building the compiler,
standard library, [`rustdoc`], etc, along with testing, building a full Rust
distribution, etc.

One of the primary tools is [`src/bootstrap/`]. You can read more about
bootstrapping [in this chapter][bootstch]. The process may also use other tools
from [`src/tools/`], such as [`tidy/`] or [`compiletest/`].

[`compiletest/`]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/compiletest
[`src/bootstrap/`]: https://github.com/rust-lang/rust/tree/HEAD/src/bootstrap
[`src/tools/`]: https://github.com/rust-lang/rust/tree/HEAD/src/tools
[`tidy/`]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/tidy
[bootstch]: ./building/bootstrapping/intro.md

## Standard library

This code is fairly similar to most other Rust crates except that it must be
built in a special way because it can use unstable ([`nightly`]) features.
The standard library is sometimes referred to as [`libstd or the "standard facade"`].

[`libstd or the "standard facade"`]: https://rust-lang.github.io/rfcs/0040-libstd-facade.html
[`nightly`]: https://doc.rust-lang.org/nightly/nightly-rustc/

## Other

There are a lot of other things in the `rust-lang/rust` repo that are related
to building a full Rust distribution. Most of the time you don't need to worry about them.

These include:
- [`src/ci`]: The CI configuration. This actually quite extensive because we
  run a lot of tests on a lot of platforms.
- [`src/doc`]: Various documentation, including submodules for a few books.
- [`src/etc`]: Miscellaneous utilities.
- And more...

[`src/ci`]: https://github.com/rust-lang/rust/tree/HEAD/src/ci
[`src/doc`]: https://github.com/rust-lang/rust/tree/HEAD/src/doc
[`src/etc`]: https://github.com/rust-lang/rust/tree/HEAD/src/etc

---

### Src Doc Rustc Dev Guide Src Compiler Team (`src/doc/rustc-dev-guide/src/compiler-team.md`)

# About the compiler team

> NOTE:
> There exists much detail about the team [on Forge], making most of the following obsolete.

rustc is maintained by the [Rust compiler team][team].
The people who belong to
this team collectively work to track regressions and implement new features.
Members of the Rust compiler team are people who have made significant
contributions to rustc and its design.

[on Forge]: https://forge.rust-lang.org/compiler
[team]: https://www.rust-lang.org/governance/teams/compiler

## Discussion

Currently the compiler team chats in Zulip:

- Team chat occurs in the [`t-compiler`][zulip-t-compiler] stream on the Zulip instance
- There are also a number of other associated Zulip channels,
  such as [`t-compiler/help`][zulip-help], where people can ask for help
  with rustc development, or [`t-compiler/meetings`][zulip-meetings],
  where the team holds their weekly triage and steering meetings.

## Reviewers

If you're interested in figuring out who can answer questions about a
particular part of the compiler, or you'd just like to know who works on what,
check out [triagebot.toml's assign section][map].
It contains a listing of the various parts of the compiler and a list of people
who are reviewers of each part.

[map]: https://github.com/rust-lang/rust/blob/HEAD/triagebot.toml

## Rust compiler meeting

The compiler team has a weekly meeting where we do triage and try to
generally stay on top of new bugs, regressions, and discuss important things in general.
They are held on [Zulip][zulip-meetings].
It works roughly as follows:

- **Announcements, MCPs/FCPs, and WG-check-ins:** We share some
  announcements with the rest of the team about important things we want everyone to be aware of.
  We also share the status of MCPs and FCPs and we
  use the opportunity to have a couple of WGs giving us an update about their work.
- **Check for beta and stable nominations:** These are nominations of things to
  backport to beta and stable respectively.
  We then look for new cases where the compiler broke previously working code in the wild.
  Regressions are important issues to fix, so it's
  likely that they are tagged as P-critical or P-high; the major
  exception would be bug fixes (though even there we often [aim to give
  warnings first][procedure]).
- **Review P-critical and P-high bugs:** P-critical and P-high bugs are
  those that are sufficiently important for us to actively track progress.
  P-critical and P-high bugs should ideally always have an assignee.
- **Check `S-waiting-on-t-compiler` and `I-compiler-nominated` issues:** These are issues where
  feedback from the team is desired.
- **Look over the performance triage report:** We check for PRs that made the
    performance worse and try to decide if it's worth reverting the performance regression or if
    the regression can be addressed in a future PR.

The meeting currently takes place on Thursdays at 10am Boston time
(UTC-4 typically, but daylight savings time sometimes makes things complicated).

[procedure]: ./bug-fix-procedure.md
[zulip-t-compiler]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler
[zulip-help]: https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp
[zulip-meetings]: https://rust-lang.zulipchat.com/#narrow/stream/238009-t-compiler.2Fmeetings

## Team membership

Membership in the Rust team is typically offered when someone has been
making significant contributions to the compiler for some time.
Membership is both a recognition but also an obligation:
compiler team members are generally expected to help with upkeep as
well as doing reviews and other work.

If you are interested in becoming a compiler team member, the first
thing to do is to start fixing some bugs, or get involved in a working group.
One good way to find bugs is to look for
[open issues tagged with E-easy](https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy)
or [E-mentor](https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AE-mentor).

You can also dig through the graveyard of PRs that were
[closed due to inactivity](https://github.com/rust-lang/rust/pulls?q=is%3Apr+label%3AS-inactive),
some of them may contain work that is still useful - refer to the
associated issues, if any - and only needs some finishing touches
for which the original author didn't have time.

### r+ rights

Once you have made a number of individual PRs to rustc, we will often offer r+ privileges.
This means that you have the right to instruct
"bors" (the robot that manages which PRs get landed into rustc) to merge a PR
([here are some instructions for how to talk to bors][bors-guide]).

[bors-guide]: https://bors.rust-lang.org/

The guidelines for reviewers are as follows:

- You are always welcome to review any PR, regardless of who it is assigned to.
  However, do not r+ PRs unless:
  - You are confident in that part of the code.
  - You are confident that nobody else wants to review it first.
    - For example, sometimes people will express a desire to review a
      PR before it lands, perhaps because it touches a particularly
      sensitive part of the code.
- Always be polite when reviewing: you are a representative of the
  Rust project, so it is expected that you will go above and beyond
  when it comes to the [Code of Conduct].

[Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct

### Reviewer rotation

Once you have r+ rights, you can also be added to the [reviewer rotation].
[triagebot] is the bot that [automatically assigns] incoming PRs to reviewers.
If you are added, you will be randomly selected to review PRs.
If you find you are assigned a PR that you don't feel comfortable
reviewing, you can also leave a comment like `r? @so-and-so` to assign
to someone else — if you don't know who to request, just write `r?
@nikomatsakis for reassignment` and @nikomatsakis will pick someone for you.

[reviewer rotation]: https://github.com/rust-lang/rust/blob/36285c5de8915ecc00d91ae0baa79a87ed5858d5/triagebot.toml#L528-L577
[triagebot]: https://github.com/rust-lang/triagebot/
[automatically assigns]: https://forge.rust-lang.org/triagebot/pr-assignment.html

Getting on the reviewer rotation is much appreciated as it lowers the review burden for all of us!
However, if you don't have time to give
people timely feedback on their PRs, it may be better that you don't get on the list.

---

### Src Doc Rustc Dev Guide Src Const Eval (`src/doc/rustc-dev-guide/src/const-eval.md`)

# Constant Evaluation

Constant evaluation is the process of computing values at compile time.
For a specific item (constant/static/array length) this happens after the MIR for the
item is borrow-checked and optimized.
In many cases trying to const evaluate an
item will trigger the computation of its MIR for the first time.

Prominent examples are:

* The initializer of a `static`
* Array length
    * needs to be known to reserve stack or heap space
* Enum variant discriminants
    * needs to be known to prevent two variants from having the same discriminant
* Patterns
    * need to be known to check for overlapping patterns

Additionally constant evaluation can be used to reduce the workload or binary
size at runtime by precomputing complex operations at compile time and only storing the result.

All uses of constant evaluation can either be categorized as "influencing the type system"
(array lengths, enum variant discriminants, const generic parameters), or as solely being
done to precompute expressions to be used at runtime.

Constant evaluation can be done by calling the `const_eval_*` functions of `TyCtxt`.
They're the wrappers of the `const_eval` query.

* `const_eval_global_id_for_typeck` evaluates a constant to a valtree,
  so the result value can be further inspected by the compiler.
* `const_eval_global_id` evaluate a constant to an "opaque blob" containing its final value;
  this is only useful for codegen backends and the CTFE evaluator engine itself.
* `eval_static_initializer` specifically computes the initial values of a static.
  Statics are special; all other functions do not represent statics correctly
  and have thus assertions preventing their use on statics.

The `const_eval_*` functions use a [`ParamEnv`](./typing-parameter-envs.md) of environment
in which the constant is evaluated (e.g. the function within which the constant is used)
and a [`GlobalId`].
The `GlobalId` is made up of an `Instance` referring to a constant
or static or of an `Instance` of a function and an index into the function's `Promoted` table.

Constant evaluation returns an [`EvalToValTreeResult`] for type system constants
or [`EvalToConstValueResult`] with either the error, or a representation of the
evaluated constant: a [valtree](mir/index.md#valtrees) or a [MIR constant
value](mir/index.md#mir-constant-values), respectively.

[`GlobalId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/struct.GlobalId.html
[`EvalToConstValueResult`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/error/type.EvalToConstValueResult.html
[`EvalToValTreeResult`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/error/type.EvalToValTreeResult.html

---

### Src Doc Rustc Dev Guide Src Const Generics (`src/doc/rustc-dev-guide/src/const-generics.md`)

# Const generics

## Kinds of const arguments

Most of the kinds of `ty::Const` that exist have direct parallels to kinds of types that exist, for example `ConstKind::Param` is equivalent to `TyKind::Param`.

The main interesting points here are:
- [`ConstKind::Alias`], which is equivalent to `TyKind::Alias`.
- [`ConstKind::Value`], which is the final value of a `ty::Const` after monomorphization.
  This is somewhat similar to fully concrete things like `TyKind::Str` or `TyKind::ADT`.

For a complete list of *all* kinds of const arguments and how they are actually represented in the type system, see the [`ConstKind`] type.

Inference Variables are quite boring and treated equivalently to type inference variables almost everywhere.
Const Parameters are also similarly boring and equivalent to uses of type parameters almost everywhere.
However, there are some interesting subtleties with how they are handled during parsing, name resolution, and AST lowering: [ambig-unambig-ty-and-consts].

## Anon consts

Anon consts (short for anonymous const items) are how arbitrary expression are represented in const generics, for example an array length of `1 + 1` or `foo()` or even just `0`.
These are unique to const generics and have no real type equivalent.

### Desugaring

```rust
struct Foo<const N: usize>;
type Alias = [u8; 1 + 1];
```

In this example we have a const argument of `1 + 1` (the array length) which is represented as an *anon const*.
The desugaring would look something like:
```rust
struct Foo<const N: usize>;

const ANON: usize = 1 + 1;
type Alias = [u8; ANON];
```

Where the array length in `[u8; ANON]` isn't itself an anon const containing a usage of `ANON`, but a kind of "direct" usage of the `ANON` const item ([`ConstKind::Alias`]).

Anon consts do not inherit any generic parameters of the item they are inside of:
```rust
struct Foo<const N: usize>;
type Alias<T: Sized> = [T; 1 + 1];

// Desugars To;

struct Foo<const N: usize>;

const ANON: usize = 1 + 1;
type Alias<T: Sized> = [T; ANON];
```

Note how the `ANON` const has no generic parameters or where clauses, even though `Alias` has both a type parameter `T` and a where clauses `T: Sized`.
This desugaring is part of how we enforce that anon consts can't make use of generic parameters.

While it's useful to think of anon consts as being desugared to real const items, the compiler does not actually implement things this way.

At AST lowering time we do not yet know the *type* of the anon const, so we can't desugar to a real HIR item with an explicitly written type.
To work around this, we have [`DefKind::AnonConst`] and [`hir::Node::AnonConst`],
which are used to represent these anonymous const items that can't actually be desugared.

The types of these anon consts are obtainable from the [`type_of`] query.
However, the `type_of` query does not actually contain logic for computing the type (and, in fact, it just ICEs when called).
Instead, HIR Ty lowering is responsible for *feeding* the value of the `type_of` query for any anon consts that get lowered.
HIR Ty lowering can determine the type of the anon const by looking at the type of the Const Parameter that the anon const is an argument to.

TODO: write a chapter on query feeding and link it here

In some sense the desugarings from the previous examples are to:
```rust
struct Foo<const N: usize>;
type Alias = [u8; 1 + 1];

// sort-of desugars to pseudo-rust:
struct Foo<const N: usize>;

const ANON = 1 + 1;
type Alias = [u8; ANON];
```

When we go through HIR ty lowering for the array type in `Alias`, we will lower the array length too, and feed `type_of(ANON) -> usize`.
This will effectively set the type of the `ANON` const item during some later part of the compiler rather than when constructing the HIR.

After all of this desugaring has taken place the final representation in the type system (ie as a `ty::Const`) is a `ConstKind::Alias` with the `DefId` of the `AnonConst`.
This is equivalent to how we would represent a usage of an actual const item if we were to represent them without going through an anon const (e.g. when `gca_generic_const_args` is enabled).

This allows the representation for const "aliases" to be the same as the representation of `TyKind::Alias`.
Having a proper HIR body also allows for a *lot* of code re-use, e.g. we can reuse HIR typechecking and all of the lowering steps to MIR where we can then reuse const eval.

### Enforcing lack of generic parameters

There are three ways that we enforce anon consts can't use generic parameters:
1. Name Resolution will not resolve paths to generic parameters when inside of an anon const
2. HIR Ty lowering will error when a `Self` type alias to a type referencing generic parameters is encountered inside of an anon const
3. Anon Consts do not inherit where clauses or generics from their parent definition (ie [`generics_of`] does not contain a parent for anon consts)

```rust
// *1* Errors in name resolution
type Alias<const N: usize> = [u8; N + 1];
//~^ ERROR: generic parameters may not be used in const operations

// *2* Errors in HIR Ty lowering:
struct Foo<T>(T);
impl<T> Foo<T> {
    fn assoc() -> [u8; { let a: Self; 0 }] {}
    //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants
}

// *3* Errors due to lack of where clauses on the desugared anon const
trait Trait<T> {
    const ASSOC: usize;
}
fn foo<T>() -> [u8; <()>::ASSOC]
//~^ ERROR: no associated item named `ASSOC` found for unit type `()`
where
    (): Trait<T> {}
```

The second point is particularly subtle as it is very easy to get HIR Ty lowering wrong and not properly enforce that anon consts can't use generic parameters.
The existing check is too conservative and accidentally permits some generic parameters to wind up in the body of the anon const [#144547](https://github.com/rust-lang/rust/issues/144547).

Erroneously allowing generic parameters in anon consts can sometimes lead to ICEs but can also lead to accepting illformed programs.

The third point is also somewhat subtle, by not inheriting any of the where clauses of the parent item we can't wind up with the trait solving inferring inference variables to generic parameters based off where clauses in scope that mention generic parameters.
For example, inferring `?x=T` from the expression `<() as Trait<?x>>::ASSOC` and an in-scope where clause of `(): Trait<T>`.

This also makes it much more likely that the compiler will ICE or atleast incidentally emit some kind of error if we *do* accidentally allow generic parameters in an anon const, as the anon const will have none of the necessary information in its environment to properly handle the generic parameters.

#### Array repeat expressions
The one exception to all of the above is repeat counts of array expressions.
As a *backwards compatibility hack*, we allow the repeat count const argument to use generic parameters.

```rust
fn foo<T: Sized>() {
    let a = [1_u8; size_of::<T>()];
}
```

However, to avoid most of the problems involved in allowing generic parameters in anon const const arguments,
we require that the constant be evaluated before monomorphization (e.g. during type checking).
In some sense we only allow generic parameters here when they are semantically unused.

In the previous example the anon const can be evaluated for any type parameter `T` because raw pointers to sized types always have the same size (e.g. `8` on 64bit platforms).

When detecting that we evaluated an anon const that syntactically contained generic parameters, but did not actually depend on them for evaluation to succeed, we emit the [`const_evaluatable_unchecked` FCW][cec_fcw].
This is intended to become a hard error once we stabilize more ways of using generic parameters in const arguments, for example `gca_min_const_items` or (the now dead) `generic_const_exprs`.

The implementation for this FCW can be found here: [`const_eval_resolve_for_typeck`]

### Incompatibilities with `generic_const_parameter_types`

Supporting const parameters such as `const N: [u8; M]` or `const N: Foo<T>` does not work very nicely with the current anon consts setup.
There are two reasons for this:
1. As anon consts cannot use generic parameters, their type *also* can't reference generic parameters.
   This means it is fundamentally not possible to use an anon const as an argument to a const parameter whose type still references generic parameters.

    ```rust
    #![feature(adt_const_params, generic_const_parameter_types)]

    fn foo<const N: usize, const M: [u8; N]>() {}

    fn bar<const N: usize>() {
        // There is no way to specify the const argument to `M`
        foo::<N, { [1_u8; N] }>();
    }
    ```

2. We currently require knowing the type of anon consts when lowering them during HIR ty lowering.
   With generic const parameter types it may be the case that the currently known type contains inference variables (ie may not be fully known yet).

    ```rust
    #![feature(adt_const_params, generic_const_parameter_types)]

    fn foo<const N: usize, const M: [u8; N]>() {}

    fn bar() {
        // The const argument to `N` must be explicitly specified
        // even though it is able to be inferred
        foo::<_, { [1_u8; 3] }>();
    }
    ```

It is currently unclear what the right way to make `generic_const_parameter_types` work nicely with the rest of const generics is.

`generic_const_exprs` would have allowed for anon consts with types referencing generic parameters, but that design wound up unworkable.

`gca_min_const_items` will allow for some expressions (for example array construction) to be representable without an anon const and therefore without running into these issues, though whether this is *enough* has yet to be determined.

## Checking types of const arguments

In order for a const argument to be well formed it must have the same type as the const parameter it is an argument to.
For example, a const argument of type `bool` for an array length is not well formed, as an array's length parameter has type `usize`.

```rust
type Alias<const B: bool> = [u8; B];
//~^ ERROR:
```

To check this, we have [`ClauseKind::ConstArgHasType(ty::Const, Ty)`][const_arg_has_type], where,
for each Const Parameter defined on an item,
we also desugar an equivalent `ConstArgHasType` clause into its list of where cluases.
This ensures that whenever we check wellformedness of anything by proving all of its clauses,
we also check happen to check that all of the Const Arguments have the correct type.

```rust
fn foo<const N: usize>() {}

// desugars to in pseudo-rust

fn foo<const N>()
where
//  ConstArgHasType(N, usize)
    N: usize, {}
```

Proving `ConstArgHasType` goals is implemented by first computing the type of the const argument, then equating it with the provided type.
A rough outline of how the type of a Const Argument may be computed:
- [`ConstKind::Param(N)`][`ConstKind::Param`] can be looked up in the [`ParamEnv`] to find a `ConstArgHasType(N, ty)` clause
- [`ConstKind::Value`] stores the type of the value inside itself so can trivially be accessed
- [`ConstKind::Alias`] can have its type computed by calling the `type_of` query
- See the implementation of proving `ConstArgHasType` goals for more detailed information

`ConstArgHasType` is *the* soundness critical way that we check Const Arguments have the correct type.
However, we do *indirectly* check the types of Const Arguments a different way in some cases.

```rust
type Alias = [u8; true];

// desugars to

const ANON: usize = true;
type Alias = [u8; ANON];
```

By feeding the type of an anon const with the type of the Const Parameter,
we guarantee that the `ConstArgHasType` goal involving the anon const will succeed.
In cases where the type of the anon const doesn't match the type of the Const Parameter,
what actually happens is a *type checking* error when type checking the anon const's body.

Looking at the above example, this corresponds to `[u8; ANON]` being a well formed type because `ANON` has type `usize`, but the *body* of `ANON` being illformed and resulting in a type checking error because `true` can't be returned from a const item of type `usize`.

[ambig-unambig-ty-and-consts]: ./ambig-unambig-ty-and-consts.md
[`ConstKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/consts/type.ConstKind.html
[`ConstKind::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/consts/type.ConstKind.html#variant.Infer
[`ConstKind::Param`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/consts/type.ConstKind.html#variant.Param
[`ConstKind::Alias`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/consts/type.ConstKind.html#variant.Alias
[`ConstKind::Value`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/consts/type.ConstKind.html#variant.Value
[const_arg_has_type]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ClauseKind.html#variant.ConstArgHasType
[`ParamEnv`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html
[`generics_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#impl-TyCtxt%3C'tcx%3E/method.generics_of
[`type_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.type_of
[`DefKind::AnonConst`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def/enum.DefKind.html#variant.AnonConst
[`hir::Node::AnonConst`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html#variant.AnonConst#
[cec_fcw]: https://github.com/rust-lang/rust/issues/76200
[`const_eval_resolve_for_typeck`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.const_eval_resolve_for_typeck

---

### Src Doc Rustc Dev Guide Src Contributing To Guide (`src/doc/rustc-dev-guide/src/contributing-to-guide.md`)

# Writing rustc-dev-guide documentation

Contributions to the [rustc-dev-guide] are always welcome, and can be made directly at
[the rust-lang/rustc-dev-guide repo][rdgrepo].
The issue tracker in that repo is also a great way to find things that need doing.
There are issues for beginners and advanced compiler devs alike!

Just a few things to keep in mind:

[rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle

- When writing about a particular part of the compiler's code, we
  recommend that you link to the relevant parts of the [rustc API docs].

- Use sentence case for chapter and section titles.

- Use dashes (`-`) to separate words in file names.

- Links within the guide should use `.md` relative links, not `.html` links.
  CI will enforce this.

- Please try to avoid overly long lines and use semantic line breaks (where you break the line after each sentence).
  This makes it easier to review diffs, since they avoid reflowing other unrelated prose.
  There is no strict limit on line lengths;
  let the sentence or part of the sentence flow to its proper end on the same line.

  You can use a tool in ci/sembr to help with this.
  Its help output can be seen with this command:

  ```console
  cargo run --manifest-path ci/sembr/Cargo.toml -- --help
  ```

- When contributing text to the guide, please contextualize the information with some time period
  and/or a reason so that the reader knows how much to trust the information.
  Aim to provide a reasonable amount of context, and consider including:

  - A reason for why the text may be out of date other than "change",
    as change is a constant across the project.

  - The date the comment was added, e.g. instead of writing _"Currently, ..."_
    or _"As of now, ..."_, consider adding the date, in one of the following formats:
    - Jan 2021
    - January 2021
    - jan 2021
    - january 2021

    There is a CI action (in `.github/workflows/date-check.yml`)
    that generates a monthly report showing those that are over 6 months old
    ([example](https://github.com/rust-lang/rustc-dev-guide/issues/2052)).

    For the action to pick the date, add a special annotation before specifying the date:

    ```md
     Jul 2026
    ```

    Example:

    ```md
    As of  Jul 2026, the foo did the bar.
    ```

    For cases where the date should not be part of the visible rendered output,
    use the following instead:

    ```md
    
    ```

  - A link to a relevant WG, tracking issue, `rustc` rustdoc page, or similar, that may provide
    further explanation for the change process or a way to verify that the information is not
    outdated.

## ⚠️ Note: Where to contribute `rustc-dev-guide` changes

For detailed information about where to contribute rustc-dev-guide changes and the benefits of doing so,
see [the rustc-dev-guide team documentation].

[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/
[rdgrepo]: https://github.com/rust-lang/rustc-dev-guide
[the rustc-dev-guide team documentation]: https://forge.rust-lang.org/rustc-dev-guide/index.html#where-to-contribute-rustc-dev-guide-changes

---

### Src Doc Rustc Dev Guide Src Contributing (`src/doc/rustc-dev-guide/src/contributing.md`)

# Contribution procedures

## Bug reports

While bugs are unfortunate, they're a reality in software.
We can't fix what we don't know about, so please report liberally.
If you're not sure if something is a bug, feel free to open an issue anyway.

**If you believe reporting your bug publicly represents a security risk to Rust users,
please follow our [instructions for reporting security vulnerabilities][vuln]**.

[vuln]: https://www.rust-lang.org/policies/security

If you're using the nightly channel, please check if the bug exists in the
latest toolchain before filing your bug.
It might be fixed already.

If you have the chance, before reporting a bug, please [search existing issues],
as it's possible that someone else has already reported your error.
This doesn't always work, and sometimes it's hard to know what to search for, so consider this
extra credit.
We won't mind if you accidentally file a duplicate report.

Similarly, to help others who encountered the bug find your issue, consider
filing an issue with a descriptive title, which contains information that might be unique to it.
This can be the language or compiler feature used, the
conditions that trigger the bug, or part of the error message if there is any.
An example could be: **"impossible case reached" on lifetime inference for impl
Trait in return position**.

Opening an issue is as easy as following [this link][create an issue] and filling out the fields
in the appropriate provided template.

[search existing issues]: https://github.com/rust-lang/rust/issues?q=is%3Aissue
[create an issue]: https://github.com/rust-lang/rust/issues/new/choose

## Other procedures

Other contribution procedures are documented with the parts of the guide that own them:

<a id="bug-fixes-or-normal-code-changes"></a>
<a id="pull-requests"></a>

- For routine changes or large, cross-cutting pull requests, see [normal code changes](getting-started.md#bug-fixes-or-normal-code-changes), [PR lifecycle](./pr-lifecycle.md), and [pull request guidance](getting-started.md#pull-requests).

<a id="new-features"></a>
<a id="breaking-changes"></a>
<a id="major-changes"></a>

- For new features, major changes, and breaking changes, see [Implementing new language features](implementing-new-features.md) and [Procedures for breaking changes](bug-fix-procedure.md).

<a id="performance"></a>

- For performance-sensitive changes, see [Performance testing](tests/perf.md#performance-considerations).

<a id="writing-documentation"></a>

- For compiler documentation, see [Contributing documentation](building/compiler-documenting.md#contributing-documentation).

<a id="issue-triage"></a>

- For issue triage, see [Issue triage](getting-started.md#issue-triage).

<a id="llm-guidance"></a>

- For guidance on LLM usage, see [Running LLMs](llm-guidance.md).

<a id="contributing-to-rustc-dev-guide"></a>

- For changes to this guide itself, see [Writing rustc-dev-guide documentation](contributing-to-guide.md).

<a id="external-dependencies"></a>

- For external dependencies, see [Using external repositories](external-repos.md).

<a id="helpful-links-and-information"></a>

- For further resources, see [About this guide](about-this-guide.md#other-places-to-find-information).

---

### Src Doc Rustc Dev Guide Src Conventions (`src/doc/rustc-dev-guide/src/conventions.md`)

# Coding conventions

This chapter covers [formatting](#formatting), [coding for correctness](#cc),
[using crates from crates.io](#cio), and some tips on [structuring your PR for easy review](#er).

<a id="formatting"></a>

## Formatting and the tidy script

rustc is moving towards the [Rust standard coding style][fmt].

However, for now we don't use stable `rustfmt`; we use a pinned version with a
special config, so this may result in different style from normal [`rustfmt`].
Therefore, formatting this repository using `cargo fmt` is not recommended.

Instead, formatting should be done using `./x fmt`.
It's a good habit to run `./x fmt` before every commit, as this reduces conflicts later.

Formatting is checked by the `tidy` script.
It runs automatically when you do `./x test` and can be run in isolation with `./x fmt --check`.

> **Note: Formatting and test suites**
>
> Most Rust source files under `tests/` directory are not formatted for reasons
> such as whitespace sensitivity, nature of snapshot tests, location-sensitive
> comments and more.
>
> Consult the `ignore` entries in
> <https://github.com/rust-lang/rust/blob/main/rustfmt.toml> for which test
> files are not formatted.

If you want to use format-on-save in your editor, the pinned version of
`rustfmt` is built under `build/<target>/stage0/bin/rustfmt`.

[fmt]: https://github.com/rust-dev-tools/fmt-rfcs
[`rustfmt`]:https://github.com/rust-lang/rustfmt

### Formatting C++ code

The compiler contains some C++ code for interfacing with parts of LLVM that
don't have a stable C API.
When modifying that code, use this command to format it:

```console
./x test tidy --extra-checks cpp:fmt --bless
```

This uses a pinned version of `clang-format`, to avoid relying on the local environment.

### Formatting and linting Python code

The Rust repository contains quite a lot of Python code.
We try to keep it both linted and formatted by the [ruff] tool.

When modifying Python code, use this command to format it:

```console
./x test tidy --extra-checks py:fmt --bless
```

And, the following command to run lints:

```console
./x test tidy --extra-checks py:lint
```

These use a pinned version of `ruff`, to avoid relying on the local environment.

[ruff]: https://github.com/astral-sh/ruff

<a id="copyright"></a>



### Copyright notice


In the past, files began with a copyright and license notice.
Please **omit** this notice for new files licensed under the standard terms (MIT OR Apache-2.0).

All of the copyright notices should be gone by now, but if you come across one
in the rust-lang/rust repo, feel free to open a PR to remove it.

### Line length

Lines should be at most 100 characters.
It's even better if you can keep things to 80.

Sometimes, and particularly for tests, it can be necessary to exempt yourself from this limit.
In that case, you can add a comment towards the top of the file like so:

```rust
// ignore-tidy-linelength
```

### Tabs vs spaces

Prefer 4-space indents.

<a id="cc"></a>

## Coding for correctness

Beyond formatting, there are a few other tips that are worth following.

### Prefer exhaustive matches

Using `_` in a match is convenient, but it means that when new
variants are added to the enum, they may not get handled correctly.
Ask yourself: if a new variant were added to this enum, what's the
chance that it would want to use the `_` code, versus having some other treatment?
Unless the answer is "low", then prefer an exhaustive match.

The same advice applies to `if let` and `while let`,
which are effectively tests for a single variant.

### Use "TODO" comments for things you don't want to forget

As a useful tool to yourself, you can insert a `// TODO` comment
for something that you want to get back to before you land your PR:

```rust,ignore
fn do_something() {
    if something_else {
        unimplemented!(); // TODO write this
    }
}
```

The tidy script will report an error for a `// TODO` comment, so this
code would not be able to land until the TODO is fixed (or removed).

This can also be useful in a PR as a way to signal from one commit that you are
leaving a bug that a later commit will fix:

```rust,ignore
if foo {
    return true; // TODO wrong, but will be fixed in a later commit
}
```

If you want to leave a note in the codebase, use `// FIXME` instead.

### Follow the style of surrounding code

Use existing helpers and avoid duplicating logic or validation.

### [Avoid duplicated sources of truth](https://react.dev/learn/choosing-the-state-structure)

Trying to keep data in sync between two different places is a code smell.

### Use types to enforce invariants

When practical, [make invalid states unrepresentable](https://kentcdodds.com/blog/make-impossible-states-impossible), [not just checked at construction time](https://lexi-lambda.github.io/blog/2020/11/01/names-are-not-type-safety/).

### Write useful comments

[Write comments that say *why*][mit-comment-style] you have done a thing, not *what* you have done.
It's ok to go into detail about non-obvious bugs.

[mit-comment-style]: https://mitcommlab.mit.edu/broad/commkit/coding-and-comment-style/

### Preserve existing behavior

Consider platform differences and error cases.
Look for relevant tests that exercise the edge cases.

### Work in small steps

Work in small, independently testable steps.
Run the relevant tests after every meaningful change, so you know where you first went wrong.

<a id="cio"></a>

## Using crates from crates.io

See the [crates.io dependencies][crates] section.

<a id="er"></a>

## How to structure your PR

How you prepare the commits in your PR can make a big difference for the reviewer.
Here are some tips.

**Isolate "pure refactorings" into their own commit.** For example, if
you rename a method, then put that rename into its own commit, along
with the renames of all the uses.

**More commits is usually better.** If you are doing a large change,
it's almost always better to break it up into smaller steps that can be [independently understood][atomic commits].
The one thing to be aware of is that if
you introduce some code following one strategy, then change it
dramatically (versus adding to it) in a later commit, that 'back-and-forth' can be confusing.

[atomic commits]: https://github.blog/developer-skills/github/write-better-commits-build-better-projects/#%e2%9a%9b%ef%b8%8f-resize-and-stabilize-the-commits

**Format liberally.** While only the final commit of a PR must be correctly
formatted, it is both easier to review and less noisy to format each commit
individually using `./x fmt`.

**No merges.** We do not allow merge commits into our history, other than those by bors.
If you get a merge conflict, rebase instead via a
command like `git rebase --interactive rust-lang/main` (presuming you use the
name `rust-lang` for your remote).

**Individual commits do not have to build (but it's nice).** We do not
require that every intermediate commit successfully builds – we only
expect to be able to bisect at a PR level.
However, if you *can* make individual commits build, that is always helpful.

## Naming conventions

Apart from normal Rust style/naming conventions, there are also some specific to the compiler.

- `cx` tends to be short for "context" and is often used as a suffix.
  For example, `tcx` is a common name for the [Typing Context][tcx].

- [`'tcx`][tcx] is used as the lifetime name for the Typing Context.

- Because `crate` is a keyword, if you need a variable to represent something
  crate-related, often the spelling is changed to `krate`.

[tcx]: ./ty.md

[crates]: ./crates-io.md

---

### Src Doc Rustc Dev Guide Src Coroutine Closures (`src/doc/rustc-dev-guide/src/coroutine-closures.md`)

# Async closures/"coroutine-closures"

Please read [RFC 3668] to understand the general motivation of the feature.
This is a very technical and somewhat "vertical" chapter;
ideally, we'd split this and sprinkle it across all the relevant chapters,
but for the purposes of understanding async closures *holistically*,
I've put this together all here in one chapter.

## Coroutine-closures -- a technical deep dive

Coroutine-closures are a generalization of async closures, being special syntax for closure expressions which return a coroutine, notably one that is allowed to capture from the closure's upvars.

For now, the only usable kind of coroutine-closure is the async closure, and supporting async closures is the extent of this PR. We may eventually support `gen || {}`, etc., and most of the problems and curiosities described in this document apply to all coroutine-closures in general.

As a consequence of the code being somewhat general, this document may flip between calling them "async closures" and "coroutine-closures".
The future that is returned by the async closure will generally be called the "coroutine" or the "child coroutine".

### HIR

Async closures (and in the future, other coroutine flavors such as `gen`) are represented in HIR as a `hir::Closure`.
The closure-kind of the `hir::Closure` is `ClosureKind::CoroutineClosure(_)`[^k1], which wraps an async block, which is also represented in HIR as a `hir::Closure`.
The closure-kind of the async block is `ClosureKind::Closure(CoroutineKind::Desugared(_, CoroutineSource::Closure))`[^k2].

[^k1]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_ast_lowering/src/expr.rs#L1147>

[^k2]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_ast_lowering/src/expr.rs#L1117>

Like `async fn`, when lowering an async closure's body, we need to unconditionally move all of the closures arguments into the body so they are captured.
This is handled by `lower_coroutine_body_with_moved_arguments`[^l1].
The only notable quirk with this function is that the async block we end up generating as a capture kind of `CaptureBy::ByRef`[^l2].
We later force all of the *closure args* to be captured by-value[^l3], but we don't want the *whole* async block to act as if it were an `async move`, since that would defeat the purpose of the self-borrowing of an async closure.

[^l1]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_ast_lowering/src/item.rs#L1096-L1100>

[^l2]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_ast_lowering/src/item.rs#L1276-L1279>

[^l3]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_hir_typeck/src/upvar.rs#L250-L256>

### `rustc_middle::ty` representation

For the purposes of keeping the implementation mostly future-compatible (i.e. with gen `|| {}` and `async gen || {}`), most of this section calls async closures "coroutine-closures".

The main thing that this PR introduces is a new `TyKind` called `CoroutineClosure`[^t1] and corresponding variants on other relevant enums in typeck and borrowck (`UpvarArgs`, `DefiningTy`, `AggregateKind`).

[^t1]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_type_ir/src/ty_kind.rs#L163-L168>

We introduce a new `TyKind` instead of generalizing the existing `TyKind::Closure` due to major representational differences in the type.
The major differences between `CoroutineClosure`s can be explored by first inspecting the `CoroutineClosureArgsParts`, which is the "unpacked" representation of the coroutine-closure's generics.

#### Similarities to closures

Like a closure, we have `parent_args`, a `closure_kind_ty`, and a `tupled_upvars_ty`. These represent the same thing as their closure counterparts; namely: the generics inherited from the body that the closure is defined in, the maximum "calling capability" of the closure (i.e. must it be consumed to be called, like `FnOnce`, or can it be called by-ref), and the captured upvars of the closure itself.

#### The signature

A traditional closure has a `fn_sig_as_fn_ptr_ty` which it uses to represent the signature of the closure.
In contrast, we store the signature of a coroutine closure in a somewhat "exploded" way, since coroutine-closures have *two* signatures depending on what `AsyncFn*` trait you call it with (see below sections).

Conceptually, the coroutine-closure may be thought as containing several different signature types depending on whether it is being called by-ref or by-move.

To conveniently recreate both of these signatures, the `signature_parts_ty` stores all of the relevant parts of the coroutine returned by this coroutine-closure.
This signature parts type will have the general shape of `fn(tupled_inputs, resume_ty) -> (return_ty, yield_ty)`, where `resume_ty`, `return_ty`, and `yield_ty` are the respective types for the *coroutine* returned by the coroutine-closure[^c1].

[^c1]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_type_ir/src/ty_kind/closure.rs#L221-L229>

The compiler mainly deals with the `CoroutineClosureSignature` type[^c2], which is created by extracting the relevant types out of the `fn()` ptr type described above, and which exposes methods that can be used to construct the *coroutine* that the coroutine-closure ultimately returns.

[^c2]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_type_ir/src/ty_kind/closure.rs#L362>

#### The data we need to carry along to construct a `Coroutine` return type

Along with the data stored in the signature, to construct a `TyKind::Coroutine` to return, we also need to store the "witness" of the coroutine.

So what about the upvars of the `Coroutine` that is returned? Well, for `AsyncFnOnce` (i.e. call-by-move), this is simply the same upvars that the coroutine returns. But for `AsyncFnMut`/`AsyncFn`, the coroutine that is returned from the coroutine-closure borrows data from the coroutine-closure with a given "environment" lifetime[^c3]. This corresponds to the `&self` lifetime[^c4] on the `AsyncFnMut`/`AsyncFn` call signature, and the GAT lifetime of the `ByRef`[^c5].

[^c3]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_type_ir/src/ty_kind/closure.rs#L447-L455>

[^c4]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/library/core/src/ops/async_function.rs#L36>

[^c5]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/library/core/src/ops/async_function.rs#L30>

#### Actually getting the coroutine return type(s)

To most easily construct the `Coroutine` that a coroutine-closure returns, you can use the `to_coroutine_given_kind_and_upvars`[^helper] helper on `CoroutineClosureSignature`, which can be acquired from the `CoroutineClosureArgs`.

[^helper]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_type_ir/src/ty_kind/closure.rs#L419>

Most of the args to that function will be components that you can get out of the `CoroutineArgs`, except for the `goal_kind: ClosureKind` which controls which flavor of coroutine to return based off of the `ClosureKind` passed in -- i.e. it will prepare the by-ref coroutine if `ClosureKind::Fn | ClosureKind::FnMut`, and the by-move coroutine if `ClosureKind::FnOnce`.

### Trait hierarchy

We introduce a parallel hierarchy of `Fn*` traits that are implemented for .
The motivation for the introduction was covered in a blog post: [Async Closures](https://hackmd.io/@compiler-errors/async-closures).

All currently-stable callable types (i.e., closures, function items, function pointers, and `dyn Fn*` trait objects) automatically implement `AsyncFn*() -> T` if they implement `Fn*() -> Fut` for some output type `Fut`, and `Fut` implements `Future<Output = T>`[^tr1].

[^tr1]: <https://github.com/rust-lang/rust/blob/7c7bb7dc017545db732f5cffec684bbaeae0a9a0/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs#L404-L409>

Async closures implement `AsyncFn*` as their bodies permit; i.e. if they end up using upvars in a way that is compatible (i.e. if they consume or mutate their upvars, it may affect whether they implement `AsyncFn` and `AsyncFnMut`...)

#### Lending

We may in the future move `AsyncFn*` onto a more general set of `LendingFn*` traits; however, there are some concrete technical implementation details that limit our ability to use `LendingFn` ergonomically in the compiler today.
These have to do with:

- Closure signature inference.
- Limitations around higher-ranked trait bounds.
- Shortcomings with error messages.

These limitations, plus the fact that the underlying trait should have no effect on the user experience of async closures and async `Fn` trait bounds, leads us to `AsyncFn*` for now.
To ensure we can eventually move to these more general traits, the precise `AsyncFn*` trait definitions (including the associated types) are left as an implementation detail.

#### When do async closures implement the regular `Fn*` traits?

We mention above that "regular" callable types can implement `AsyncFn*`, but the reverse question exists of "can async closures implement `Fn*` too"? The short answer is "when it's valid", i.e. when the coroutine that would have been returned from `AsyncFn`/`AsyncFnMut` does not actually have any upvars that are "lent" from the parent coroutine-closure.

See the "follow-up: when do..." section below for an elaborated answer.
The full answer describes a pretty interesting and hopefully thorough heuristic that is used to ensure that most async closures "just work".

### Tale of two bodies...

When async closures are called with `AsyncFn`/`AsyncFnMut`, they return a coroutine that borrows from the closure.
However, when they are called via `AsyncFnOnce`, we consume that closure, and cannot return a coroutine that borrows from data that is now dropped.

To work around this limitation, we synthesize a separate by-move MIR body for calling `AsyncFnOnce::call_once` on a coroutine-closure that can be called by-ref.

This body operates identically to the "normal" coroutine returned from calling the coroutine-closure, except for the fact that it has a different set of upvars, since we must *move* the captures from the parent coroutine-closure into the child coroutine.

#### Synthesizing the by-move body

When we want to access the by-move body of the coroutine returned by a coroutine-closure, we can do so via the `coroutine_by_move_body_def_id`[^b1] query.

[^b1]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs#L1-L70>

This query synthesizes a new MIR body by copying the MIR body of the coroutine and inserting additional derefs and field projections[^b2] to preserve the semantics of the body.

[^b2]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs#L131-L195>

Since we've synthesized a new def id, this query is also responsible for feeding a ton of other relevant queries for the MIR body.
This query is `ensure()`d[^b3] during the `mir_promoted` query, since it operates on the *built* mir of the coroutine.

[^b3]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_mir_transform/src/lib.rs#L339-L342>

### Closure signature inference

The closure signature inference algorithm for async closures is a bit more complicated than the inference algorithm for "traditional" closures.
Like closures, we iterate through all of the clauses that may be relevant (for the expectation type passed in)[^deduce1].

To extract a signature, we consider two situations:
* Projection predicates with `AsyncFnOnce::Output`, which we will use to extract the inputs and output type for the closure.
  This corresponds to the situation that there was a `F: AsyncFn*() -> T` bound[^deduce2].
* Projection predicates with `FnOnce::Output`, which we will use to extract the inputs.
  For the output, we also try to deduce an output by looking for relevant `Future::Output` projection predicates.
  This corresponds to the situation that there was an `F: Fn*() -> T, T: Future<Output = U>` bound.[^deduce3]
    * If there is no `Future` bound, we simply use a fresh infer var for the output.
      This corresponds to the case where one can pass an async closure to a combinator function like `Option::map`.[^deduce4]

[^deduce1]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_hir_typeck/src/closure.rs#L345-L362>

[^deduce2]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_hir_typeck/src/closure.rs#L486-L487>

[^deduce3]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_hir_typeck/src/closure.rs#L517-L534>

[^deduce4]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_hir_typeck/src/closure.rs#L575-L590>

We support the latter case simply to make it easier for users to simply drop-in `async || {}` syntax, even when they're calling an API that was designed before first-class `AsyncFn*` traits were available.

#### Calling a closure before its kind has been inferred

We defer[^call1] the computation of a coroutine-closure's "kind" (i.e. its maximum calling mode: `AsyncFnOnce`/`AsyncFnMut`/`AsyncFn`) until the end of typeck. However, since we want to be able to call that coroutine-closure before the end of typeck, we need to come up with the return type of the coroutine-closure before that.

[^call1]: <https://github.com/rust-lang/rust/blob/705cfe0e966399e061d64dd3661bfbc57553ed87/compiler/rustc_hir_typeck/src/callee.rs#L169-L210>

Unlike regular closures, whose return type does not change depending on what `Fn*` trait we call it with, coroutine-closures *do* end up returning different coroutine types depending on the flavor of `AsyncFn*` trait used to call it.

Specifically, while the def-id of the returned coroutine does not change, the upvars[^call2] (which are either borrowed or moved from the parent coroutine-closure) and the coroutine-kind[^call3] are dependent on the calling mode.

[^call2]: <https://github.com/rust-lang/rust/blob/705cfe0e966399e061d64dd3661bfbc57553ed87/compiler/rustc_type_ir/src/ty_kind/closure.rs#L574-L576>

[^call3]: <https://github.com/rust-lang/rust/blob/705cfe0e966399e061d64dd3661bfbc57553ed87/compiler/rustc_type_ir/src/ty_kind/closure.rs#L554-L563>

We introduce a `AsyncFnKindHelper` trait which allows us to defer the question of "does this coroutine-closure support this calling mode"[^helper1] via a trait goal, and "what are the tupled upvars of this calling mode"[^helper2] via an associated type, which can be computed by appending the input types of the coroutine-closure to either the upvars or the "by ref" upvars computed during upvar analysis.

[^helper1]: <https://github.com/rust-lang/rust/blob/7c7bb7dc017545db732f5cffec684bbaeae0a9a0/library/core/src/ops/async_function.rs#L135-L144>

[^helper2]: <https://github.com/rust-lang/rust/blob/7c7bb7dc017545db732f5cffec684bbaeae0a9a0/library/core/src/ops/async_function.rs#L146-L154>

#### Ok, so why?

This seems a bit roundabout and complex, and I admit that it is.
But let's think of the "do nothing" alternative -- we could instead mark all `AsyncFn*` goals as ambiguous until upvar analysis, at which point we would know exactly what to put into the upvars of the coroutine we return.
However, this is actually *very* detrimental to inference in the program, since it means that programs like this would not be valid:

```rust,ignore
let c = async || -> String { .. };
let s = c().await;
// ^^^ If we can't project `<{c} as AsyncFn>::call()` to a coroutine, then the `IntoFuture::into_future` call inside of the `.await` stalls, and the type of `s` is left unconstrained as an infer var.
s.as_bytes();
// ^^^ That means we can't call any methods on the awaited return of a coroutine-closure, like... at all!
```

So *instead*, we use this alias (in this case, a projection: `AsyncFnKindHelper::Upvars<'env, ...>`) to delay the computation of the *tupled upvars* and give us something to put in its place, while still allowing us to return a `TyKind::Coroutine` (which is a rigid type) and we may successfully confirm the built-in traits we need (in our case, `Future`), since the `Future` implementation doesn't depend on the upvars at all.

### Upvar analysis

By and large, the upvar analysis for coroutine-closures and their child coroutines proceeds like normal upvar analysis.
However, there are several interesting bits that happen to account for async closures' special natures:

#### Forcing all inputs to be captured

Like async fn, all input arguments are captured.
We explicitly force[^f1] all of these inputs to be captured by move so that the future coroutine returned by async closures does not depend on whether the input is *used* by the body or not, which would impart an interesting semver hazard.

[^f1]: <https://github.com/rust-lang/rust/blob/7c7bb7dc017545db732f5cffec684bbaeae0a9a0/compiler/rustc_hir_typeck/src/upvar.rs#L250-L259>

#### Computing the by-ref captures

For a coroutine-closure that supports `AsyncFn`/`AsyncFnMut`, we must also compute the relationship between the captures of the coroutine-closure and its child coroutine.
Specifically, the coroutine-closure may `move` a upvar into its captures, but the coroutine may only borrow that upvar.

We compute the "`coroutine_captures_by_ref_ty`" by looking at all of the child coroutine's captures and comparing them to the corresponding capture of the parent coroutine-closure[^br1].
This `coroutine_captures_by_ref_ty` ends up being represented as a `for<'env> fn() -> captures...` type, with the additional binder lifetime representing the "`&self`" lifetime of calling `AsyncFn::async_call` or `AsyncFnMut::async_call_mut`.
We instantiate that binder later when actually calling the methods.

[^br1]: <https://github.com/rust-lang/rust/blob/7c7bb7dc017545db732f5cffec684bbaeae0a9a0/compiler/rustc_hir_typeck/src/upvar.rs#L375-L471>

Note that not every by-ref capture from the parent coroutine-closure results in a "lending" borrow.
See the **Follow-up: When do async closures implement the regular `Fn*` traits?** section below for more details, since this intimately influences whether or not the coroutine-closure is allowed to implement the `Fn*` family of traits.

#### By-move body + `FnOnce` quirk

There are several situations where the closure upvar analysis ends up inferring upvars for the coroutine-closure's child coroutine that are too relaxed, and end up resulting in borrow-checker errors.
This is best illustrated via examples.
For example, given:

```rust
fn force_fnonce<T: async FnOnce()>(t: T) -> T { t }

let x = String::new();
let c = force_fnonce(async move || {
    println!("{x}");
});
```

`x` will be moved into the coroutine-closure, but the coroutine that is returned would only borrow `&x`.
However, since `force_fnonce` forces the coroutine-closure to `AsyncFnOnce`, which is not *lending*, we must force the capture to happen by-move[^bm1].

Similarly:

```rust
let x = String::new();
let y = String::new();
let c = async move || {
    drop(y);
    println!("{x}");
};
```

`x` will be moved into the coroutine-closure, but the coroutine that is returned would only borrow `&x`. However, since we also capture `y` and drop it, the coroutine-closure is forced to be `AsyncFnOnce`. We must also force the capture of `x` to happen by-move. To determine this situation in particular, since unlike the last example the coroutine-kind's closure-kind has not yet been constrained, we must analyze the body of the coroutine-closure to see if how all of the upvars are used, to determine if they've been used in a way that is "consuming" -- i.e. that would force it to `FnOnce`[^bm2].

[^bm1]: <https://github.com/rust-lang/rust/blob/7c7bb7dc017545db732f5cffec684bbaeae0a9a0/compiler/rustc_hir_typeck/src/upvar.rs#L211-L248>

[^bm2]: <https://github.com/rust-lang/rust/blob/7c7bb7dc017545db732f5cffec684bbaeae0a9a0/compiler/rustc_hir_typeck/src/upvar.rs#L532-L539>

#### Follow-up: When do async closures implement the regular `Fn*` traits?

Well, first of all, all async closures implement `FnOnce` since they can always be called *at least once*.

For `Fn`/`FnMut`, the detailed answer involves answering a related question: is the coroutine-closure lending?
Because if it is, then it cannot implement the non-lending `Fn`/`FnMut` traits.

Determining when the coroutine-closure must *lend* its upvars is implemented in the `should_reborrow_from_env_of_parent_coroutine_closure` helper function[^u1].
Specifically, this needs to happen in two places:

[^u1]: <https://github.com/rust-lang/rust/blob/7c7bb7dc017545db732f5cffec684bbaeae0a9a0/compiler/rustc_hir_typeck/src/upvar.rs#L1818-L1860>

1.  Are we borrowing data owned by the parent closure?
    We can determine if that is the case by checking if the parent capture is by-move, EXCEPT if we apply a deref projection, which means we're reborrowing a reference that we captured by-move.

```rust
let x = &1i32; // Let's call this lifetime `'1`.
let c = async move || {
    println!("{:?}", *x);
    // Even though the inner coroutine borrows by ref, we're only capturing `*x`,
    // not `x`, so the inner closure is allowed to reborrow the data for `'1`.
};
```

2. If a coroutine is mutably borrowing from a parent capture, then that mutable borrow cannot live for longer than either the parent *or* the borrow that we have on the original upvar.
   Therefore we always need to borrow the child capture with the lifetime of the parent coroutine-closure's env.

```rust
let mut x = 1i32;
let c = async || {
    x = 1;
    // The parent borrows `x` for some `&'1 mut i32`.
    // However, when we call `c()`, we implicitly autoref for the signature of
    // `AsyncFnMut::async_call_mut`. Let's call that lifetime `'call`. Since
    // the maximum that `&'call mut &'1 mut i32` can be reborrowed is `&'call mut i32`,
    // the inner coroutine should capture w/ the lifetime of the coroutine-closure.
};
```

If either of these cases apply, then we should capture the borrow with the lifetime of the parent coroutine-closure's env.
Luckily, if this function is not correct, then the program is not unsound, since we still borrowck and validate the choices made from this function -- the only side-effect is that the user may receive unnecessary borrowck errors.

### Instance resolution

If a coroutine-closure has a closure-kind of `FnOnce`, then its `AsyncFnOnce::call_once` and `FnOnce::call_once` implementations resolve to the coroutine-closure's body[^res1], and the `Future::poll` of the coroutine that gets returned resolves to the body of the child closure.

[^res1]: <https://github.com/rust-lang/rust/blob/705cfe0e966399e061d64dd3661bfbc57553ed87/compiler/rustc_ty_utils/src/instance.rs#L351>

If a coroutine-closure has a closure-kind of `FnMut`/`Fn`, then the same applies to `AsyncFn` and the corresponding `Future` implementation of the coroutine that gets returned.[^res1] However, we use a MIR shim to generate the implementation of `AsyncFnOnce::call_once`/`FnOnce::call_once`[^res2], and `Fn::call`/`FnMut::call_mut` instances if they exist[^res3].

[^res2]: <https://github.com/rust-lang/rust/blob/705cfe0e966399e061d64dd3661bfbc57553ed87/compiler/rustc_ty_utils/src/instance.rs#L341-L349>

[^res3]: <https://github.com/rust-lang/rust/blob/705cfe0e966399e061d64dd3661bfbc57553ed87/compiler/rustc_ty_utils/src/instance.rs#L312-L326>

This is represented by the `ConstructCoroutineInClosureShim`[^i1].
The `receiver_by_ref` bool will be true if this is the instance of `Fn::call`/`FnMut::call_mut`.[^i2] The coroutine that all of these instances returns corresponds to the by-move body we will have synthesized by this point.[^i3]

[^i1]: <https://github.com/rust-lang/rust/blob/705cfe0e966399e061d64dd3661bfbc57553ed87/compiler/rustc_middle/src/ty/instance.rs#L129-L134>

[^i2]: <https://github.com/rust-lang/rust/blob/705cfe0e966399e061d64dd3661bfbc57553ed87/compiler/rustc_middle/src/ty/instance.rs#L136-L141>

[^i3]: <https://github.com/rust-lang/rust/blob/07cbbdd69363da97075650e9be24b78af0bcdd23/compiler/rustc_middle/src/ty/instance.rs#L841>

### Borrow-checking

It turns out that borrow-checking async closures is pretty straightforward.
After adding a new `DefiningTy::CoroutineClosure`[^bck1] variant, and teaching borrowck how to generate the signature of the coroutine-closure[^bck2], borrowck proceeds totally fine.

One thing to note is that we don't borrow-check the synthetic body we make for by-move coroutines, since by construction (and the validity of the by-ref coroutine body it was derived from) it must be valid.

[^bck1]: <https://github.com/rust-lang/rust/blob/705cfe0e966399e061d64dd3661bfbc57553ed87/compiler/rustc_borrowck/src/universal_regions.rs#L110-L115>

[^bck2]: <https://github.com/rust-lang/rust/blob/7c7bb7dc017545db732f5cffec684bbaeae0a9a0/compiler/rustc_borrowck/src/universal_regions.rs#L743-L790>

[RFC 3668]: https://rust-lang.github.io/rfcs/3668-async-closures.html

---

### Src Doc Rustc Dev Guide Src Crates Io (`src/doc/rustc-dev-guide/src/crates-io.md`)

# crates.io dependencies

The Rust compiler supports building with some dependencies from `crates.io`.

Rust Forge has [official policy for vetting new dependencies].

## Permitted dependencies

The `tidy` tool has [a list of crates that are allowed].
To add a dependency that is not already in the compiler, you will need to add it to the list.

[a list of crates that are allowed]: https://github.com/rust-lang/rust/blob/9d1b2106e23b1abd32fce1f17267604a5102f57a/src/tools/tidy/src/deps.rs#L73
[official policy for vetting new dependencies]: https://forge.rust-lang.org/compiler/third-party-out-of-tree#third-party-crates

---

### Src Doc Rustc Dev Guide Src Debugging Support In Rustc (`src/doc/rustc-dev-guide/src/debugging-support-in-rustc.md`)

# Debugging support in the Rust compiler

This document explains the state of debugging tools support in the Rust compiler (rustc).
It gives an overview of GDB, LLDB, WinDbg/CDB,
as well as infrastructure around Rust compiler to debug Rust code.
If you want to learn how to debug the Rust compiler itself,
see [Debugging the Compiler].

The material is gathered from the video,
[Tom Tromey discusses debugging support in rustc].

## Preliminaries

### Debuggers

According to Wikipedia

> A [debugger or debugging tool] is a computer program that is used to test and debug
> other programs (the "target" program).

Writing a debugger from scratch for a language requires a lot of work, especially if
debuggers have to be supported on various platforms.
GDB and LLDB, however, can be extended to support debugging a language.
This is the path that Rust has chosen.
This document's main goal is to document the said debuggers support in Rust compiler.

### DWARF

According to the [DWARF] standard website

> DWARF is a debugging file format used by many compilers and debuggers to support source level
> debugging. It addresses the requirements of a number of procedural languages,
> such as C, C++, and Fortran, and is designed to be extensible to other languages.
> DWARF is architecture independent and applicable to any processor or operating system.
> It is widely used on Unix, Linux and other operating systems,
> as well as in stand-alone environments.

DWARF reader is a program that consumes the DWARF format and creates debugger compatible output.
This program may live in the compiler itself.
 DWARF uses a data structure called
Debugging Information Entry (DIE) which stores the information as "tags" to denote functions,
variables etc., e.g., `DW_TAG_variable`, `DW_TAG_pointer_type`, `DW_TAG_subprogram` etc.
You can also invent your own tags and attributes.

### CodeView/PDB

[PDB] (Program Database) is a file format created by Microsoft that contains debug information.
PDBs can be consumed by debuggers such as WinDbg/CDB and other tools to display debug information.
A PDB contains multiple streams that describe debug information about a specific binary such
as types, symbols, and source files used to compile the given binary.
CodeView is another
format which defines the structure of [symbol records] and [type records] that appear within
PDB streams.

## Supported debuggers

### GDB

#### Rust expression parser

To be able to show debug output, we need an expression parser.
This (GDB) expression parser is written in [Bison],
and can parse only a subset of Rust expressions.
GDB parser was written from scratch and has no relation to any other parser,
including that of rustc.

GDB has Rust-like value and type output.
It can print values and types in a way that look like Rust syntax in the output.
Or when you print a type as [ptype] in GDB,
it also looks like Rust source code.
Checkout the documentation in the [manual for GDB/Rust].

#### Parser extensions

Expression parser has a couple of extensions in it to facilitate features that you cannot do
with Rust.
Some limitations are listed in the [manual for GDB/Rust].
There is some special code in the DWARF reader in GDB to support the extensions.

A couple of examples of DWARF reader support needed are as follows:

1. Enum: Needed for support for enum types.
   The Rust compiler writes the information about enum into DWARF,
   and GDB reads the DWARF to understand where is the tag field,
   or if there is a tag field,
   or if the tag slot is shared with non-zero optimization etc.

2. Dissect trait objects: DWARF extension where the trait object's description in the DWARF
   also points to a stub description of the corresponding vtable which in turn points to the
   concrete type for which this trait object exists.
   This means that you can do a `print *object`
   for that trait object, and GDB will understand how to find the correct type of the payload in
   the trait object.

**TODO**: Figure out if the following should be mentioned in the GDB-Rust document rather than
this guide page so there is no duplication.
This is regarding the following comments:

[This comment by Tom](https://github.com/rust-lang/rustc-dev-guide/pull/316#discussion_r284027340)
> gdb's Rust extensions and limitations are documented in the gdb manual:
https://sourceware.org/gdb/onlinedocs/gdb/Rust.html -- however, this neglects to mention that
gdb convenience variables and registers follow the gdb $ convention, and that the Rust parser
implements the gdb @ extension.

[This question by Aman](https://github.com/rust-lang/rustc-dev-guide/pull/316#discussion_r285401353)
> @tromey do you think we should mention this part in the GDB-Rust document rather than this
document so there is no duplication etc.?

### LLDB

#### Rust expression parser

This expression parser is written in C++.
It is a type of [Recursive Descent parser].
It implements slightly less of the Rust language than GDB.
LLDB has Rust-like value and type output.

#### Developer notes

* LLDB has a plugin architecture but that does not work for language support.
* GDB generally works better on Linux.

### WinDbg/CDB

Microsoft provides [Windows Debugging Tools] such as the Windows Debugger (WinDbg) and
the Console Debugger (CDB) which both support debugging programs written in Rust.
These debuggers parse the debug info for a binary from the `PDB`, if available, to construct a
visualization to serve up in the debugger.

#### Natvis

Both WinDbg and CDB support defining and viewing custom visualizations for any given type
within the debugger using the Natvis framework.
The Rust compiler defines a set of Natvis
files that define custom visualizations for a subset of types in the standard libraries such
as, `std`, `core`, and `alloc`.
These Natvis files are embedded into `PDBs` generated by the
`*-pc-windows-msvc` target triples to automatically enable these custom visualizations when
debugging.
This default can be overridden by setting the `strip` rustc flag to either `debuginfo` or `symbols`.

Rust has support for embedding Natvis files for crates outside of the standard libraries by
using the `#[debugger_visualizer]` attribute.
For more details on how to embed debugger visualizers,
please refer to the section on the [`debugger_visualizer` attribute].

## DWARF and `rustc`

[DWARF] is the standard way compilers generate debugging information that debuggers read.
It is _the_ debugging format on macOS and Linux.
It is a multi-language and extensible format,
and is mostly good enough for Rust's purposes.
Hence, the current implementation reuses DWARF's concepts.
This is true even if some of the concepts in DWARF do not align with Rust semantically because,
generally, there can be some kind of mapping between the two.

We have some DWARF extensions that the Rust compiler emits and the debuggers understand that
are _not_ in the DWARF standard.

* Rust compiler will emit DWARF for a virtual table, and this `vtable` object will have a
  `DW_AT_containing_type` that points to the real type.
  This lets debuggers dissect a trait object pointer to correctly find the payload.
  Here is an example of such a DIE, from a test case in the gdb repository:

  ```asm
  <1><1a9>: Abbrev Number: 3 (DW_TAG_structure_type)
     <1aa>   DW_AT_containing_type: <0x1b4>
     <1ae>   DW_AT_name        : (indirect string, offset: 0x23d): vtable
     <1b2>   DW_AT_byte_size   : 0
     <1b3>   DW_AT_alignment   : 8
  ```

* The other extension is that the Rust compiler can emit a tagless discriminated union.
  See [DWARF feature request] for this item.

### Current limitations of DWARF

* Traits - require a bigger change than normal to DWARF, on how to represent Traits in DWARF.
* DWARF provides no way to differentiate between Structs and Tuples.
  Rust compiler emits
fields with `__0` and debuggers look for a sequence of such names to overcome this limitation.
For example, in this case the debugger would look at a field via `x.__0` instead of `x.0`.
This is resolved via the Rust parser in the debugger so now you can do `x.0`.

DWARF relies on debuggers to know some information about platform ABI.
Rust does not do that all the time.

## Developer notes

This section is from the talk about certain aspects of development.

## What is missing

### Code signing for LLDB debug server on macOS

According to Wikipedia, [System Integrity Protection] is

> System Integrity Protection (SIP, sometimes referred to as rootless) is a security feature
> of Apple's macOS operating system introduced in OS X El Capitan. It comprises a number of
> mechanisms that are enforced by the kernel. A centerpiece is the protection of system-owned
> files and directories against modifications by processes without a specific "entitlement",
> even when executed by the root user or a user with root privileges (sudo).

It prevents processes using `ptrace` syscall.
If a process wants to use `ptrace` it has to be code signed.
The certificate that signs it has to be trusted on your machine.

See [Apple developer documentation for System Integrity Protection].

We may need to sign up with Apple and get the keys to do this signing.
Tom has looked into if Mozilla cannot do this because it is at the maximum number of
keys it is allowed to sign.
Tom does not know if Mozilla could get more keys.

Alternatively, Tom suggests that maybe a Rust legal entity is needed to get the keys via Apple.
This problem is not technical in nature.
If we had such a key, we could sign GDB as well and ship that.

### DWARF and Traits

Rust traits are not emitted into DWARF at all.
The impact of this is calling a method `x.method()` does not work as-is.
The reason being that method is implemented by a trait, as opposed to a type.
That information is not present, so finding trait methods is missing.

DWARF has a notion of interface types (possibly added for Java).
Tom's idea was to use this interface type as traits.

DWARF only deals with concrete names, not the reference types.
So, a given implementation of a
trait for a type would be one of these interfaces (`DW_tag_interface` type).
Also, the type for which it is implemented would describe all the interfaces this type implements.
This requires a DWARF extension.

Issue on GitHub: [https://github.com/rust-lang/rust/issues/33014]

## Typical process for a Debug Info change (LLVM)

LLVM has Debug Info (DI) builders.
This is the primary thing that Rust calls into.
This is why we need to change LLVM first because that is emitted first and not DWARF directly.
This is a kind of metadata that you construct and hand-off to LLVM.
For the Rustc/LLVM hand-off,
some LLVM DI builder methods are called to construct representation of a type.

The steps of this process are as follows:

1. LLVM needs changing.

   LLVM does not emit Interface types at all, so this needs to be implemented in LLVM first.

   Get sign off on LLVM maintainers that this is a good idea.

2. Change the DWARF extension.

3. Update the debuggers.

   Update DWARF readers, expression evaluators.

4. Update Rust compiler.

   Change it to emit this new information.

### Procedural macro stepping

A deeply profound question is that how do you actually debug a procedural macro?
What is the location you emit for a macro expansion?
Consider some of the following cases -

* You can emit location of the invocation of the macro.
* You can emit the location of the definition of the macro.
* You can emit locations of the content of the macro.

RFC: [https://github.com/rust-lang/rfcs/pull/2117]

Focus is to let macros decide what to do.
This can be achieved by having some kind of attribute
that lets the macro tell the compiler where the line marker should be.
This affects where you set the breakpoints and what happens when you step it.

## Source file checksums in debug info

Both DWARF and CodeView (PDB) support embedding a cryptographic hash of each source file that
contributed to the associated binary.

The cryptographic hash can be used by a debugger to verify that the source file matches the
executable.
If the source file does not match, the debugger can provide a warning to the user.

The hash can also be used to prove that a given source file has not been modified since it was
used to compile an executable.
Because MD5 and SHA1 both have demonstrated vulnerabilities,
using SHA256 is recommended for this application.

The Rust compiler stores the hash for each source file in the corresponding `SourceFile` in
the `SourceMap`.
The hashes of input files to external crates are stored in `rlib` metadata.

A default hashing algorithm is set in the target specification.
This allows the target to
specify the best hash available, since not all targets support all hash algorithms.

The hashing algorithm for a target can also be overridden with the `-Z source-file-checksum=`
command-line option.

#### DWARF 5
DWARF version 5 supports embedding an MD5 hash to validate the source file version in use.
DWARF 5 - Section 6.2.4.1 opcode DW_LNCT_MD5

#### LLVM
LLVM IR supports MD5 and SHA1 (and SHA256 in LLVM 11+) source file checksums in the DIFile node.

[LLVM DIFile documentation](https://llvm.org/docs/LangRef.html#difile)

#### Microsoft Visual C++ Compiler /ZH option
The MSVC compiler supports embedding MD5, SHA1, or SHA256 hashes in the PDB using the `/ZH`
compiler option.

[MSVC /ZH documentation](https://docs.microsoft.com/en-us/cpp/build/reference/zh)

#### Clang
Clang always embeds an MD5 checksum, though this does not appear in documentation.

## Future work

#### Name mangling changes

* New demangler in `libiberty` (gcc source tree).
* New demangler in LLVM or LLDB.

**TODO**: Check the location of the demangler source.
[#1157](https://github.com/rust-lang/rustc-dev-guide/issues/1157)

#### Reuse Rust compiler for expressions

This is an important idea because debuggers by and large do not try to implement type inference.
You need to be much more explicit when you type into the debugger than your actual source code.
So, you cannot just copy and paste an expression from your source
code to debugger and expect the same answer, but this would be nice.
This can be helped by using compiler.

It is certainly doable, but it is a large project.
You certainly need a bridge to the debugger because the debugger alone has access to the memory.
Both GDB (gcc) and LLDB (clang) have this feature.
LLDB uses Clang to compile code to JIT and GDB can do the same with GCC.

Both debuggers expression evaluation implement both a superset and a subset of Rust.
They implement just the expression language,
but they also add some extensions like GDB has convenience variables.
Therefore, if you are taking this route,
then you not only need to do this bridge,
but may have to add some mode to let the compiler understand some extensions.

[Tom Tromey discusses debugging support in rustc]: https://www.youtube.com/watch?v=elBxMRSNYr4
[Debugging the Compiler]: compiler-debugging.md
[debugger or debugging tool]: https://en.wikipedia.org/wiki/Debugger
[Bison]: https://www.gnu.org/software/bison/
[ptype]: https://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_109.html
[rust-lang/lldb wiki page]: https://github.com/rust-lang/lldb/wiki
[DWARF]: http://dwarfstd.org
[manual for GDB/Rust]: https://sourceware.org/gdb/onlinedocs/gdb/Rust.html
[GDB Bugzilla]: https://sourceware.org/bugzilla/
[Recursive Descent parser]: https://en.wikipedia.org/wiki/Recursive_descent_parser
[System Integrity Protection]: https://en.wikipedia.org/wiki/System_Integrity_Protection
[https://github.com/rust-dev-tools/gdb]: https://github.com/rust-dev-tools/gdb
[DWARF feature request]: http://dwarfstd.org/ShowIssue.php?issue=180517.2
[https://docs.python.org/3/c-api/stable.html]: https://docs.python.org/3/c-api/stable.html
[https://github.com/rust-lang/rfcs/pull/2117]: https://github.com/rust-lang/rfcs/pull/2117
[https://github.com/rust-lang/rust/issues/33014]: https://github.com/rust-lang/rust/issues/33014
[https://github.com/rust-lang/rust/issues/34457]: https://github.com/rust-lang/rust/issues/34457
[Apple developer documentation for System Integrity Protection]: https://developer.apple.com/library/archive/releasenotes/MacOSX/WhatsNewInOSX/Articles/MacOSX10_11.html#//apple_ref/doc/uid/TP40016227-SW11
[https://github.com/rust-lang/lldb]: https://github.com/rust-lang/lldb
[https://github.com/rust-lang/llvm-project]: https://github.com/rust-lang/llvm-project
[PDB]: https://llvm.org/docs/PDB/index.html
[symbol records]: https://llvm.org/docs/PDB/CodeViewSymbols.html
[type records]: https://llvm.org/docs/PDB/CodeViewTypes.html
[Windows Debugging Tools]: https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/
[`debugger_visualizer` attribute]: https://doc.rust-lang.org/nightly/reference/attributes/debugger.html#the-debugger_visualizer-attribute

---

### Src Doc Rustc Dev Guide Src Diagnostics (`src/doc/rustc-dev-guide/src/diagnostics.md`)

# Errors and lints

A lot of effort has been put into making `rustc` have great error messages.
This chapter is about how to emit compile errors and lints from the compiler.

## Diagnostic structure

The main parts of a diagnostic error are the following:

```
error[E0000]: main error message
  --> file.rs:LL:CC
   |
LL | <code>
   | -^^^^- secondary label
   |  |
   |  primary label
   |
   = note: note without a `Span`, created with `.note`
note: sub-diagnostic message for `.span_note`
  --> file.rs:LL:CC
   |
LL | more code
   |      ^^^^
```

- Level (`error`, `warning`, etc.). It indicates the severity of the message.
  (See [diagnostic levels](#diagnostic-levels))
- Code (for example, for "mismatched types", it is `E0308`).
  It helps users get more information about the current error through an extended
  description of the problem in the error code index.
  Not all diagnostic have a code.
  For example, diagnostics created by lints don't have one.
- Message.
  It is the main description of the problem.
  It should be general and able to stand on its own, so that it can make sense even in isolation.
- Diagnostic window.
  This contains several things:
  - The path, line number and column of the beginning of the primary span.
  - The users' affected code and its surroundings.
  - Primary and secondary spans underlying the users' code.
    These spans can optionally contain one or more labels.
    - Primary spans should have enough text to describe the problem in such a
      way that if it were the only thing being displayed (for example,
      in an IDE) it would still make sense.
      Because it is "spatially aware" (it points at the code),
      it can generally be more succinct than the error message.
    - If cluttered output can be foreseen in cases when multiple span labels overlap,
      it is a good idea to tweak the output appropriately.
      For example, the `if/else arms have incompatible types` error uses different
      spans depending on whether the arms are all in the same line,
      if one of the arms is empty, and if none of those cases applies.
- Sub-diagnostics.
  Any error can have multiple sub-diagnostics that look similar to the main part of the error.
  These are used for cases where the
  order of the explanation might not correspond with the order of the code.
  If the order of the explanation can be "order free", leveraging secondary labels
  in the main diagnostic is preferred, as it is typically less verbose.

The text should be matter of fact and avoid capitalization and periods,
unless multiple sentences are _needed_:

```txt
error: the fobrulator needs to be krontrificated
```

When code or an identifier must appear in a message or label,
it should be surrounded with backticks:

```txt
error: the identifier `foo.bar` is invalid
```

### Error codes and explanations

Most errors have an associated error code.
Error codes are linked to long-form
explanations which contains an example of how to trigger the error and in-depth
details about the error.
They may be viewed with the `--explain` flag, or via the [error index].

As a general rule, give an error a code (with an associated explanation) if the
explanation would give more information than the error itself.
A lot of the time it's better to put all the information in the emitted error itself.
However,
sometimes that would make the error verbose or there are too many possible
triggers to include useful information for all cases in the error,
in which case it's a good idea to add an explanation.[^estebank]
As always, if you are not sure, just ask your reviewer!

If you decide to add a new error with an associated error code,
please read [this section][error-codes] for a guide and important details about the process.

[^estebank]: This rule of thumb was suggested by **@estebank** [here][estebank-comment].

[error index]: https://doc.rust-lang.org/error-index.html
[estebank-comment]: https://github.com/rust-lang/rustc-dev-guide/pull/967#issuecomment-733218283
[error-codes]: ./diagnostics/error-codes.md

### Lints versus fixed diagnostics

Some messages are emitted via [lints](#lints), where the user can control the level.
Most diagnostics are hard-coded such that the user cannot control the level.

Usually it is obvious whether a diagnostic should be "fixed" or a lint,
but there are some grey areas.

Here are a few examples:

- Borrow checker errors: these are fixed errors.
  The user cannot adjust the level of these diagnostics to silence the borrow checker.
- Dead code: this is a lint.
  While the user probably doesn't want dead code in their crate,
  making this a hard error would make refactoring and development very painful.
- [future-incompatible lints]: these are silenceable lints.
  It was decided that making them fixed errors would cause too much breakage,
  so warnings are instead emitted,
  and will eventually be turned into fixed (hard) errors.

Hard-coded warnings (those using methods like `span_warn`) should be avoided for normal code,
preferring to use lints instead.
Some cases, such as warnings with CLI flags, will require the use of hard-coded warnings.

See the `deny` [lint level](#diagnostic-levels) below for guidelines when to
use an error-level lint instead of a fixed error.

[future-incompatible lints]: #future-incompatible-lints

## Diagnostic output style guide

- Write in plain simple English.
  If your message, when shown on a – possibly
  small – screen (which hasn't been cleaned for a while), cannot be understood
  by a normal programmer, who just came out of bed after a night partying,
  it's too complex.
- `Error`, `Warning`, `Note`,
  and `Help` messages start with a lowercase letter and do not end with punctuation.
- Error messages should be succinct.
  Users will see these error messages many times,
  and more verbose descriptions can be viewed with the `--explain` flag.
  That said, don't make it so terse that it's hard to understand.
- The word "illegal" is illegal.
  Prefer "invalid" or a more specific word instead.
- Errors should document the span of code where they occur (use
  [`rustc_errors::DiagCtxt`][DiagCtxt]'s
  `span_*` methods or a diagnostic struct's `#[primary_span]` to easily do this).
  Also `note` other spans that have contributed to the error if the span isn't too large.
- When emitting a message with span,
  try to reduce the span to the smallest amount possible that still signifies the issue
- Try not to emit multiple error messages for the same error.
  This may require detecting duplicates.
- When the compiler has too little information for a specific error message,
  consult with the compiler team to add new attributes for library code that
  allow adding more information.
  For example, see [`#[rustc_on_unimplemented]`](#rustc_on_unimplemented).
  Use these annotations when available!
- Keep in mind that Rust's learning curve is rather steep,
  and that the compiler messages are an important learning tool.
- When talking about the compiler, call it `the compiler`, not `Rust` or `rustc`.
- Use the [Oxford comma](https://en.wikipedia.org/wiki/Serial_comma) when writing lists of items.
- When mentioning attributes, use this form whenever possible: "the `inline` attribute".
  Don't include `#[`/`#![`/`]` delimiters or attribute arguments in the message or the span unless
  they are relevant.

### Lint naming

From [RFC 0344], lint names should be consistent, with the following guidelines:

The basic rule is: the lint name should make sense when read as "allow
*lint-name*" or "allow *lint-name* items".
For example, "allow `deprecated` items" and "allow `dead_code`" makes sense,
while "allow `unsafe_block`" is ungrammatical (should be plural).

- Lint names should state the bad thing being checked for, e.g. `deprecated`,
  so that `#[allow(deprecated)]` (items) reads correctly.
  Thus, `ctypes` is not an appropriate name; `improper_ctypes` is.

- Lints that apply to arbitrary items (like the stability lints) should just
  mention what they check for: use `deprecated` rather than `deprecated_items`.
  This keeps lint names short.
  (Again, think "allow *lint-name* items".)

- If a lint applies to a specific grammatical class,
  mention that class and use the plural form: use `unused_variables` rather than `unused_variable`.
  This makes `#[allow(unused_variables)]` read correctly.

- Lints that catch unnecessary, unused, or useless aspects of code should use
  the term `unused`, e.g. `unused_imports`, `unused_typecasts`.

- Use snake case in the same way you would for function names.

[RFC 0344]: https://github.com/rust-lang/rfcs/blob/master/text/0344-conventions-galore.md#lints

### Diagnostic levels

Guidelines for different diagnostic levels:

- `error`: emitted when the compiler detects a problem that makes it unable to
  compile the program, either because the program is invalid or the programmer
  has decided to make a specific `warning` into an error.

- `warning`: emitted when the compiler detects something odd about a program.
  Care should be taken when adding warnings to avoid warning fatigue,
  and avoid false-positives where there really isn't a problem with the code.
  Some examples of when it is appropriate to issue a warning:

  - A situation where the user *should* take action, such as swap out a deprecated item,
    or use a `Result`, but otherwise doesn't prevent compilation.
  - Unnecessary syntax that can be removed without affecting the semantics of the code.
    For example, unused code, or unnecessary `unsafe`.
  - Code that is very likely to be incorrect, dangerous, or confusing, but the
    language technically allows, and is not ready or confident enough to make an error.
    Examples are `unused_comparisons` (out of bounds comparisons) or
    `bindings_with_variant_name` (the user likely did not intend to create a
    binding in a pattern).
  - [Future-incompatible lints](#future-incompatible), where something was
    accidentally or erroneously accepted in the past,
    but rejecting would cause excessive breakage in the ecosystem.
  - Stylistic choices.
    For example, camel or snake case, or the `dyn` trait warning in the 2018 edition.
    These have a high bar to be added, and should only be used in exceptional circumstances.
    Other stylistic choices should either be allow-by-default lints,
    or part of other tools like Clippy or rustfmt.

- `help`: emitted following an `error` or `warning` to give additional
  information to the user about how to solve their problem.
  These messages often include a suggestion string and [`rustc_errors::Applicability`]
  confidence level to guide automated source fixes by tools.
  See the [Suggestions](#suggestions) section for more details.

  The error or warning portion should *not* suggest how to fix the problem,
  only the "help" sub-diagnostic should.

- `note`: emitted to give more context and identify additional circumstances
  and parts of the code that caused the warning or error.
  For example, the borrow checker will note any previous conflicting borrows.

  `help` vs `note`: `help` should be used to show changes the user can
  possibly make to fix the problem.
  `note` should be used for everything else,
  such as other context, information and facts, online resources to read, etc.

Not to be confused with *lint levels*, whose guidelines are:

- `forbid`: Lints should never default to `forbid`.
- `deny`: Equivalent to `error` diagnostic level.
  Some examples:

  - A future-incompatible or edition-based lint that has graduated from the warning level.
  - Something that has an extremely high confidence that is incorrect,
    but still want an escape hatch to allow it to pass.

- `warn`: Equivalent to the `warning` diagnostic level.
  See `warning` above for guidelines.
- `allow`: Examples of the kinds of lints that should default to `allow`:

  - The lint has a too high false positive rate.
  - The lint is too opinionated.
  - The lint is experimental.
  - The lint is used for enforcing something that is not normally enforced.
    For example, the `unsafe_code` lint can be used to prevent usage of unsafe code.

More information about lint levels can be found in the [rustc
book][rustc-lint-levels] and the [reference][reference-diagnostics].

[`rustc_errors::Applicability`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html
[reference-diagnostics]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#lint-check-attributes
[rustc-lint-levels]: https://doc.rust-lang.org/nightly/rustc/lints/levels.html

## Helpful tips and options

### Finding the source of errors

There are three main ways to find where a given error is emitted:

- `grep` for either a sub-part of the error message/label or error code.
  This usually works well and is straightforward, but there are some cases where
  the code emitting the error is removed from the code where the error is
  constructed behind a relatively deep call-stack.
  Even then, it is a good way to get your bearings.
- Invoking `rustc` with the nightly-only flag `-Z treat-err-as-bug=1`
  will treat the first error being emitted as an Internal Compiler Error,
  which allows you to get a stack trace at the point the error has been emitted.
  Change the `1` to something else if you wish to trigger on a later error.

  There are limitations with this approach:
  - Some calls get elided from the stack trace because they get inlined in the compiled `rustc`.
  - The _construction_ of the error is far away from where it is _emitted_,
    a problem similar to the one we faced with the `grep` approach.
    In some cases, we buffer multiple errors in order to emit them in order.
- Invoking `rustc` with `-Z track-diagnostics` will print error creation
  locations alongside the error.

The regular development practices apply: judicious use of `debug!()` statements
and use of a debugger to trigger break points in order to figure out in what
order things are happening.

## `Span`

[`Span`][span] is the primary data structure in `rustc` used to represent a
location in the code being compiled.
`Span`s are attached to most constructs in HIR and MIR,
allowing for more informative error reporting.

[span]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html

A `Span` can be looked up in a [`SourceMap`][sourcemap] to get a "snippet"
useful for displaying errors with [`span_to_snippet`][sptosnip] and other
similar methods on the `SourceMap`.

[sourcemap]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/source_map/struct.SourceMap.html
[sptosnip]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/source_map/struct.SourceMap.html#method.span_to_snippet

## Error messages

The [`rustc_errors`][errors] crate defines most of the utilities used for reporting errors.

[errors]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html

Diagnostics can be implemented as types which implement the `Diagnostic` trait.
This is preferred for new diagnostics as it enforces a separation
between diagnostic emitting logic and the main code paths.
For less-complex diagnostics,
the `Diagnostic` trait can be derived -- see [Diagnostic structs][diagnostic-structs].
Within the trait implementation, the APIs described below can be used as normal.

[diagnostic-structs]: ./diagnostics/diagnostic-structs.md

[`DiagCtxt`][DiagCtxt] has methods that create and emit errors.
These methods
usually have names like `span_err` or `struct_span_err` or `span_warn`, etc...
There are lots of them; they emit different types of "errors", such as
warnings, errors, fatal errors, suggestions, etc.

[DiagCtxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagCtxt.html

In general, there are two classes of such methods: ones that emit an error
directly and ones that allow finer control over what to emit.
For example,
[`span_err`][spanerr] emits the given error message at the given `Span`,
but [`struct_span_err`][strspanerr] instead returns a [`Diag`][diag].

Most of these methods will accept strings, but it is recommended that typed
identifiers for translatable diagnostics be used for new diagnostics (see [Translation]).

[translation]: ./diagnostics/translation.md

`Diag` allows you to add related notes and suggestions to an error
before emitting it by calling the [`emit`] method.
(Failing to either emit or [cancel] a `Diag` will result in an ICE.) See the
[docs][diag] for more info on what you can do.

[spanerr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagCtxt.html#method.span_err
[strspanerr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagCtxt.html#method.struct_span_err
[`emit`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html#method.emit
[cancel]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html#method.cancel

```rust,ignore
// Get a `Diag`. This does _not_ emit an error yet.
let mut err = sess.dcx.struct_span_err(sp, fluent::example::example_error);

// In some cases, you might need to check if `sp` is generated by a macro to
// avoid printing weird errors about macro-generated code.

if let Ok(snippet) = sess.source_map().span_to_snippet(sp) {
    // Use the snippet to generate a suggested fix
    err.span_suggestion(suggestion_sp, fluent::example::try_qux_suggestion, format!("qux {}", snippet));
} else {
    // If we weren't able to generate a snippet, then emit a "help" message
    // instead of a concrete "suggestion". In practice this is unlikely to be
    // reached.
    err.span_help(suggestion_sp, fluent::example::qux_suggestion);
}

// emit the error
err.emit();
```

```fluent
example-example-error = oh no! this is an error!
  .try-qux-suggestion = try using a qux here
  .qux-suggestion = you could use a qux here instead
```

## Suggestions

In addition to telling the user exactly _why_ their code is wrong,
it's oftentimes furthermore possible to tell them how to fix it.
To this end,
[`Diag`][diag] offers a structured suggestions API, which formats code
suggestions pleasingly in the terminal, or (when the `--error-format json` flag
is passed) as JSON for consumption by tools like [`rustfix`][rustfix].

[rustfix]: https://github.com/rust-lang/rustfix

Not all suggestions should be applied mechanically;
they have a degree of confidence in the suggested code,
from high (`Applicability::MachineApplicable`) to low (`Applicability::MaybeIncorrect`).
Be conservative when choosing the level.
Use the [`span_suggestion`][span_suggestion] method of `Diag` to make a suggestion.
The last argument provides a hint to tools whether the suggestion is mechanically applicable or not.

Suggestions point to one or more spans with corresponding code that will
replace their current content.

The message that accompanies them should be understandable in the following contexts:

- shown as an independent sub-diagnostic (this is the default output)
- shown as a label pointing at the affected span (this is done automatically if
some heuristics for verbosity are met)
- shown as a `help` sub-diagnostic with no content (used for cases where the
suggestion is obvious from the text, but we still want to let tools to apply them)
- not shown (used for _very_ obvious cases, but we still want to allow tools to apply them)

[span_suggestion]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html#method.span_suggestion

For example, to make our `qux` suggestion machine-applicable, we would do:

```rust,ignore
let mut err = sess.dcx.struct_span_err(sp, fluent::example::message);

if let Ok(snippet) = sess.source_map().span_to_snippet(sp) {
    err.span_suggestion(
        suggestion_sp,
        fluent::example::try_qux_suggestion,
        format!("qux {}", snippet),
        Applicability::MachineApplicable,
    );
} else {
    err.span_help(suggestion_sp, fluent::example::qux_suggestion);
}

err.emit();
```

This might emit an error like

```console
$ rustc mycode.rs
error[E0999]: oh no! this is an error!
 --> mycode.rs:3:5
  |
3 |     sad()
  |     ^ help: try using a qux here: `qux sad()`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0999`.
```

In some cases, like when the suggestion spans multiple lines or when there are
multiple suggestions, the suggestions are displayed on their own:

```console
error[E0999]: oh no! this is an error!
 --> mycode.rs:3:5
  |
3 |     sad()
  |     ^
help: try using a qux here:
  |
3 |     qux sad()
  |     ^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0999`.
```

The possible values of [`Applicability`][appl] are:

- `MachineApplicable`: Can be applied mechanically.
- `HasPlaceholders`: Cannot be applied mechanically because it has placeholder
  text in the suggestions.
  For example: ```try adding a type: `let x: <type>` ```.
- `MaybeIncorrect`: Cannot be applied mechanically because the suggestion may
  or may not be a good one.
- `Unspecified`: Cannot be applied mechanically because we don't know which
  of the above cases it falls into.

[appl]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html

### Suggestion Style Guide

- Suggestions should not be a question.
  In particular, language like "did you mean" should be avoided.
  Sometimes, it's unclear why a particular suggestion is being made.
  In these cases, it's better to be upfront about what the suggestion is.

  Compare "did you mean: `Foo`" vs.
  "there is a struct with a similar name: `Foo`".

- The message should not contain any phrases like "the following", "as shown",
  etc. Use the span to convey what is being talked about.
- The message may contain further instruction such as "to do xyz, use" or "to do xyz, use abc".
- The message may contain a name of a function, variable, or type, but avoid whole expressions.

## Lints

The compiler linting infrastructure is defined in the [`rustc_middle::lint`][rlint] module.

[rlint]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/lint/index.html

### When do lints run?

Different lints will run at different times based on what information the lint needs to do its job.
Some lints get grouped into *passes* where the lints
within a pass are processed together via a single visitor.
Some of the passes are:

- Pre-expansion pass: Works on [AST nodes] before [macro expansion].
  This should generally be avoided.
  - Example: [`keyword_idents`] checks for identifiers that will become
    keywords in future editions, but is sensitive to identifiers used in macros.

- Early lint pass: Works on [AST nodes] after [macro expansion] and name resolution,
  just before [AST lowering].
  These lints are for purely syntactical lints.
  - Example: The [`unused_parens`] lint checks for parenthesized-expressions
    in situations where they are not needed, like an `if` condition.

- Late lint pass: Works on [HIR nodes], towards the end of [analysis] (after
  borrow checking, etc.). These lints have full type information available.
  Most lints are late.
  - Example: The [`invalid_value`] lint (which checks for obviously invalid
    uninitialized values) is a late lint because it needs type information to
    figure out whether a type allows being left uninitialized.

- MIR pass: Works on [MIR nodes].
  This isn't quite the same as other passes;
  lints that work on MIR nodes have their own methods for running.
  - Example: The [`arithmetic_overflow`] lint is emitted when it detects a
    constant value that may overflow.

Most lints work well via the pass systems,
and they have a fairly straightforward interface and easy way to integrate (mostly just implementing
a specific `check` function).
However,
some lints are easier to write when they live on a specific code path anywhere in the compiler.
For example, the [`unused_mut`] lint is implemented in the borrow checker as it requires some
information and state in the borrow checker.

Some of these inline lints fire before the linting system is ready.
Those lints will be *buffered* where they are held until later phases of the
compiler when the linting system is ready.
See [Linting early in the compiler](#linting-early-in-the-compiler).


[AST nodes]: the-parser.md
[AST lowering]: ./hir/lowering.md
[HIR nodes]: hir.md
[MIR nodes]: mir/index.md
[macro expansion]: macro-expansion.md
[analysis]: part-4-intro.md
[`keyword_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#keyword-idents
[`unused_parens`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#unused-parens
[`invalid_value`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#invalid-value
[`arithmetic_overflow`]: https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html#arithmetic-overflow
[`unused_mut`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#unused-mut

### Lint definition terms

Lints are managed via the [`LintStore`][LintStore] and get registered in various ways.
The following terms refer to the different classes of lints
generally based on how they are registered.

- *Built-in* lints are defined inside the compiler source.
- *Driver-registered* lints are registered when the compiler driver is created
  by an external driver.
  This is the mechanism used by Clippy, for example.
- *Tool* lints are lints with a path prefix like `clippy::` or `rustdoc::`.
- *Internal* lints are the `rustc::` scoped tool lints that only run on the
  rustc source tree itself and are defined in the compiler source like a regular built-in lint.

More information about lint registration can be found in the [LintStore] chapter.

[LintStore]: diagnostics/lintstore.md

### Declaring a lint

The built-in compiler lints are defined in the [`rustc_lint`][builtin] crate.
Lints that need to be implemented in other crates are defined in [`rustc_lint_defs`].
You should prefer to place lints in `rustc_lint` if possible.
One benefit is that it is close to the dependency root, so it can be much faster to work on.

[builtin]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/index.html
[`rustc_lint_defs`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/index.html

Every lint is implemented via a `struct` that implements the `LintPass` `trait`
(you can also implement one of the more specific lint pass traits,
either `EarlyLintPass` or `LateLintPass`, depending on when is best for your lint to run).
The trait implementation allows you to check certain syntactic constructs
as the linter walks the AST.
You can then choose to emit lints in a very similar way to compile errors.

You also declare the metadata of a particular lint via the [`declare_lint!`] macro.
This macro includes the name, the default level, a short description, and some more details.

Note that the lint and the lint pass must be registered with the compiler.

For example, the following lint checks for uses
of `while true { ... }` and suggests using `loop { ... }` instead.

```
/* Detailed source-code truncated for AI context efficiency. */
```

```fluent
example-use-loop = denote infinite loops with `loop {"{"} ... {"}"}`
  .suggestion = use `loop`
```

[`declare_lint!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html

### Edition-gated lints

Sometimes we want to change the behavior of a lint in a new edition.
To do this,
we just add the transition to our invocation of `declare_lint!`:

```rust,ignore
declare_lint! {
    pub ANONYMOUS_PARAMETERS,
    Allow,
    "detects anonymous parameters",
    Edition::Edition2018 => Warn,
}
```

This makes the `ANONYMOUS_PARAMETERS` lint allow-by-default in the 2015 edition
but warn-by-default in the 2018 edition.

See [Edition-specific lints](./guides/editions.md#edition-specific-lints) for more information.

### Feature-gated lints

Lints belonging to a feature should only be usable if the feature is enabled in the crate.
To support this, lint declarations can contain a feature gate like so:

```rust,ignore
declare_lint! {
    pub SOME_LINT_NAME,
    Warn,
    "a new and useful, but feature gated lint",
    @feature_gate = sym::feature_name;
}
```

### future-incompatible lints

The use of the term `future-incompatible` within the compiler has a slightly
broader meaning than what rustc exposes to users of the compiler.

Inside rustc,
future-incompatible lints are for signalling to the user their code may not compile in the future.
In general, future-incompatible code exists for two reasons:
* The code is unsound, and the compiler mistakenly accepted it.
  While it is within Rust's backwards compatibility guarantees to fix the soundness hole
  (breaking the user's code), the lint is there to warn the user that this will happen
  in some upcoming version of rustc *regardless of which edition the code uses*.
  This is the meaning that rustc exclusively exposes to users as "future incompatible".
* The code will either no longer compile *or* will change
  meaning in an upcoming *edition*.
  These are often called "edition lints" and can be
  typically seen in the various "edition compatibility" lint groups (e.g., `rust_2021_compatibility`)
  that are used to lint against code that will break if the user updates the crate's edition.
  See [migration lints](guides/editions.md#migration-lints) for more details.

A future-incompatible lint should be declared with the `@future_incompatible` additional "field":

```rust,ignore
declare_lint! {
    pub ANONYMOUS_PARAMETERS,
    Allow,
    "detects anonymous parameters",
    @future_incompatible = FutureIncompatibleInfo {
        reason: fcw!(EditionError 2018 "slug-of-edition-guide-page")
    };
}
```

Notice the `reason` field which describes why the future incompatible change is happening.
This will change the diagnostic message the user receives as well as determine which
lint groups the lint is added to.
In the example above, the lint is an "edition lint" (since its "reason" is `EditionError`),
signifying to the user that the use of anonymous
parameters will no longer compile in Rust 2018 and beyond.

Inside [LintStore::register_lints][fi-lint-groupings], lints with `future_incompatible`
fields get placed into either edition-based lint groups (if their `reason` is tied to
an edition) or into the `future_incompatibility` lint group.

[fi-lint-groupings]: https://github.com/rust-lang/rust/blob/51fd129ac12d5bfeca7d216c47b0e337bf13e0c2/compiler/rustc_lint/src/context.rs#L212-L237

If you need a combination of options that's not supported by the `declare_lint!` macro,
you can always change the `declare_lint!` macro to support this.

### Renaming or removing a lint

If it is determined that a lint is either improperly named or no longer needed,
the lint must be registered for renaming or removal,
which will trigger a warning if a user tries to use the old lint name.
To declare a rename/remove,
add a line with [`store.register_renamed`] or [`store.register_removed`] to the code of the
[`rustc_lint::register_builtins`] function.

```rust,ignore
store.register_renamed("single_use_lifetime", "single_use_lifetimes");
```

[`store.register_renamed`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html#method.register_renamed
[`store.register_removed`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html#method.register_removed
[`rustc_lint::register_builtins`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/fn.register_builtins.html

### Lint groups

Lints can be turned on in groups.
These groups are declared in the
[`register_builtins`][rbuiltins] function in [`rustc_lint::lib`][builtin].
The `add_lint_group!` macro is used to declare a new group.

[rbuiltins]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/fn.register_builtins.html

For example,

```rust,ignore
add_lint_group!(sess,
    "nonstandard_style",
    NON_CAMEL_CASE_TYPES,
    NON_SNAKE_CASE,
    NON_UPPER_CASE_GLOBALS);
```

This defines the `nonstandard_style` group which turns on the listed lints.
A user can turn on these lints with a `#![warn(nonstandard_style)]` attribute in the source code,
or by passing `-W nonstandard-style` on the command line.

Some lint groups are created automatically in `LintStore::register_lints`.
For instance,
any lint declared with `FutureIncompatibleInfo` where the reason is
`FutureIncompatibilityReason::FutureReleaseError` (the default when
`@future_incompatible` is used in `declare_lint!`),
will be added to the `future_incompatible` lint group.
Editions also have their own lint groups
(e.g., `rust_2021_compatibility`) automatically generated for any lints signaling
future-incompatible code that will break in the specified edition.

### Linting early in the compiler

On occasion, you may need to define a lint that runs before the linting system
has been initialized (e.g. during parsing or macro expansion). This is
problematic because we need to have computed lint levels to know whether we
should emit a warning or an error or nothing at all.

To solve this problem, we buffer the lints until the linting system is processed.
[`Session`][sessbl] and [`ParseSess`][parsebl] both have
`buffer_lint` methods that allow you to buffer a lint for later.
The linting system automatically takes care of handling buffered lints later.

[sessbl]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html#method.buffer_lint
[parsebl]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.ParseSess.html#method.buffer_lint

Thus, to define a lint that runs early in the compilation,
one defines a lint like normal but invokes the lint with `buffer_lint`.

#### Linting even earlier in the compiler

The parser (`rustc_ast`) is interesting in that it cannot have dependencies on
any of the other `rustc*` crates.
In particular, it cannot depend on `rustc_middle::lint` or `rustc_lint`,
where all of the compiler linting infrastructure is defined.
That's troublesome!

To solve this, `rustc_ast` defines its own buffered lint type, which `ParseSess::buffer_lint` uses.
After macro expansion, these buffered lints are
then dumped into the `Session::buffered_lints` used by the rest of the compiler.

## JSON diagnostic output

The compiler accepts an `--error-format json` flag to output
diagnostics as JSON objects (for the benefit of tools such as `cargo fix`).
It looks like this:

```console
$ rustc json_error_demo.rs --error-format json
{"message":"cannot add `&str` to `{integer}`","code":{"code":"E0277","explanation":"\nYou tried to use a type which doesn't implement some trait in a place which\nexpected that trait. Erroneous code example:\n\n```compile_fail,E0277\n// here we declare the Foo trait with a bar method\ntrait Foo {\n    fn bar(&self);\n}\n\n// we now declare a function which takes an object implementing the Foo trait\nfn some_func<T: Foo>(foo: T) {\n    foo.bar();\n}\n\nfn main() {\n    // we now call the method with the i32 type, which doesn't implement\n    // the Foo trait\n    some_func(5i32); // error: the trait bound `i32 : Foo` is not satisfied\n}\n```\n\nIn order to fix this error, verify that the type you're using does implement\nthe trait. Example:\n\n```\ntrait Foo {\n    fn bar(&self);\n}\n\nfn some_func<T: Foo>(foo: T) {\n    foo.bar(); // we can now use this method since i32 implements the\n               // Foo trait\n}\n\n// we implement the trait on the i32 type\nimpl Foo for i32 {\n    fn bar(&self) {}\n}\n\nfn main() {\n    some_func(5i32); // ok!\n}\n```\n\nOr in a generic context, an erroneous code example would look like:\n\n```compile_fail,E0277\nfn some_func<T>(foo: T) {\n    println!(\"{:?}\", foo); // error: the trait `core::fmt::Debug` is not\n                           //        implemented for the type `T`\n}\n\nfn main() {\n    // We now call the method with the i32 type,\n    // which *does* implement the Debug trait.\n    some_func(5i32);\n}\n```\n\nNote that the error here is in the definition of the generic function: Although\nwe only call it with a parameter that does implement `Debug`, the compiler\nstill rejects the function: It must work with all possible input types. In\norder to make this example compile, we need to restrict the generic type we're\naccepting:\n\n```\nuse std::fmt;\n\n// Restrict the input type to types that implement Debug.\nfn some_func<T: fmt::Debug>(foo: T) {\n    println!(\"{:?}\", foo);\n}\n\nfn main() {\n    // Calling the method is still fine, as i32 implements Debug.\n    some_func(5i32);\n\n    // This would fail to compile now:\n    // struct WithoutDebug;\n    // some_func(WithoutDebug);\n}\n```\n\nRust only looks at the signature of the called function, as such it must\nalready specify all requirements that will be used for every type parameter.\n"},"level":"error","spans":[{"file_name":"json_error_demo.rs","byte_start":50,"byte_end":51,"line_start":4,"line_end":4,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    a + b","highlight_start":7,"highlight_end":8}],"label":"no implementation for `{integer} + &str`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the trait `std::ops::Add<&str>` is not implemented for `{integer}`","code":null,"level":"help","spans":[],"children":[],"rendered":null}],"rendered":"error[E0277]: cannot add `&str` to `{integer}`\n --> json_error_demo.rs:4:7\n  |\n4 |     a + b\n  |       ^ no implementation for `{integer} + &str`\n  |\n  = help: the trait `std::ops::Add<&str>` is not implemented for `{integer}`\n\n"}
{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error\n\n"}
{"message":"For more information about this error, try `rustc --explain E0277`.","code":null,"level":"","spans":[],"children":[],"rendered":"For more information about this error, try `rustc --explain E0277`.\n"}
```

Note that the output is a series of lines, each of which is a JSON object,
but the series of lines taken together is, unfortunately, not
valid JSON, thwarting tools and tricks (such as [piping to `python3 -m
json.tool`](https://docs.python.org/3/library/json.html#module-json.tool)) that require such.
(One speculates that this was intentional for LSP performance purposes,
so that each line/object can be sent as it is flushed?)

Also note the "rendered" field, which contains the "human" output as a
string; this was introduced so that UI tests could both make use of
the structured JSON and see the "human" output (well,
_sans_ colors) without having to compile everything twice.

The "human" readable and the json format emitter can be found under `rustc_errors`,
both were moved from the `rustc_ast` crate to the
[rustc_errors crate](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html).

The JSON emitter defines [its own `Diagnostic`
struct](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/json/struct.Diagnostic.html)
(and sub-structs) for the JSON serialization.
Don't confuse this with
[`errors::Diag`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html)!

## Diagnostic attributes

There are many attributes that can be used to generate or improve error messages:
- `diagnostic::on_unimplemented` and [`rustc_on_unimplemented`]: customize unimplemented trait errors
- `diagnostic::on_move`: customize borrowcheck errors 
- `diagnostic::on_unknown`: customize unresolved imports errors
- `diagnostic::on_unmatched_args`: customize macro matcher errors
- `diagnostic::opaque`: stop the internals of macros from showing up in error messages
- `diagnostic::on_const`: customize non-const trait impl errors
- `rustc_as_ptr`: used by the `dangling_pointers_from_temporaries` lint.
- `rustc_never_returns_null_ptr`: used by the `useless_ptr_null_checks` lint.
- `rustc_no_implicit_autorefs`: used for the `dangerous_implicit_autorefs` lint.

If possible, consider improving or implementing such an attribute rather than adding custom error
reporting code.

[`rustc_on_unimplemented`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_ir/attribute.rustc_on_unimplemented.html
[diag]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html

---

### Src Doc Rustc Dev Guide Src Early Late Parameters (`src/doc/rustc-dev-guide/src/early-late-parameters.md`)

# Early vs Late bound parameters

> **NOTE**: This chapter largely talks about early/late bound as being solely relevant when discussing function item types/function definitions. This is potentially not completely true, async blocks and closures should likely be discussed somewhat in this chapter.

See also these blog posts from when the distinction between early and late bound parameters was
introduced: [Intermingled parameter lists] and [Intermingled parameter lists, take 2].

[Intermingled parameter lists]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
[Intermingled parameter lists, take 2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/

## What does it mean to be "early" bound or "late" bound

Every function definition has a corresponding ZST that implements the `Fn*` traits known as a [function item type][function_item_type].
This part of the chapter will talk a little bit about the "desugaring" of function item types as it is useful context for explaining the difference between early bound and late bound generic parameters.

Let's start with a very trivial example involving no generic parameters:

```rust
fn foo(a: String) -> u8 {
    # 1
    /* snip */
}
```

If we explicitly wrote out the definitions for the function item type corresponding to `foo` and its associated `Fn` impl it would look something like this:
```rust,ignore
struct FooFnItem;

impl Fn<(String,)> for FooFnItem {
    type Output = u8;
    /* fn call(&self, ...) -> ... { ... } */
}
```

The builtin impls for the `FnMut`/`FnOnce` traits as well as the impls for `Copy` and `Clone` were omitted for brevity reasons (although these traits *are* implemented for function item types).

A slightly more complicated example would involve introducing generic parameters to the function:
```rust
fn foo<T: Sized>(a: T) -> T {
    # a
    /* snip */
}
```
Writing out the definitions would look something like this:
```rust,ignore
struct FooFnItem<T: Sized>(PhantomData<fn(T) -> T>);

impl<T: Sized> Fn<(T,)> for FooFnItem<T> {
    type Output = T;
    /* fn call(&self, ...) -> ... { ... } */
}
```

Note that the function item type `FooFnItem` is generic over some type parameter `T` as defined on the function `foo`.
However, not all generic parameters defined on functions are also defined on the function item type as demonstrated here:
```rust
fn foo<'a, T: Sized>(a: &'a T) -> &'a T {
    # a
    /* snip */
}
```
With its "desugared" form looking like so:
```rust,ignore
struct FooFnItem<T: Sized>(PhantomData<for<'a> fn(&'a T) -> &'a T>);

impl<'a, T: Sized> Fn<(&'a T,)> for FooFnItem<T> {
    type Output = &'a T;
    /* fn call(&self, ...) -> ... { ... } */
}
```

The lifetime parameter `'a` from the function `foo` is not present on the function item type `FooFnItem` and is instead introduced on the builtin impl solely for use in representing the argument types.

Generic parameters not all being defined on the function item type means that there are two steps where generic arguments are provided when calling a function.
1. Naming the function (e.g. `let a = foo;`) the arguments for `FooFnItem` are provided.
2. Calling the function (e.g. `a(&10);`) any parameters defined on the builtin impl are provided.

This two-step system is where the early vs late naming scheme comes from, early bound parameters are provided in the *earliest* step (naming the function), whereas late bound parameters are provided in the *latest* step (calling the function).

Looking at the desugaring from the previous example we can tell that `T` is an early bound type parameter and `'a` is a late bound lifetime parameter as `T` is present on the function item type but `'a` is not.
See this example of calling `foo` annotated with where each generic parameter has an argument provided:
```rust
fn foo<'a, T: Sized>(a: &'a T) -> &'a T {
    # a
    /* snip */
}

// Here we provide a type argument `String` to the
// type parameter `T` on the function item type
let my_func = foo::<String>;

// Here (implicitly) a lifetime argument is provided
// to the lifetime parameter `'a` on the builtin impl.
my_func(&String::new());
```

[function_item_type]: https://doc.rust-lang.org/reference/types/function-item.html

## Differences between early and late bound parameters

### Higher ranked function pointers and trait bounds

A generic parameter being late bound allows for more flexible usage of the function item.
For example, if we have some function `foo` with an early bound lifetime parameter and some function `bar` with a late bound lifetime parameter `'a`, we would have the following builtin `Fn` impls:
```rust,ignore
impl<'a> Fn<(&'a String,)> for FooFnItem<'a> { /* ... */ }
impl<'a> Fn<(&'a String,)> for BarFnItem { /* ... */ }
```

The `bar` function has a strictly more flexible signature as the function item type can be called with a borrow with *any* lifetime, whereas the `foo` function item type would only be callable with a borrow with the same lifetime on the function item type.
We can show this by simply trying to call `foo`'s function item type multiple times with different lifetimes:

```rust
// The `'a: 'a` bound forces this lifetime to be early bound.
fn foo<'a: 'a>(b: &'a String) -> &'a String { b }
fn bar<'a>(b: &'a String) -> &'a String { b }

// Early bound generic parameters are instantiated here when naming
// the function `foo`. As `'a` is early bound an argument is provided.
let f = foo::<'_>;

// Both function arguments are required to have the same lifetime as
// the lifetime parameter being early bound means that `f` is only
// callable for one specific lifetime.
//
// As we call this with borrows of different lifetimes, the borrow checker
// will error here.
f(&String::new());
f(&String::new());
```

The lifetime parameter on `foo` being early bound requires all callers of `f` to provide a borrow with the same lifetime.
In this example, we call `foo`'s function item type twice, each time with a borrow of a temporary.
These two borrows could not possibly have lifetimes that overlap as the temporaries are only alive during the function call, not after, so we get a compilation error.

If the lifetime parameter on `foo` was late bound, this would be able to compile as each caller could provide a different lifetime argument for its borrow.
See the following example, which demonstrates this using the `bar` function defined above:

```rust
# fn foo<'a: 'a>(b: &'a String) -> &'a String { b }
# fn bar<'a>(b: &'a String) -> &'a String { b }
#
// Early bound parameters are instantiated here, however as `'a` is
// late bound it is not provided here.
let b = bar;

// Late bound parameters are instantiated separately at each call site
// allowing different lifetimes to be used by each caller.
b(&String::new());
b(&String::new());
```

This is reflected in the ability to coerce function item types to higher ranked function pointers and prove higher ranked `Fn` trait bounds.
We can demonstrate this with the following example:
```rust
// The `'a: 'a` bound forces this lifetime to be early bound.
fn foo<'a: 'a>(b: &'a String) -> &'a String { b }
fn bar<'a>(b: &'a String) -> &'a String { b }

fn accepts_hr_fn(_: impl for<'a> Fn(&'a String) -> &'a String) {}

fn higher_ranked_trait_bound() {
    let bar_fn_item = bar;
    accepts_hr_fn(bar_fn_item);

    let foo_fn_item = foo::<'_>;
    // errors
    accepts_hr_fn(foo_fn_item);
}

fn higher_ranked_fn_ptr() {
    let bar_fn_item = bar;
    let fn_ptr: for<'a> fn(&'a String) -> &'a String = bar_fn_item;

    let foo_fn_item = foo::<'_>;
    // errors
    let fn_ptr: for<'a> fn(&'a String) -> &'a String = foo_fn_item;
}
```

In both of these cases, the borrow checker errors as it does not consider `foo_fn_item` to be callable with a borrow of any lifetime.
This is due to the fact that the lifetime parameter on `foo` is early bound, causing `foo_fn_item` to have a type of `FooFnItem<'_>` which (as demonstrated by the desugared `Fn` impl) is only callable with a borrow of the same lifetime `'_`.

### Turbofishing in the presence of late bound parameters

As mentioned previously, the distinction between early and late bound parameters means that there are two places where generic parameters are instantiated:
- When naming a function (early)
- When calling a function (late)

There is currently no syntax for explicitly specifying generic arguments for late bound parameters during the call step; generic arguments can only be specified for early bound parameters when naming a function.
The syntax `foo::<'static>();`, despite being part of a function call, behaves as `(foo::<'static>)();` and instantiates the early bound generic parameters on the function item type.

See the following example:
```rust
fn foo<'a>(b: &'a u32) -> &'a u32 { b }

let f /* : FooFnItem<????> */ = foo::<'static>;
```

The above example errors as the lifetime parameter `'a` is late bound and so cannot be instantiated as part of the "naming a function" step.
If we make the lifetime parameter early bound we will see this code start to compile:
```rust
fn foo<'a: 'a>(b: &'a u32) -> &'a u32 { b }

let f /* : FooFnItem<'static> */ = foo::<'static>;
```

What the current implementation of the compiler aims to do is error when specifying lifetime arguments to a function that has both early *and* late bound lifetime parameters.
In practice, due to excessive breakage, some cases are actually only future compatibility warnings ([#42868](https://github.com/rust-lang/rust/issues/42868)):
- When the amount of lifetime arguments is the same as the number of early bound lifetime parameters, a FCW is emitted instead of an error
- An error is always downgraded to a FCW when using method call syntax

To demonstrate this we can write out the different kinds of functions and give them both a late and early bound lifetime:
```rust,ignore
fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}

struct Foo;

trait Trait: Sized {
    fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ());
    fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ());
}

impl Trait for Foo {
    fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
    fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
}

impl Foo {
    fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
    fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
}
```

Then, for the first case, we can call each function with a single lifetime argument (corresponding to the one early bound lifetime parameter) and note that it only results in a FCW rather than a hard error.
```rust
#![deny(late_bound_lifetime_arguments)]

# fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
#
# struct Foo;
#
# trait Trait: Sized {
#     fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ());
#     fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ());
# }
#
# impl Trait for Foo {
#     fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
#     fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
# }
#
# impl Foo {
#     fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
#     fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
# }
#
// Specifying as many arguments as there are early
// bound parameters is always a future compat warning
Foo.trait_method::<'static>(&(), &());
Foo::trait_method::<'static>(Foo, &(), &());
Foo::trait_function::<'static>(&(), &());
Foo.inherent_method::<'static>(&(), &());
Foo::inherent_function::<'static>(&(), &());
free_function::<'static>(&(), &());
```

For the second case we call each function with more lifetime arguments than there are lifetime parameters (be it early or late bound) and note that method calls result in a FCW as opposed to the free/associated functions which result in a hard error:
```rust
# fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
#
# struct Foo;
#
# trait Trait: Sized {
#     fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ());
#     fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ());
# }
#
# impl Trait for Foo {
#     fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
#     fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
# }
#
# impl Foo {
#     fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
#     fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
# }
#
// Specifying more arguments than there are early
// bound parameters is a future compat warning when
// using method call syntax.
Foo.trait_method::<'static, 'static, 'static>(&(), &());
Foo.inherent_method::<'static, 'static, 'static>(&(), &());
// However, it is a hard error when not using method call syntax.
Foo::trait_method::<'static, 'static, 'static>(Foo, &(), &());
Foo::trait_function::<'static, 'static, 'static>(&(), &());
Foo::inherent_function::<'static, 'static, 'static>(&(), &());
free_function::<'static, 'static, 'static>(&(), &());
```

Even when specifying enough lifetime arguments for both the late and early bound lifetime parameter, these arguments are not actually used to annotate the lifetime provided to late bound parameters.
We can demonstrate this by turbofishing `'static` to a function while providing a non-static borrow:
```rust
struct Foo;

impl Foo {
    fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b String ) {}
}

Foo.inherent_method::<'static, 'static>(&(), &String::new());
```

This compiles even though the `&String::new()` function argument does not have a `'static` lifetime, this is because "extra" lifetime arguments are discarded rather than taken into account for late bound parameters when actually calling the function.

### Liveness of types with late bound parameters

When checking type outlives bounds involving function item types we take into account early bound parameters.
For example:

```rust
fn foo<T>(_: T) {}

fn requires_static<T: 'static>(_: T) {}

fn bar<T>() {
    let f /* : FooFnItem<T> */ = foo::<T>;
    requires_static(f);
}
```

As the type parameter `T` is early bound, the desugaring of the function item type for `foo` would look something like `struct FooFnItem<T>`.
Then, in order for `FooFnItem<T>: 'static` to hold, we must also require `T: 'static` to hold as otherwise we would wind up with soundness bugs.

Unfortunately, due to bugs in the compiler, we do not take into account early bound *lifetimes*, which is the cause of the open soundness bug [#84366](https://github.com/rust-lang/rust/issues/84366).
This means that it's impossible to demonstrate a "difference" between early/late bound parameters for liveness/type outlives bounds as the only kind of generic parameters that are able to be late bound are lifetimes which are handled incorrectly.

Regardless, in theory the code example below *should* demonstrate such a difference once [#84366](https://github.com/rust-lang/rust/issues/84366) is fixed:
```rust
fn early_bound<'a: 'a>(_: &'a String) {}
fn late_bound<'a>(_: &'a String) {}

fn requires_static<T: 'static>(_: T) {}

fn bar<'b>() {
    let e = early_bound::<'b>;
    // this *should* error but does not
    requires_static(e);

    let l = late_bound;
    // this correctly does not error
    requires_static(l);
}
```

## Requirements for a parameter to be late bound

### Must be a lifetime parameter

Type and Const parameters are not able to be late bound as we do not have a way to support types such as `dyn for<T> Fn(Box<T>)` or `for<T> fn(Box<T>)`.
Calling such types requires being able to monomorphize the underlying function which is not possible with indirection through dynamic dispatch.

### Must not be used in a where clause

Currently when a generic parameter is used in a where clause it must be early bound.
For example:
```rust
# trait Trait<'a> {}
fn foo<'a, T: Trait<'a>>(_: &'a String, _: T) {}
```

In this example the lifetime parameter `'a` is considered to be early bound as it appears in the where clause `T: Trait<'a>`.
This is true even for "trivial" where clauses such as `'a: 'a` or those implied by wellformedness of function arguments, for example:
```rust
fn foo<'a: 'a>(_: &'a String) {}
fn bar<'a, T: 'a>(_: &'a T) {}
```

In both of these functions the lifetime parameter `'a` would be considered to be early bound even though the where clauses they are used in arguably do not actually impose any constraints on the caller.

The reason for this restriction is a combination of two things:
- We cannot prove bounds on late bound parameters until they have been instantiated
- Function pointers and trait objects do not have a way to represent yet to be proven where clauses from the underlying function

Take the following example:
```rust
trait Trait<'a> {}
fn foo<'a, T: Trait<'a>>(_: &'a T) {}

let f = foo::<String>;
let f = f as for<'a> fn(&'a String);
f(&String::new());
```

At *some point* during type checking an error should be emitted for this code as `String` does not implement `Trait` for any lifetime.

If the lifetime `'a` were late bound then this becomes difficult to check.
When naming `foo` we do not know what lifetime should be used as part of the `T: Trait<'a>` trait bound as it has not yet been instantiated.
When coercing the function item type to a function pointer we have no way of tracking the `String: Trait<'a>` trait bound that must be proven when calling the function.

If the lifetime `'a` is early bound (which it is in the current implementation in rustc), then the trait bound can be checked when naming the function `foo`.
Requiring parameters used in where clauses to be early bound gives a natural place to check where clauses defined on the function.

Finally, we do not require lifetimes to be early bound if they are used in *implied bounds*, for example:
```rust
fn foo<'a, T>(_: &'a T) {}

let f = foo;
f(&String::new());
f(&String::new());
```

This code compiles, demonstrating that the lifetime parameter is late bound, even though `'a` is used in the type `&'a T` which implicitly requires `T: 'a` to hold.
Implied bounds can be treated specially as any types introducing implied bounds are in the signature of the function pointer type, which means that when calling the function we know to prove `T: 'a`.

### Must be constrained by argument types

It is important that builtin impls on function item types do not wind up with unconstrained generic parameters as this can lead to unsoundness.
This is the same kind of restriction as applies to user written impls, for example the following code results in an error:
```rust
trait Trait {
    type Assoc;
}

impl<'a> Trait for u8 {
    type Assoc = &'a String;
}
```

The analogous example for builtin impls on function items would be the following:
```rust,ignore
fn foo<'a>() -> &'a String { /* ... */ }
```
If the lifetime parameter `'a` were to be late bound we would wind up with a builtin impl with an unconstrained lifetime, we can manually write out the desugaring for the function item type and its impls with `'a` being late bound to demonstrate this:
```rust,ignore
// NOTE: this is just for demonstration, in practice `'a` is early bound
struct FooFnItem;

impl<'a> Fn<()> for FooFnItem {
    type Output = &'a String;
    /* fn call(...) -> ... { ... } */
}
```

In order to avoid such a situation we consider `'a` to be early bound which causes the lifetime on the impl to be constrained by the self type:
```rust,ignore
struct FooFnItem<'a>(PhantomData<fn() -> &'a String>);

impl<'a> Fn<()> for FooFnItem<'a> {
    type Output = &'a String;
    /* fn call(...) -> ... { ... } */
}
```

---

### Src Doc Rustc Dev Guide Src Effects (`src/doc/rustc-dev-guide/src/effects.md`)

# Effects, const traits, and const condition checking

## The `HostEffect` predicate

[`HostEffectPredicate`]s are a kind of predicate from `[const] Tr` or `const Tr` bounds.
It has a trait reference,
and a `constness` which could be `Maybe` or `Const`, depending on the bound.
Because `[const] Tr`, or rather `Maybe` bounds
apply differently based on whichever contexts they are in,
they have different behavior than normal bounds.
Where normal trait bounds on a function such as
`T: Tr` are collected within the [`clauses_of`] query to be proven when a
function is called and to be assumed within the function,
bounds such as `T: [const] Tr` will behave as a normal trait bound and add `T: Tr` to the result
from `clauses_of`, but also adds a `HostEffectPredicate` to the [`const_conditions`] query.

On the other hand, `T: const Tr` bounds do not change meaning across contexts,
therefore they will result in `HostEffect(T: Tr, const)` being added to `clauses_of`,
and not `const_conditions`.

[`HostEffectPredicate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/predicate/struct.HostEffectPredicate.html
[`clauses_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.clauses_of
[`const_conditions`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.const_conditions

## The `const_conditions` query

`clauses_of` represents a set of clauses that need to be proven to use an item.
For example, to use `foo` in the example below:

```rust
fn foo<T>() where T: Default {}
```

We must be able to prove that `T` implements `Default`.
In a similar vein,
`const_conditions` represents a set of predicates that need to be proven to use
an item *in const contexts*.
If we adjust the example above to use `const` trait bounds:

```rust
const fn foo<T>() where T: [const] Default {}
```

Then `foo` would get a `HostEffect(T: Default, maybe)` in the `const_conditions` query,
suggesting that in order to call `foo` from const contexts, one must
prove that `T` has a const implementation of `Default`.

## Enforcement of `const_conditions`

`const_conditions` are currently checked in various places.

Every call in HIR from a const context (which includes `const fn` and `const`
items) will check that `const_conditions` of the function we are calling hold.
This is done in [`FnCtxt::enforce_context_effects`].
Note that we don't check if the function is only referred to but not called,
as the following code needs to compile:

```rust
const fn hi<T: [const] Default>() -> T {
    T::default()
}
const X: fn() -> u32 = hi::<u32>;
```

For a trait `impl` to be well-formed,
we must be able to prove the `const_conditions` of the trait from the `impl`'s environment.
This is checked in [`wfcheck::check_impl`].

Here's an example:

```rust
const trait Bar {}
const trait Foo: [const] Bar {}
// `const_conditions` contains `HostEffect(Self: Bar, maybe)`

impl const Bar for () {}
impl const Foo for () {}
// ^ here we check `const_conditions` for the impl to be well-formed
```

Methods of trait impls must not have stricter bounds than the method of the
trait that they are implementing.
To check that the methods are compatible,
a hybrid environment is constructed with the predicates of the `impl` plus the
predicates of the trait method, and we attempt to prove the predicates of the impl method.
We do the same for `const_conditions`:

```rust
const trait Foo {
    fn hi<T: [const] Default>();
}

impl<T: [const] Clone> Foo for Vec<T> {
    fn hi<T: [const] PartialEq>();
    // ^ we can't prove `T: [const] PartialEq` given `T: [const] Clone` and
    // `T: [const] Default`, therefore we know that the method on the impl
    // is stricter than the method on the trait.
}
```

These checks are done in [`compare_method_clause_entailment`].
A similar function that does the same check for associated types is called
[`compare_type_clause_entailment`].
Both of these need to consider `const_conditions` when in const contexts.

In MIR, as part of const checking, `const_conditions` of items that are called
are revalidated again in [`Checker::revalidate_conditional_constness`].

[`compare_method_clause_entailment`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_clause_entailment.html
[`compare_type_clause_entailment`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_type_clause_entailment.html
[`FnCtxt::enforce_context_effects`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#method.enforce_context_effects
[`wfcheck::check_impl`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/wfcheck/fn.check_impl.html
[`Checker::revalidate_conditional_constness`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/check_consts/check/struct.Checker.html#method.revalidate_conditional_constness

## `explicit_implied_const_bounds` on associated types and traits

Bounds on associated types, opaque types,
and supertraits such as the following have their bounds represented differently:

```rust
trait Foo: [const] PartialEq {
    type X: [const] PartialEq;
}

fn foo() -> impl [const] PartialEq {
    // ^ unimplemented syntax
}
```

Unlike `const_conditions`, which need to be proved for callers,
and can be assumed inside the definition (e.g. trait
bounds on functions), these bounds need to be proved at definition (at the impl,
or when returning the opaque) but can be assumed for callers.
The non-const equivalent of these bounds are called [`explicit_item_bounds`].

These bounds are checked in [`compare_impl_item::check_type_bounds`] for HIR typeck,
[`evaluate_host_effect_from_item_bounds`] in the old solver and
[`consider_additional_alias_assumptions`] in the new solver.

[`explicit_item_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.explicit_item_bounds
[`compare_impl_item::check_type_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.check_type_bounds.html
[`evaluate_host_effect_from_item_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/effects/fn.evaluate_host_effect_from_item_bounds.html
[`consider_additional_alias_assumptions`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/assembly/trait.GoalKind.html#tymethod.consider_additional_alias_assumptions

## Proving `HostEffectPredicate`s

`HostEffectPredicate`s are implemented both in the [old solver] and the [new trait solver].
In general, we can prove a `HostEffect` predicate when either of these conditions are met:

* The predicate can be assumed from caller bounds;
* The type has a `const` `impl` for the trait, *and* that const conditions on the impl holds,
  *and* that the `explicit_implied_const_bounds` on the trait holds; or
* The type has a built-in implementation for the trait in const contexts.
  For example, `Fn` may be implemented by function items if their const conditions are satisfied,
  or `Destruct` is implemented in const contexts if the type can
  be dropped at compile time.

[old solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_trait_selection/traits/effects.rs.html
[new trait solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_next_trait_solver/solve/effect_goals.rs.html

## More on const traits

To be expanded later.

### The `#[rustc_non_const_trait_method]` attribute

This is intended for internal (standard library) usage only.
With this attribute applied to a trait method,
the compiler will not check the default body of this method for ability to run in compile time.
Users of the trait will also not be allowed to use this trait method in const contexts.
This attribute is primarily
used for constifying large traits such as `Iterator` without having to make all
its methods `const` at the same time.

This attribute should not be present while stabilizing the trait as `const`.

---

### Src Doc Rustc Dev Guide Src External Repos (`src/doc/rustc-dev-guide/src/external-repos.md`)

# Using external repositories

The `rust-lang/rust` git repository depends on several other repos in the `rust-lang` organization.
There are three main ways we use dependencies:
1. As a Cargo dependency through crates.io (e.g. `rustc-rayon`)
2. As a git (e.g. `clippy`) or a [josh] (e.g. `miri`) subtree
3. As a git submodule (e.g. `cargo`)

As a general rule:
- Use crates.io for libraries that could be useful for others in the ecosystem
- Use subtrees for tools that depend on compiler internals and need to be updated if there are breaking
  changes
- Use submodules for tools that are independent of the compiler

## External dependencies (subtrees)

The following external projects are managed using some form of a `subtree`:

* [clippy](https://github.com/rust-lang/rust-clippy)
* [miri](https://github.com/rust-lang/miri)
* [portable-simd](https://github.com/rust-lang/portable-simd)
* [rustfmt](https://github.com/rust-lang/rustfmt)
* [rust-analyzer](https://github.com/rust-lang/rust-analyzer)
* [rustc_codegen_cranelift](https://github.com/rust-lang/rustc_codegen_cranelift)
* [rustc_codegen_gcc](https://github.com/rust-lang/rustc_codegen_gcc)
* [rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide)
* [compiler-builtins](https://github.com/rust-lang/compiler-builtins)
* [stdarch](https://github.com/rust-lang/stdarch)

In contrast to `submodule` dependencies (see below for those),
the `subtree` dependencies are just regular files and directories which can be updated in-tree.
However, if possible, enhancements, bug fixes, etc. specific
to these tools should be filed against the tools directly in their respective upstream repositories.
The exception is that when rustc changes are required to implement a new tool feature or test,
that should happen in one collective rustc PR.

Similarly, if your rustc changes break the build of some subtree dependency,
you should include fixes for those in the rustc PR as well.

`subtree` dependencies are currently managed by two distinct approaches:

* Using `git subtree`
    * `clippy` ([sync guide](https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html#performing-the-sync-from-rust-langrust-to-clippy))
    * `portable-simd` ([sync script](https://github.com/rust-lang/portable-simd/blob/master/subtree-sync.sh))
    * `rustc_codegen_gcc` ([sync guide](https://github.com/rust-lang/rustc_codegen_gcc/blob/master/doc/subtree.md))
* Using the [josh](#synchronizing-a-josh-subtree) tool
    * `miri`
    * `rust-analyzer`
    * `rustc_codegen_cranelift`
    * `rustc-dev-guide`
    * `rustfmt`
    * `compiler-builtins`
    * `stdarch`

### Josh subtrees

The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories.
Specific tooling is required to work with josh.
We provide a helper tool, [`rustc-josh-sync`][josh-sync], to help with the synchronization, described [below](#synchronizing-a-josh-subtree).

### Synchronizing a Josh subtree

We use a dedicated tool called [`rustc-josh-sync`][josh-sync] for performing Josh subtree updates.
The commands below can be used for all our Josh subtrees, although note that `miri`
requires you to perform some [additional steps](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo) during pulls.

You can install the tool using the following command:
```
cargo install --locked --git https://github.com/rust-lang/josh-sync
```

Both pulls (synchronize changes from rust-lang/rust into the subtree) and pushes (synchronize
changes from the subtree to rust-lang/rust) are performed from the subtree repository (so first
switch to its repository checkout directory in your terminal).

#### Performing pull
1. Checkout a new branch that will be used to create a PR into the subtree
2. Run the pull command
    ```
    rustc-josh-sync pull
    ```
3. Push the branch to your fork and create a PR into the subtree repository
    - If you have `gh` CLI installed, `rustc-josh-sync` can create the PR for you.

#### Performing push

> NOTE:
> Before you proceed, look at some guidance related to Git [on josh-sync README].

1. Run the push command to create a branch named `<branch-name>` in a `rustc` fork under the `<gh-username>` account
    ```
    rustc-josh-sync push <branch-name> <gh-username>
    ```
2. Create a PR from `<branch-name>` into `rust-lang/rust`

### Creating a new Josh subtree dependency

If you want to migrate a repository dependency from `git subtree` or `git submodule` to josh, you can check out [this guide](https://hackmd.io/7pOuxnkdQDaL1Y1FQr65xg).

### Synchronizing a git subtree

Periodically the changes made to subtree based dependencies need to be synchronized between this
repository and the upstream tool repositories.

Subtree synchronizations are typically handled by the respective tool maintainers.
Other users are welcome to submit synchronization PRs.
However, in order to do so,
you will need to modify your local git installation and follow a very precise set of instructions.
These instructions are documented, along with several useful tips and tricks,
in the [syncing subtree changes][clippy-sync-docs] section in Clippy's Contributing guide.
The instructions are applicable for use with any subtree-based tool;
just be sure to use the correct corresponding subtree directory and remote repository.

The synchronization process goes in two directions: `subtree push` and `subtree pull`.

A `subtree push` takes all the changes that happened to the copy in this repo and creates commits
on the remote repo that match the local changes.
Every local commit that touched the subtree causes a commit on the remote repo,
but is modified to move the files from the specified directory to the tool repo root.

A `subtree pull` takes all changes since the last `subtree pull`
from the tool repo and adds these commits to the rustc repo along with a merge commit that moves
the tool changes into the specified directory in the Rust repository.

It is recommended that you always do a push first and get that merged to the default branch of the tool.
Then, when you do a pull, the merge works without conflicts.
While it's definitely possible to resolve conflicts during a pull, you may have to redo the conflict
resolution if your PR doesn't get merged fast enough and there are new conflicts.
Do not try to
rebase the result of a `git subtree pull`; rebasing merge commits is a bad idea in general.

You always need to specify the `-P` prefix to the subtree directory and the corresponding remote
repository.
If you specify the wrong directory or repository
you'll get very fun merges that try to push the wrong directory to the wrong remote repository.
Luckily you can just abort this without any consequences by throwing away either the pulled commits
in rustc or the pushed branch on the remote and try again.
It is usually fairly obvious
that this is happening because you suddenly get thousands of commits that want to be synchronized.

[clippy-sync-docs]: https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html

### Creating a new subtree dependency

If you want to create a new subtree dependency from an existing repository,
call (from this repository's root directory!)

```
git subtree add -P src/tools/clippy https://github.com/rust-lang/rust-clippy.git master
```

This will create a new commit, which you may not rebase under any circumstances!
Delete the commit and redo the operation if you need to rebase.

Now you're done;
the `src/tools/clippy` directory behaves as if Clippy were part of the rustc monorepo,
so no one but you (or others that synchronize subtrees) actually needs to use `git subtree`.

## External dependencies (submodules)

Building Rust will also use external git repositories tracked using [git submodules].
The complete list may be found in the [`.gitmodules`] file.
Some of these projects are required (like `stdarch` for the standard library) and
some of them are optional (like `src/doc/book`).

Usage of submodules is discussed more in the [Using Git chapter](git.md#git-submodules).

Some of the submodules are allowed to be in a "broken" state where they
either don't build or their tests don't pass, e.g. the documentation books
like [The Rust Reference].
Maintainers of these projects will be notified when the project is in a broken state,
and they should fix them as soon as possible.
The current status is tracked on the [toolstate website].
More information may be found on the Forge [Toolstate chapter].
In practice, it is very rare for documentation to have broken toolstate.

Breakage is not allowed in the beta and stable channels,
and must be addressed before the PR is merged.
They are also not allowed to be broken on `main` in the week leading up to the beta cut.

[git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules
[`.gitmodules`]: https://github.com/rust-lang/rust/blob/HEAD/.gitmodules
[The Rust Reference]: https://github.com/rust-lang/reference/
[toolstate website]: https://rust-lang-nursery.github.io/rust-toolstate/
[Toolstate chapter]: https://forge.rust-lang.org/infra/toolstate.html
[josh]: https://josh-project.github.io/josh/intro.html
[josh-sync]: https://github.com/rust-lang/josh-sync
[on josh-sync README]: https://github.com/rust-lang/josh-sync#git-peculiarities

---

### Src Doc Rustc Dev Guide Src Feature Gate Check (`src/doc/rustc-dev-guide/src/feature-gate-check.md`)

# Feature Gate Checking

For the how-to steps to add, remove, rename, or stabilize feature gates,
see [Feature gates][feature-gates].

Feature gates prevent usage of unstable language and library features without a
nightly-only `#![feature(...)]` opt-in.
This chapter documents the implementation
of feature gating: where gates are defined, how they are enabled, and how usage is verified.



## Feature Definitions

All feature gate definitions are located in the `rustc_feature` crate:

- **Unstable features** are declared in [`rustc_feature/src/unstable.rs`] via
  the `declare_features!` macro.
  This associates features with issue numbers and tracking metadata.
- **Accepted features** (stabilized) are listed in [`rustc_feature/src/accepted.rs`].
- **Removed features** (explicitly disallowed) are listed in [`rustc_feature/src/removed.rs`].
- **Gated built-in attributes and cfgs** are declared in [`rustc_feature/src/builtin_attrs.rs`].

The [`rustc_feature::Features`] type represents the **active feature set** for a crate.
Helpers like `enabled`, `incomplete`, and `internal` are used during compilation to check status.

## Collecting Features

Before AST validation or expansion, `rustc` collects crate-level
`#![feature(...)]` attributes to build the active `Features` set.

- The collection happens in [`rustc_expand/src/config.rs`] in [`features`].
- Each `#![feature]` entry is classified against the `unstable`, `accepted`, and `removed` tables:
  - **Removed** features cause an immediate error.
  - **Accepted** features are recorded but do not require nightly.
    On stable/beta, `maybe_stage_features` in
    [`rustc_ast_passes/src/feature_gate.rs`] emits the non-nightly
    diagnostic and lists stable features, which is where the "already
    stabilized" messaging comes from.
  - **Unstable** features are recorded as enabled.
  - Unknown features are treated as **library features** and validated later.
- With `-Z allow-features=...`, any **unstable** or **unknown** feature
  not in the allowlist is rejected.
- [`RUSTC_BOOTSTRAP`] feeds into `UnstableFeatures::from_environment`.
  This variable controls whether the compiler is treated as "nightly", allowing
  feature gates to be bypassed during bootstrapping or explicitly disabled (`-1`).

## Parser Gating

Some syntax is detected and gated during parsing.
The parser records spans for
later checking to keep diagnostics consistent and deferred until after parsing.

- [`rustc_session/src/parse.rs`] defines [`GatedSpans`] and the `gate` method.
- The parser uses it in [`rustc_parse/src/parser/*`] when it encounters
  syntax that requires a gate (e.g., `async for`, `yield`, experimental patterns).

## Checking Pass

The central logic lives in [`rustc_ast_passes/src/feature_gate.rs`], primarily
in `check_crate` and its AST visitor.

### `check_crate`

`check_crate` performs high-level validation:

- `maybe_stage_features`: Rejects `#![feature]` on stable/beta.
- `check_incompatible_features`: Ensures incompatible feature combinations
  (declared in `rustc_feature::INCOMPATIBLE_FEATURES`) are not used together.
- `check_new_solver_banned_features`: Bans features incompatible with
  compiler mode for the next trait solver.
- `check_features_requiring_new_solver`: Requires the new trait solver for
  features incompatible with the old solver.
- **Parser-gated spans**: Processes the `GatedSpans` recorded during parsing
  (see [Checking `GatedSpans`](#checking-gatedspans)).

### Checking `GatedSpans`

`check_crate` iterates over `sess.psess.gated_spans`:

- The `gate_all!` macro emits diagnostics for each gated span if the feature is not enabled.
- Some gates have extra logic (e.g., `yield` can be allowed by `coroutines` or
  `gen_blocks`).
- Legacy gates (e.g., `box_patterns`, `try_blocks`) may use a separate path that
  emits future-incompatibility warnings instead of hard errors.

### AST Visitor

A `PostExpansionVisitor` walks the expanded AST to check constructs that are
easier to validate after expansion.

- The visitor uses helper macros (`gate!`, `gate_alt!`, `gate_multi!`) to check:
  1. Is the feature enabled?
  2. Does `span.allows_unstable` permit it (for internal compiler macros)?
- Examples include `trait_alias`, `decl_macro`, `extern types`, and various `impl Trait` forms.

## Attributes and `cfg`

Beyond syntax, rustc also gates attributes and `cfg` options.

### Built-in attributes

- [`rustc_ast_passes::check_attribute`] inspects attributes against `BUILTIN_ATTRIBUTE_SET`.
- If the attribute is `AttributeGate::Gated` and the feature isn’t enabled,
  `feature_err` is emitted.

### `cfg` options

- [`rustc_attr_parsing/src/attributes/cfg.rs`] defines `gate_cfg` and uses
  [`rustc_feature::find_gated_cfg`] to reject gated `cfg`s.
- `gate_cfg` respects `Span::allows_unstable`, allowing internal compiler
  macros to bypass `cfg` gates when marked with `#[allow_internal_unstable]`.
- The gated cfg list is defined in [`rustc_feature/src/builtin_attrs.rs`].

## Diagnostics

Diagnostic helpers are located in [`rustc_session/src/parse.rs`].

- `feature_err` and `feature_warn` emit standardized diagnostics, attaching the
  tracking issue number where possible.
- `Span::allows_unstable` in [`rustc_span/src/lib.rs`] checks if a span originates
  from a macro marked with `#[allow_internal_unstable]`.
  This allows internal
  macros to use unstable features on stable channels while enforcing gates for user code.

[`rustc_feature/src/unstable.rs`]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_feature/src/unstable.rs
[`rustc_feature/src/removed.rs`]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_feature/src/removed.rs
[`rustc_feature/src/accepted.rs`]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_feature/src/accepted.rs
[`rustc_feature/src/builtin_attrs.rs`]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_feature/src/builtin_attrs.rs
[`rustc_feature::Features`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_feature/struct.Features.html
[`rustc_expand/src/config.rs`]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_expand/src/config.rs
[`features`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/config/fn.features.html
[`RUSTC_BOOTSTRAP`]: https://doc.rust-lang.org/beta/unstable-book/compiler-environment-variables/RUSTC_BOOTSTRAP.html
[`rustc_session/src/parse.rs`]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_session/src/parse.rs
[`GatedSpans`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.GatedSpans.html
[`rustc_ast_passes/src/feature_gate.rs`]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_ast_passes/src/feature_gate.rs
[`rustc_parse/src/parser/*`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/index.html
[`rustc_ast_passes::check_attribute`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_passes/feature_gate/fn.check_attribute.html
[`rustc_attr_parsing/src/attributes/cfg.rs`]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_attr_parsing/src/attributes/cfg.rs
[`rustc_feature::find_gated_cfg`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_feature/fn.find_gated_cfg.html
[`rustc_span/src/lib.rs`]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_span/src/lib.rs
[feature-gates]: ./feature-gates.md

---

### Src Doc Rustc Dev Guide Src Feature Gates (`src/doc/rustc-dev-guide/src/feature-gates.md`)

# Feature gates

This chapter is intended to provide basic help for adding, removing, and modifying feature gates.

For how rustc enforces and checks feature gates in the compiler pipeline,
see [Feature Gate Checking][feature-gate-check].

Note that this is specific to *language* feature gates; *library* feature gates use [a different
mechanism][libs-gate].

[feature-gate-check]: ./feature-gate-check.md
[libs-gate]: ./stability.md

## Adding a feature gate

See ["Stability in code"][adding] in the "Implementing new features" section for instructions.

[adding]: ./implementing-new-features.md#stability-in-code

## Removing a feature gate

[removing]: #removing-a-feature-gate

To remove a feature gate, follow these steps:

1. Remove the feature gate declaration in `rustc_feature/src/unstable.rs`.
   It will look like this:

   ```rust,ignore
   /// description of feature
   (unstable, $feature_name, "$version", Some($tracking_issue_number))
   ```

2. Add a modified version of the feature gate declaration that you just
   removed to `rustc_feature/src/removed.rs`:

   ```rust,ignore
   /// description of feature
   (removed, $old_feature_name, "$version", Some($tracking_issue_number),
    Some("$why_it_was_removed"))
   ```


## Renaming a feature gate

[renaming]: #renaming-a-feature-gate

To rename a feature gate, follow these steps (the first two are the same steps
to follow when [removing a feature gate][removing]):

1. Remove the old feature gate declaration in `rustc_feature/src/unstable.rs`.
   It will look like this:

   ```rust,ignore
   /// description of feature
   (unstable, $old_feature_name, "$version", Some($tracking_issue_number))
   ```

2. Add a modified version of the old feature gate declaration that you just
   removed to `rustc_feature/src/removed.rs`:

   ```rust,ignore
   /// description of feature
   /// Renamed to `$new_feature_name`
   (removed, $old_feature_name, "$version", Some($tracking_issue_number),
    Some("renamed to `$new_feature_name`"))
   ```

3. Add a feature gate declaration with the new name to `rustc_feature/src/unstable.rs`.
   It should look very similar to the old declaration:

   ```rust,ignore
   /// description of feature
   (unstable, $new_feature_name, "$version", Some($tracking_issue_number))
   ```


## Stabilizing a feature

See ["Updating the feature-gate listing"] in the "Stabilizing Features" chapter for instructions.
There are additional steps you will need to take beyond just updating the declaration!


["Stability in code"]: ./implementing-new-features.md#stability-in-code
["Updating the feature-gate listing"]: ./stabilization-guide.md#updating-the-feature-gate-listing

---

### Src Doc Rustc Dev Guide Src Fuzzing (`src/doc/rustc-dev-guide/src/fuzzing.md`)

# Fuzzing



For the purposes of this guide, *fuzzing* is any testing methodology that
involves compiling a wide variety of programs in an attempt to uncover bugs in rustc.
Fuzzing is often used to find internal compiler errors (ICEs).
Fuzzing can be beneficial, because it can find bugs before users run into them.
It also provides small, self-contained programs that make the bug easier to track down.
However, some common mistakes can reduce the helpfulness of fuzzing and end up
making contributors' lives harder.
To maximize your positive impact on the Rust
project, please read this guide before reporting fuzzer-generated bugs!

## Guidelines

### In a nutshell

*Please do:*

- Ensure the bug is still present on the latest nightly rustc
- Include a reasonably minimal, standalone example along with any bug report
- Include all of the information requested in the bug report template
- Search for existing reports with the same message and query stack
- Format the test case with `rustfmt`
- Indicate that the bug was found by fuzzing

*Please don't:*

- Don't report lots of bugs that use internal features, including but not
  limited to `custom_mir`, `lang_items`, `no_core`, and `rustc_attrs`.
- Don't seed your fuzzer with inputs that are known to crash rustc (details below).

### Discussion

If you're not sure whether or not an ICE is a duplicate of one that's already
been reported, please go ahead and report it and link to issues you think might be related.
In general, ICEs on the same line but with different *query stacks* are usually distinct bugs.
For example, [#109020] and [#109129] had similar error messages:

```
error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead
```

```
error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <() as Project>::Assoc, maybe try to call `try_normalize_erasing_regions` instead
```

However, they have different query stacks:
```
query stack during panic:
#0 [fn_abi_of_instance] computing call ABI of `<[closure@src/main.rs:36:25: 36:28] as core::ops::function::FnOnce<(Emplacable<()>,)>>::call_once - shim(vtable)`
end of query stack
```
```
query stack during panic:
#0 [check_mod_attrs] checking attributes in top-level module
#1 [analysis] running analysis passes on this crate
end of query stack
```

[#109020]: https://github.com/rust-lang/rust/issues/109020
[#109129]: https://github.com/rust-lang/rust/issues/109129

## Building a corpus

When building a corpus, be sure to avoid collecting tests that are already known to crash rustc.
A fuzzer that is seeded with such tests is more likely to
generate bugs with the same root cause.
The simplest way to avoid this is to loop over each file in the corpus, see if it causes an
ICE, and remove it if so.

To build a corpus, you may want to use:

- The rustc/rust-analyzer/clippy test suites (or even source code) --- though avoid
  tests that are already known to cause failures, which often begin with comments
  like `//@ failure-status: 101` or `//@ known-bug: #NNN`.
- The already-fixed ICEs in the archived [Glacier] repository --- though
  avoid the unfixed ones in `ices/`!

[glacier]: https://github.com/rust-lang/glacier

## Extra credit

Here are a few things you can do to help the Rust project after filing an ICE:

- [Bisect][bisect] the bug to figure out when it was introduced.
  If you find the regressing PR / commit, you can mark the issue with the label `S-has-bisection`.
  If not, consider applying `E-needs-bisection` instead.
- Fix "distractions": problems with the test case that don't contribute to
  triggering the ICE, such as syntax errors or borrow-checking errors
- Minimize the test case (see below).
  If successful, you can label the issue with `S-has-mcve`.
  Otherwise, you can apply `E-needs-mcve`.
- Add the minimal test case to the rust-lang/rust repo as a [crash test].
  While you're at it, consider including other "untracked" crashes in your PR.
  Please don't forget to mark all relevant issues with `S-bug-has-test` once your PR is merged.

See also [applying and removing labels][labeling].

[bisect]: https://rust-lang.github.io/cargo-bisect-rustc/
[crash test]: tests/compiletest.md#crash-tests
[labeling]: https://forge.rust-lang.org/release/issue-triaging.html#applying-and-removing-labels

## Minimization

It is helpful to carefully *minimize* the fuzzer-generated input.
When minimizing, be careful to preserve the original error, and avoid introducing
distracting problems such as syntax, type-checking, or borrow-checking errors.

There are some tools that can help with minimization.
If you're not sure how to avoid introducing syntax, type-, and borrow-checking errors while using
these tools, post both the complete and minimized test cases.
Generally,
*syntax-aware* tools give the best results in the least amount of time.
[`treereduce-rust`][treereduce] and [picireny][picireny] are syntax-aware.
[`halfempty`][halfempty] is not, but is generally a high-quality tool.

[halfempty]: https://github.com/googleprojectzero/halfempty
[picireny]: https://github.com/renatahodovan/picireny
[treereduce]: https://github.com/langston-barrett/treereduce

## Effective fuzzing

When fuzzing rustc, you may want to avoid generating machine code, since this
is mostly done by LLVM.
Try `--emit=mir` instead.

A variety of compiler flags can uncover different issues.
`-Zmir-opt-level=4` will turn on MIR optimization passes that are not run by default, potentially
uncovering interesting bugs.
`-Zvalidate-mir` can help uncover such bugs.

If you're fuzzing a compiler you built, you may want to build it with `-C
target-cpu=native` or even PGO/BOLT to squeeze out a few more executions per second.
Of course, it's best to try multiple build configurations and see
what actually results in superior throughput.

You may want to build rustc from source with debug assertions to find
additional bugs, though this can slow down fuzzing by
requiring extra work for every execution.
To enable debug assertions, add this to `bootstrap.toml` when compiling rustc:

```toml
rust.debug-assertions = true
```

ICEs that require debug assertions to reproduce should be tagged
[`requires-debug-assertions`].

[`requires-debug-assertions`]: https://github.com/rust-lang/rust/labels/requires-debug-assertions

## Existing projects

- [fuzz-rustc][fuzz-rustc] demonstrates how to fuzz rustc with libfuzzer
- [icemaker][icemaker] runs rustc and other tools on a large number of source
  files with a variety of flags to catch ICEs
- [tree-splicer][tree-splicer] generates new source files by combining existing
  ones while maintaining correct syntax

[fuzz-rustc]: https://github.com/dwrensha/fuzz-rustc
[icemaker]: https://github.com/matthiaskrgr/icemaker/
[tree-splicer]: https://github.com/langston-barrett/tree-splicer/

---

### Src Doc Rustc Dev Guide Src Generic Parameters Summary (`src/doc/rustc-dev-guide/src/generic-parameters-summary.md`)

# Generic parameter definitions

This chapter will discuss how rustc tracks what generic parameters are introduced.
For example, given some `struct Foo<T>`,
how does rustc track that `Foo` defines some type parameter `T` (and no other generic parameters).

This will *not* cover how we track generic parameters introduced via `for<'a>` syntax (e.g. in where clauses or `fn` types), which is covered elsewhere in the [chapter on `Binder`s ][ch_binders].

# `ty::Generics`

The generic parameters introduced by an item are tracked by the [`ty::Generics`] struct.
Sometimes items allow usage of generics defined on parent items,
and this is accomplished via the `ty::Generics` struct having an optional field to specify a parent item to inherit generic parameters of.
For example, given the following code:

```rust,ignore
trait Trait<T> {
    fn foo<U>(&self);
}
```

The `ty::Generics` used for `foo` would contain `[U]` and a parent of `Some(Trait)`.
`Trait` would have a `ty::Generics` containing `[Self, T]` with a parent of `None`.

The [`GenericParamDef`] struct is used to represent each individual generic parameter in a `ty::Generics` listing. The `GenericParamDef` struct contains information about the generic parameter, for example its name, defid, what kind of parameter it is (i.e. type, const, lifetime).

`GenericParamDef` also contains a `u32` index representing what position the parameter is (starting from the outermost parent), this is the value used to represent usages of generic parameters (more on this in the [chapter on representing types][ch_representing_types]).

Interestingly, `ty::Generics` does not currently contain _every_ generic parameter defined on an item.
In the case of functions, it only contains the _early bound_ parameters.

[ch_representing_types]: ./ty.md
[`ty::Generics`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Generics.html
[`GenericParamDef`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/generics/struct.GenericParamDef.html
[ch_binders]: ./ty-module/binders.md

---

### Src Doc Rustc Dev Guide Src Git (`src/doc/rustc-dev-guide/src/git.md`)

# Using Git

The Rust project uses [Git] to manage its source code.
In order to contribute, you'll need some familiarity with its features so that your changes
can be incorporated into the compiler.

[Git]: https://git-scm.com

The goal of this page is to cover some of the more common questions and
problems new contributors face.
Although some Git basics will be covered here,
if you find that this is still a little too fast for you, it might make sense
to first read some introductions to Git, such as the Beginner and Getting
started sections of [this tutorial from Atlassian][atlassian-git].
GitHub also provides [documentation] and [guides] for beginners, or you can consult the
more in depth [book from Git].

This guide is incomplete.
If you run into trouble with git that this page doesn't help with,
please [open an issue] so we can document how to fix it.

[open an issue]: https://github.com/rust-lang/rustc-dev-guide/issues/new
[book from Git]: https://git-scm.com/book/en/v2/
[atlassian-git]: https://www.atlassian.com/git/tutorials/what-is-version-control
[documentation]: https://docs.github.com/en/get-started/quickstart/set-up-git
[guides]: https://guides.github.com/introduction/git-handbook/

## Prerequisites

We'll assume that you've installed Git, forked [rust-lang/rust], and cloned the
forked repo to your PC.
We'll use the command line interface to interact
with Git; there are also a number of GUIs and IDE integrations that can
generally do the same things.

[rust-lang/rust]: https://github.com/rust-lang/rust

If you've cloned your fork, then you will be able to reference it with `origin` in your local repo.
It may be helpful to also set up a remote for the official rust-lang/rust repo via

```console
git remote add upstream https://github.com/rust-lang/rust.git
```

if you're using HTTPS, or

```console
git remote add upstream git@github.com:rust-lang/rust.git
```

if you're using SSH.

**NOTE:** This page is dedicated to workflows for `rust-lang/rust`, but will likely be
useful when contributing to other repositories in the Rust project.


## Standard Process

Below is the normal procedure that you're likely to use for most minor changes and PRs:

 1. Ensure that you're making your changes on top of `main`: `git checkout main`.
 2. Get the latest changes from the Rust repo: `git pull upstream main --ff-only`.
 (see [No-Merge Policy][no-merge-policy] for more info about this).
 3. Make a new branch for your change: `git checkout -b issue-12345-fix`.
 4. Make some changes to the repo and test them.
 5. Stage your changes via `git add src/changed/file.rs src/another/change.rs`
 and then commit them with `git commit`.
 Of course, making intermediate commits may be a good idea as well.
 Avoid `git add .`, as it makes it too easy to
 unintentionally commit changes that should not be committed, such as submodule updates.
 You can use `git status` to check if there are any files you forgot to stage.
 6. Push your changes to your fork: `git push --set-upstream origin issue-12345-fix`
 (After adding commits, you can use `git push` and after rebasing or
pulling-and-rebasing, you can use `git push --force-with-lease`).
 7. [Open a PR][ghpullrequest] from your fork to `rust-lang/rust`'s `main` branch.

[ghpullrequest]: https://guides.github.com/activities/forking/#making-a-pull-request

If you end up needing to rebase and are hitting conflicts, see [Rebasing](#rebasing).
If you want to track upstream while working on long-running feature/issue, see
[Keeping things up to date][no-merge-policy].

If your reviewer requests changes, the procedure for those changes looks much
the same, with some steps skipped:

 1. Ensure that you're making changes to the most recent version of your code:
 `git checkout issue-12345-fix`.
 2. Make, stage, and commit your additional changes just like before.
 3. Push those changes to your fork: `git push`.

 [no-merge-policy]: #keeping-things-up-to-date

## Troubleshooting git issues

You don't need to clone `rust-lang/rust` from scratch if it's out of date!
Even if you think you've messed it up beyond repair, there are ways to fix
the git state that don't require downloading the whole repository again.
Here are some common issues you might run into:

### I made a merge commit by accident.

Git has two ways to update your branch with the newest changes: merging and rebasing.
Rust [uses rebasing][no-merge-policy].
If you make a merge commit, it's not too hard to fix: `git rebase -i upstream/main`.

See [Rebasing](#rebasing) for more about rebasing.

### I deleted my fork on GitHub!

This is not a problem from git's perspective.
If you run `git remote -v`,
it will say something like this:

```console
$ git remote -v
origin  git@github.com:jyn514/rust.git (fetch)
origin  git@github.com:jyn514/rust.git (push)
upstream        https://github.com/rust-lang/rust (fetch)
upstream        https://github.com/rust-lang/rust (fetch)
```

If you renamed your fork, you can change the URL like this:

```console
git remote set-url origin <URL>
```

where the `<URL>` is your new fork.

### I changed a submodule by accident

Usually people notice this when rustbot posts a comment on github that `cargo` has been modified:



You might also notice conflicts in the web UI:



The most common cause is that you rebased after a change and ran `git add .` without first running
`x` to update the submodules.
 Alternatively, you might have run `cargo fmt` instead of `x fmt`
and modified files in a submodule, then committed the changes.

To fix it, do the following things (if you changed a submodule other than cargo,
replace `src/tools/cargo` with the path to that submodule):

1. See which commit has the accidental changes: `git log --stat -n1 src/tools/cargo`
2. Revert the changes to that commit: `git checkout <my-commit>~ src/tools/cargo`.
   Type `~` literally but replace `<my-commit>` with the output from step 1.
3. Tell git to commit the changes: `git commit --fixup <my-commit>`
4. Repeat steps 1-3 for all the submodules you modified.
    - If you modified the submodule in several different commits, you will need to repeat steps 1-3
    for each commit you modified.
    You'll know when to stop when the `git log` command shows a commit
    that's not authored by you.
5. Squash your changes into the existing commits: `git rebase --autosquash -i upstream/main`
6. [Push your changes](#standard-process).

### I see "error: cannot rebase" when I try to rebase

These are two common errors to see when rebasing:
```console
error: cannot rebase: Your index contains uncommitted changes.
error: Please commit or stash them.
```
```console
error: cannot rebase: You have unstaged changes.
error: Please commit or stash them.
```

(See <https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F#_the_three_states> for the difference between the two.)

This means you have made changes since the last time you made a commit.
To be able to rebase, either
commit your changes, or make a temporary commit called a "stash" to have them still not be committed
when you finish rebasing.
You may want to configure git to make this "stash" automatically, which
will prevent the "cannot rebase" error in nearly all cases:

```console
git config --global rebase.autostash true
```

See <https://git-scm.com/book/en/v2/Git-Tools-Stashing-and-Cleaning> for more info about stashing.

### I see 'Untracked Files: src/stdarch'?

This is left over from the move to the `library/` directory.
Unfortunately, `git rebase` does not follow renames for submodules, so you
have to delete the directory yourself:

```console
rm -r src/stdarch
```

### I see `<<< HEAD`?

You were probably in the middle of a rebase or merge conflict.
See [Conflicts](#rebasing-and-conflicts) for how to fix the conflict.
If you don't care about the changes
and just want to get a clean copy of the repository back, you can use `git reset`:

```console
# WARNING: this throws out any local changes you've made! Consider resolving the conflicts instead.
git reset --hard main
```

### failed to push some refs

`git push` will not work properly and say something like this:

```console
 ! [rejected]        issue-xxxxx -> issue-xxxxx (non-fast-forward)
error: failed to push some refs to 'https://github.com/username/rust.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

The advice this gives is incorrect!
Because of Rust's ["no-merge" policy](#no-merge-policy), the merge commit created by `git pull`
will not be allowed in the final PR, in addition to defeating the point of the rebase!
Use `git push --force-with-lease` instead.

### Git is trying to rebase commits I didn't write?

If you see many commits in your rebase list, or merge commits, or commits by other people that you
didn't write, it likely means you're trying to rebase over the wrong branch.
For example, you may
have a `rust-lang/rust` remote `upstream`, but ran `git rebase origin/main` instead of `git rebase
upstream/main`.
The fix is to abort the rebase and use the correct branch instead:

```console
git rebase --abort
git rebase --interactive upstream/main
```

<details><summary>Click here to see an example of rebasing over the wrong branch</summary>



</details>

### Quick note about submodules

When updating your local repository with `git pull`, you may notice that sometimes
Git says you have modified some files that you have never edited.
For example,
running `git status` gives you something like (note the `new commits` mention):

```console
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   src/llvm-project (new commits)
	modified:   src/tools/cargo (new commits)

no changes added to commit (use "git add" and/or "git commit -a")
```

These changes are not changes to files: they are changes to submodules (more on this [later](#git-submodules)).
To get rid of those:

```console
git submodule update
```

Some submodules are not actually needed; for example, `src/llvm-project` doesn't need to be checked
out if you're using `download-ci-llvm`.
 To avoid having to keep fetching its history, you can use
`git submodule deinit -f src/llvm-project`, which will also avoid it showing as modified again.

## Rebasing and Conflicts

When you edit your code locally, you are making changes to the version of
rust-lang/rust that existed when you created your feature branch.
As such, when you submit your PR, it is possible that some of the changes that have been made
to rust-lang/rust since then are in conflict with the changes you've made.
When this happens, you need to resolve the conflicts before your changes can be merged.
To do that, you need to rebase your work on top of rust-lang/rust.

### Rebasing

To rebase your feature branch on top of the newest version of the `main` branch
of rust-lang/rust, checkout your branch, and then run this command:

```console
git pull --rebase https://github.com/rust-lang/rust.git main
```

> If you are met with the following error:
> ```console
> error: cannot pull with rebase: Your index contains uncommitted changes.
> error: please commit or stash them.
> ```
> it means that you have some uncommitted work in your working tree. In that
> case, run `git stash` before rebasing, and then `git stash pop` after you
> have rebased and fixed all conflicts.

When you rebase a branch on main, all the changes on your branch are
reapplied to the most recent version of `main`.
In other words, Git tries to
pretend that the changes you made to the old version of `main` were instead
made to the new version of `main`.
During this process, you should expect to encounter at least one "rebase conflict".
This happens when Git's attempt to
reapply the changes fails because your changes conflicted with other changes that have been made.
You can tell that this happened because you'll see lines in the output that look like

```console
CONFLICT (content): Merge conflict in file.rs
```

When you open these files, you'll see sections of the form

```console
<<<<<<< HEAD
Original code
=======
Your code
>>>>>>> 8fbf656... Commit fixes 12345
```

This represents the lines in the file that Git could not figure out how to rebase.
The section between `<<<<<<< HEAD` and `=======` has the code from
`main`, while the other side has your version of the code.
You'll need to decide how to deal with the conflict.
You may want to keep your changes,
keep the changes on `main`, or combine the two.

Generally, resolving the conflict consists of two steps: First, fix the particular conflict.
Edit the file to make the changes you want and remove the
`<<<<<<<`, `=======` and `>>>>>>>` lines in the process.
Second, check the surrounding code.
If there was a conflict, its likely there are some logical errors lying around too!
It's a good idea to run `x check` here to make sure there are no glaring errors.

Once you're all done fixing the conflicts, you need to stage the files that had
conflicts in them via `git add`.
Afterwards, run `git rebase --continue` to let
Git know that you've resolved the conflicts and it should finish the rebase.

Once the rebase has succeeded, you'll want to update the associated branch on
your fork with `git push --force-with-lease`.

### Keeping things up to date

The [above section](#rebasing) is a specific
guide on rebasing work and dealing with merge conflicts.
Here is some general advice about how to keep your local repo up-to-date with upstream changes:

Using `git pull upstream main` while on your local `main` branch regularly will keep it up-to-date.
You will also want to keep your feature branches up-to-date as well.
After pulling, you can checkout the feature branches and rebase them:

```console
git checkout main
git pull upstream main --ff-only # to make certain there are no merge commits
git rebase main feature_branch
git push --force-with-lease # (set origin to be the same as local)
```

To avoid merges as per the [No-Merge Policy](#no-merge-policy), you may want to use
`git config pull.ff only` (this will apply the config only to the local repo)
to ensure that Git doesn't create merge commits when `git pull`ing, without
needing to pass `--ff-only` or `--rebase` every time.

You can also `git push --force-with-lease` from main to double-check that your
feature branches are in sync with their state on the GitHub side.

## Advanced Rebasing

### Squash your commits

"Squashing" commits into each other causes them to be merged into a single commit.
Both the upside and downside of this is that it simplifies the history.
On the one hand, you lose track of the steps in which changes were made, but
the history becomes easier to work with.

The easiest way to squash your commits in a PR on the `rust-lang/rust` repository is to use the `@bors squash` command in a comment on the PR.
By default, [bors] combines all commit messages of the PR into the squashed commit message.
To customize the commit message, use `@bors squash msg="<commit message>"`.
For example, `@bors squash msg="Improve diagnostics for missing lifetime parameter"`.

If you want to squash commits using local git operations, read on below.

If there are no conflicts and you are just squashing to clean up the history,
use `git rebase --interactive --keep-base main`.
This keeps the fork point of your PR the same, making it easier to review the diff of what happened
across your rebases.

Squashing can also be useful as part of conflict resolution.
If your branch contains multiple consecutive rewrites of the same code, or if
the rebase conflicts are extremely severe, you can use
`git rebase --interactive main` to gain more control over the process.
This allows you to choose to skip commits, edit the commits that you do not skip,
change the order in which they are applied, or "squash" them into each other.

Alternatively, you can sacrifice the commit history like this:

```console
# squash all the changes into one commit so you only have to worry about conflicts once
git rebase --interactive --keep-base main  # and squash all changes along the way
git rebase main
# fix all merge conflicts
git rebase --continue
```

You also may want to squash just the last few commits together, possibly
because they only represent "fixups" and not real changes.
For example,
`git rebase --interactive HEAD~2` will allow you to edit the two commits only.

[bors]: https://github.com/rust-lang/bors

### `git range-diff`

After completing a rebase, and before pushing up your changes, you may want to
review the changes between your old branch and your new one.
You can do that with `git range-diff main @{upstream} HEAD`.

The first argument to `range-diff`, `main` in this case, is the base revision
that you're comparing your old and new branch against.
The second argument is
the old version of your branch; in this case, `@upstream` means the version that
you've pushed to GitHub, which is the same as what people will see in your pull request.
Finally, the third argument to `range-diff` is the *new* version of
your branch; in this case, it is `HEAD`, which is the commit that is currently
checked-out in your local repo.

Note that you can also use the equivalent, abbreviated form `git range-diff main @{u} HEAD`.

Unlike in regular Git diffs, you'll see a `-` or `+` next to another `-` or `+`
in the range-diff output.
The marker on the left indicates a change between the
old branch and the new branch, and the marker on the right indicates a change you've committed.
So, you can think of a range-diff as a "diff of diffs" since
it shows you the differences between your old diff and your new diff.

Here's an example of `git range-diff` output (taken from [Git's docs][range-diff-example-docs]):

```console
-:  ------- > 1:  0ddba11 Prepare for the inevitable!
1:  c0debee = 2:  cab005e Add a helpful message at the start
2:  f00dbal ! 3:  decafe1 Describe a bug
    @@ -1,3 +1,3 @@
     Author: A U Thor <author@example.com>

    -TODO: Describe a bug
    +Describe a bug
    @@ -324,5 +324,6
      This is expected.

    -+What is unexpected is that it will also crash.
    ++Unexpectedly, it also crashes. This is a bug, and the jury is
    ++still out there how to fix it best. See ticket #314 for details.

      Contact
3:  bedead < -:  ------- TO-UNDO
```

(Note that `git range-diff` output in your terminal will probably be easier to
read than in this example because it will have colors.)

Another feature of `git range-diff` is that, unlike `git diff`, it will also diff commit messages.
This feature can be useful when amending several commit
messages so you can make sure you changed the right parts.

`git range-diff` is a very useful command, but note that it can take some time
to get used to its output format.
You may also find Git's documentation on the
command useful, especially their ["Examples" section][range-diff-example-docs].

[range-diff-example-docs]: https://git-scm.com/docs/git-range-diff#_examples

## No-Merge Policy

The rust-lang/rust repo uses what is known as a "rebase workflow".
This means that merge commits in PRs are not accepted.
As a result, if you are running
`git merge` locally, chances are good that you should be rebasing instead.
Of course, this is not always true; if your merge will just be a fast-forward,
like the merges that `git pull` usually performs, then no merge commit is
created and you have nothing to worry about.
Running `git config merge.ff only` (this will apply the config to the local repo)
once will ensure that all the merges you perform are of this type, so that you
cannot make a mistake.

There are a number of reasons for this decision, and like all others, it is a tradeoff.
The main advantage is the generally linear commit history.
This greatly simplifies bisecting and makes the history and commit log much easier
to follow and understand.

## Tips for reviewing

**NOTE**: This section is for *reviewing* PRs, not authoring them.

### Hiding whitespace

GitHub has a button for disabling whitespace changes that may be useful.
You can also use `git diff -w origin/main` to view changes locally.



### Fetching PRs

To checkout PRs locally, you can use `git fetch upstream pull/NNNNN/head && git checkout
FETCH_HEAD`.

You can also use github's cli tool.
GitHub shows a button on PRs where you can copy-paste the command to check it out locally.
See <https://cli.github.com/> for more info.



### Using GitHub dev

As an alternative to the GitHub web UI, GitHub Dev provides a web-based editor for browsing
repository and PRs.
It can be opened by replacing `github.com` with `github.dev` in the URL
or by pressing `.` on a GitHub page.
See [the docs for github.dev editor](https://docs.github.com/en/codespaces/the-githubdev-web-based-editor)
for more details.

### Moving large sections of code

Git and GitHub's default diff view for large moves *within* a file is quite poor; it will show each
line as deleted and each line as added, forcing you to compare each line yourself.
Git has an option to show moved lines in a different color:

```console
git log -p --color-moved=dimmed-zebra --color-moved-ws=allow-indentation-change
```

See [the docs for `--color-moved`](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---color-movedltmodegt) for more info.

### range-diff

See [the relevant section for PR authors](#git-range-diff).
This can be useful for comparing code
that was force-pushed to make sure there are no unexpected changes.

### Ignoring changes to specific files

Many large files in the repo are autogenerated.
To view a diff that ignores changes to those files,
you can use the following syntax (e.g. Cargo.lock):

```console
git log -p ':!Cargo.lock'
```

Arbitrary patterns are supported (e.g. `:!compiler/*`). Patterns use the same syntax as
`.gitignore`, with `:` prepended to indicate a pattern.

## Git submodules

**NOTE**: submodules are a nice thing to know about, but it *isn't* an absolute
prerequisite to contribute to `rustc`.
If you are using Git for the first time,
you might want to get used to the main concepts of Git before reading this section.

The `rust-lang/rust` repository uses [Git submodules] as a way to use other
Rust projects from within the `rust` repo.
Examples include Rust's fork of
`llvm-project`, `cargo`, and libraries like `stdarch` and `backtrace`.

Those projects are developed and maintained in a separate Git (and GitHub)
repository, and they have their own Git history/commits, issue tracker and PRs.
Submodules allow us to create some sort of embedded sub-repository inside the
`rust` repository and use them like they were directories in the `rust` repository.

Take `llvm-project` for example.
`llvm-project` is maintained in the [`rust-lang/llvm-project`]
repository, but it is used in `rust-lang/rust` by the compiler for code generation and optimization.
We bring it in `rust` as a submodule, in the `src/llvm-project` folder.

The contents of submodules are ignored by Git: submodules are in some sense isolated
from the rest of the repository.
However, if you try to `cd src/llvm-project` and then run `git status`:

```console
HEAD detached at 9567f08afc943
nothing to commit, working tree clean
```

As far as git is concerned, you are no longer in the `rust` repo, but in the `llvm-project` repo.
You will notice that we are in "detached HEAD" state, i.e. not on a branch but on a
particular commit.

This is because, like any dependency, we want to be able to control which version to use.
Submodules allow us to do just that: every submodule is "pinned" to a certain
commit, which doesn't change unless modified manually.
If you use `git checkout <commit>`
in the `llvm-project` directory and go back to the `rust` directory, you can stage this
change like any other, e.g. by running `git add src/llvm-project`. (Note that if
you *don't* stage the change to commit, then you run the risk that running
`x` will just undo your change by switching back to the previous commit when
it automatically "updates" the submodules.)

This version selection is usually done by the maintainers of the project, and
looks like [this][llvm-update].

Git submodules take some time to get used to, so don't worry if it isn't perfectly clear yet.
You will rarely have to use them directly and, again, you don't need
to know everything about submodules to contribute to Rust.
Just know that they exist and that they correspond to some sort of embedded subrepository dependency
that Git can nicely and fairly conveniently handle for us.

### Hard-resetting submodules

Sometimes you might run into (when you run `git status`)

```console
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
  (commit or discard the untracked or modified content in submodules)
        modified:   src/llvm-project (new commits, modified content)
```

and when you try to run `git submodule update` it breaks horribly with errors like

```console
error: RPC failed; curl 92 HTTP/2 stream 7 was not closed cleanly: CANCEL (err 8)
error: 2782 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output
fatal: Fetched in submodule path 'src/llvm-project', but it did not contain 5a5152f653959d14d68613a3a8a033fb65eec021. Direct fetching of that commit failed.
```

If you see `(new commits, modified content)` you can run

```console
git submodule foreach git reset --hard
```

and then try `git submodule update` again.

### Deinit git submodules

If that doesn't work, you can try to deinit all git submodules...

```console
git submodule deinit -f --all
```

Unfortunately sometimes your local git submodules configuration can become
completely messed up for some reason.

### Overcoming `fatal: not a git repository: <submodule>/../../.git/modules/<submodule>`

Sometimes, for some forsaken reason, you might run into

```console
fatal: not a git repository: src/gcc/../../.git/modules/src/gcc
```

In this situation, for the given submodule path, i.e. `<submodule_path> =
src/gcc` in this example, you need to:

1. `rm -rf <submodule_path>/.git`
2. `rm -rf .git/modules/<submodule_path>/config`
3. `rm -rf .gitconfig.lock` if somehow the `.gitconfig` lock is orphaned.

Then do something like `./x fmt` to have bootstrap manage the submodule checkouts for you.

## Ignoring commits during `git blame`

Some commits contain large reformatting changes that don't otherwise change functionality.
They can be instructed to be ignored by `git blame` through
[`.git-blame-ignore-revs`](https://github.com/rust-lang/rust/blob/HEAD/.git-blame-ignore-revs):

1. Configure `git blame` to use `.git-blame-ignore-revs` as the list of commits to ignore: `git
   config blame.ignorerevsfile .git-blame-ignore-revs`
2. Add suitable commits that you wish to be ignored by `git blame`.

Please include a comment for the commit that you add to `.git-blame-ignore-revs` so people can
easily figure out *why* a commit is ignored.

[Git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules
[`rust-lang/llvm-project`]: https://github.com/rust-lang/llvm-project
[llvm-update]: https://github.com/rust-lang/rust/pull/99464/files

---

### Src Doc Rustc Dev Guide Src Hir (`src/doc/rustc-dev-guide/src/hir.md`)

# The HIR

The HIR – "High-Level Intermediate Representation" – is the primary IR used
in most of rustc.
It is a compiler-friendly representation of the abstract
syntax tree (AST) that is generated after parsing, macro expansion, and name
resolution (see [Lowering](./hir/lowering.md) for how the HIR is created).
Many parts of HIR resemble Rust surface syntax quite closely, with
the exception that some of Rust's expression forms have been desugared away.
For example, `for` loops are converted into a `loop` and do not appear in
the HIR.
This makes HIR more amenable to analysis than a normal AST.

This chapter covers the main concepts of the HIR.

You can view the HIR representation of your code by passing the
`-Z unpretty=hir-tree` flag to rustc:

```bash
cargo rustc -- -Z unpretty=hir-tree
```


You can also use the `-Z unpretty=hir` option to generate a HIR
that is closer to the original source code expression:

```bash
cargo rustc -- -Z unpretty=hir
```

## Out-of-band storage and the `Crate` type

The top-level data-structure in the HIR is the [`Crate`], which stores
the contents of the crate currently being compiled (we only ever
construct HIR for the current crate).
Whereas in the AST the crate
data structure basically just contains the root module, the HIR
`Crate` structure contains a number of maps and other things that
serve to organize the content of the crate for easier access.

[`Crate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/struct.Crate.html

For example, the contents of individual items (e.g. modules,
functions, traits, impls, etc) in the HIR are not immediately
accessible in the parents.
So, for example, if there is a module item `foo` containing a function `bar()`:

```rust
mod foo {
    fn bar() { }
}
```

then in the HIR the representation of module `foo` (the [`Mod`]
struct) would only have the **`ItemId`** `I` of `bar()`.
To get the details of the function `bar()`, we would lookup `I` in the
`items` map.

[`Mod`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Mod.html

One nice result from this representation is that one can iterate
over all items in the crate by iterating over the key-value pairs
in these maps (without the need to trawl through the whole HIR).
There are similar maps for things like trait items and impl items,
as well as "bodies" (explained below).

The other reason to set up the representation this way is for better
integration with incremental compilation.
This way, if you gain access
to an [`&rustc_hir::Item`] (e.g. for the mod `foo`), you do not immediately
gain access to the contents of the function `bar()`.
Instead, you only
gain access to the **id** for `bar()`, and you must invoke some
function to lookup the contents of `bar()` given its id; this gives
the compiler a chance to observe that you accessed the data for
`bar()`, and then record the dependency.

[`&rustc_hir::Item`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Item.html

<a id="hir-id"></a>

## Identifiers in the HIR

The HIR uses a bunch of different identifiers that coexist and serve different purposes.

- A [`DefId`], as the name suggests, identifies a particular definition, or top-level
  item, in a given crate.
  It is composed of two parts: a [`CrateNum`] which identifies
  the crate the definition comes from, and a [`DefIndex`] which identifies the definition
  within the crate.
  Unlike [`HirId`]s, there isn't a [`DefId`] for every expression, which
  makes them more stable across compilations.

- A [`LocalDefId`] is basically a [`DefId`] that is known to come from the current crate.
  This allows us to drop the [`CrateNum`] part, and use the type system to ensure that
  only local definitions are passed to functions that expect a local definition.

- A [`HirId`] uniquely identifies a node in the HIR of the current crate.
  It is composed of two parts:
  an `owner` and a `local_id` that is unique within the `owner`.
  This combination makes for more stable values which are helpful for incremental compilation.
  Unlike [`DefId`]s, a [`HirId`] can refer to [fine-grained entities][Node] like expressions,
  but stays local to the current crate.

- A [`BodyId`] identifies a HIR [`Body`] in the current crate.
  It is currently only a wrapper around a [`HirId`].
  For more info about HIR bodies, please refer to the
  [HIR chapter][hir-bodies].

These identifiers can be converted into one another through the `TyCtxt`.

[`DefId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html
[`LocalDefId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.LocalDefId.html
[`HirId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.HirId.html
[`BodyId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.BodyId.html
[Node]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html
[`CrateNum`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.CrateNum.html
[`DefIndex`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefIndex.html
[`Body`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Body.html
[hir-bodies]: ./hir.md#hir-bodies

## HIR Operations

Most of the time when you are working with the HIR, you will do so via `TyCtxt`.
It contains a number of methods, defined in the `hir::map` module and
mostly prefixed with `hir_`, to convert between IDs of various kinds and to
lookup data associated with a HIR node.

[`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html

For example, if you have a [`LocalDefId`], and you would like to convert it
to a [`HirId`], you can use [`tcx.local_def_id_to_hir_id(def_id)`][local_def_id_to_hir_id].
You need a `LocalDefId`, rather than a `DefId`, since only local items have HIR nodes.

[local_def_id_to_hir_id]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.local_def_id_to_hir_id

Similarly, you can use [`tcx.hir_node(n)`][hir_node] to lookup the node for a
[`HirId`].
This returns a `Option<Node<'hir>>`, where [`Node`] is an enum
defined in the map.
By matching on this, you can find out what sort of
node the `HirId` referred to and also get a pointer to the data
itself. Often, you know what sort of node `n` is – e.g. if you know
that `n` must be some HIR expression, you can do
[`tcx.hir_expect_expr(n)`][expect_expr], which will extract and return the
[`&hir::Expr`][Expr], panicking if `n` is not in fact an expression.

[hir_node]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.hir_node
[`Node`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html
[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.expect_expr
[Expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Expr.html

Finally, you can find the parents of nodes, via
calls like [`tcx.parent_hir_node(n)`][parent_hir_node].

[parent_hir_node]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.parent_hir_node


## HIR Bodies

A [`rustc_hir::Body`] represents some kind of executable code, such as the body
of a function/closure or the definition of a constant.
Bodies are associated with an **owner**, which is typically some kind of item
(e.g. an `fn()` or `const`), but could also be a closure expression
(e.g. `|x, y| x + y`). You can use the `TyCtxt` to find the body
associated with a given def-id ([`hir_maybe_body_owned_by`]) or to find
the owner of a body ([`hir_body_owner_def_id`]).

[`rustc_hir::Body`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Body.html
[`hir_maybe_body_owned_by`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.hir_maybe_body_owned_by
[`hir_body_owner_def_id`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.hir_body_owner_def_id

---

### Src Doc Rustc Dev Guide Src Implementing New Features (`src/doc/rustc-dev-guide/src/implementing-new-features.md`)

# Implementing new language features

When you want to implement a new significant feature in the compiler,
you need to go through this process to make sure everything goes smoothly.

**NOTE: This section is for *language* features, not *library* features,
which use [a different process].**

See also [the Rust Language Design Team's procedures][lang-propose] for proposing changes to the language.

[a different process]: ./stability.md
[lang-propose]: https://lang-team.rust-lang.org/how_to/propose.html

## New features

Rust has strong backwards-compatibility guarantees.
Thus, new features can't just be implemented directly in stable Rust.
Instead, we have 3 release channels: stable, beta, and nightly.
See [The Rust Book] for more details on Rust’s train release model.

- **Stable**: this is the latest stable release for general usage.
- **Beta**: this is the next release (will be stable within 6 weeks).
- **Nightly**: follows the `main` branch of the repo.
  This is the only channel where unstable features are intended to be used,
  which happens via opt-in feature gates.

[The Rust Book]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html

### Breaking changes

Breaking changes have a [dedicated section][Breaking Changes] in the dev-guide.

### Major changes

See ["What proposal approval do I need?"](https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#what-proposalapproval-do-i-need)
For a definition of the terms there, see
["Proposals"](https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#proposals).

**When in doubt, ask [on Zulip].
It would be a shame to put a lot of work into a PR that ends up not getting merged!**

[on Zulip]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler

[Breaking Changes]: bug-fix-procedure.md

## The @rfcbot FCP process

When the change is small, uncontroversial, non-breaking,
and does not affect the stable language in any user-observable ways or add any new unstable features,
then it can be done with just writing a PR and getting an r+ from someone who knows that part of the code.
However, if not, more must be done.
Even for compiler-internal work,
it would be a bad idea to push a controversial change without consensus from the rest of the team
(both in the "distributed system" sense to make sure you don't break anything you don't know about,
and in the social sense to avoid PR fights).

For changes that need the consensus of a team,
we use the process of proposing a final comment period (FCP).
If you're not on the relevant team (and thus don't have @rfcbot permissions),
ask someone who is to start one;
unless they have a concern themselves, they should.

The FCP process is only needed if you need consensus –
if no processes require consensus for your change
and you don't think anyone would have a problem with it, it's OK to rely on only an r+.
For example,
it is OK to add or modify unstable command-line flags
or attributes in the reserved compiler-internal `rustc_` namespace
without an FCP for compiler development or standard library use,
as long as you don't expect them to be in wide use in the nightly ecosystem.
Some teams have lighter weight processes that they use in scenarios like this;
for example,
the compiler team recommends filing a Major Change Proposal ([MCP])
as a lightweight way to garner support and feedback without requiring full consensus.

[MCP]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp

You don't need to have the implementation fully ready for r+ to propose an FCP,
but it is generally a good idea to have at least a proof of concept
so that people can see what you are talking about.

When an FCP is proposed, it requires all members of the team to sign off on the FCP.
After they all do so,
there's a 10-day-long "final comment period" (hence the name) where everybody can comment,
and if no concerns are raised, the PR/issue gets FCP approval.

## The logistics of writing features

There are a few "logistical" hoops you might need to go through
in order to implement a feature in a working way.

### Warning Cycles

In some cases, a feature or bugfix might break some existing programs in some edge cases.
In that case,
you'll want to do a crater run to assess the impact and possibly add a future-compatibility lint,
similar to those used for [edition-gated lints](diagnostics.md#edition-gated-lints).

### Stability

We [value the stability of Rust].
Code that works and runs on stable should (mostly) not break.
Because of that,
we don't want to release a feature to the world with only team consensus and code review -
we want to gain real-world experience on using that feature on nightly,
and we might want to change the feature based on that experience.

To allow for that,
we must make sure users don't accidentally depend on that new feature -
otherwise,
especially if experimentation takes time or is delayed and the feature takes the trains to stable,
it would end up de facto stable
and we'll not be able to make changes in it without breaking people's code.

The way we do that is that we make sure all new features are feature gated -
they can't be used without enabling a feature gate (`#[feature(foo)]`),
which can't be done in a stable/beta compiler.
See the [stability in code] section for the technical details.

Eventually, after we gain enough experience using the feature, make the necessary changes,
and are satisfied, we expose it to the world using the stabilization process described [here].
Until then, the feature is not set in stone:
every part of the feature can be changed, or the feature might be completely rewritten or removed.
Features do not gain tenure by being unstable and unchanged for long periods of time.

###  Tracking Issues

To keep track of the status of an unstable feature,
the experience we get while using it on nightly,
and of the concerns that block its stabilization,
every feature-gate needs a tracking issue.
When creating issues and PRs related to the feature, reference this tracking issue,
and when there are updates about the feature's progress, post those to the tracking issue.

For features that are part of an accept RFC or approved lang experiment,
use the tracking issue for that.

For other features, create a tracking issue for that feature.
The issue title should be "Tracking issue for YOUR FEATURE".
Use the ["Tracking Issue" issue template][template].

[template]: https://github.com/rust-lang/rust/issues/new?template=tracking_issue.md

### Lang experiments

To land in the compiler,
features that have user-visible effects on the language (even unstable ones)
must either be part of an accepted RFC or an approved [lang experiment].

To propose a new lang experiment,
open an issue in `rust-lang/rust` that describes the motivation and the intended solution.
If it's accepted, this issue will become the tracking issue for the experiment,
so use the tracking issue [template] while also including these other details.
Nominate the issue for the lang team and CC `@rust-lang/lang` and `@rust-lang/lang-advisors`.
When the experiment is approved, the tracking issue will be marked as `B-experimental`.

Feature flags related to a lang experiment must be marked as `incomplete`
until an RFC is accepted for the feature.

[lang experiment]: https://lang-team.rust-lang.org/how_to/experiment.html

##  Stability in code

The below steps needs to be followed in order to implement a new unstable feature:

1. Open or identify the [tracking issue].
   For features that are part of an accept RFC or approved lang experiment,
   use the tracking issue for that.

   Label the tracking issue with `C-tracking-issue` and the relevant `F-feature_name` label
   (adding that label if needed).

1. Pick a name for the feature gate (for RFCs, use the name in the RFC).

1. Add the feature name to `rustc_span/src/symbol.rs` in the `Symbols {...}` block.

   Note that this block must be in alphabetical order.

1. Add a feature gate declaration to `rustc_feature/src/unstable.rs`
   in the unstable `declare_features` block.

   ```rust ignore
   /// description of feature
   (unstable, $feature_name, "CURRENT_RUSTC_VERSION", Some($tracking_issue_number))
   ```

   If you haven't yet opened a tracking issue
   (e.g. because you want initial feedback on whether the feature is likely to be accepted),
   you can temporarily use `None` - but make sure to update it before the PR is merged!

   For example:

   ```rust ignore
   /// Allows defining identifiers beyond ASCII.
   (unstable, non_ascii_idents, "CURRENT_RUSTC_VERSION", Some(55467)),
   ```

   Features can be marked as incomplete,
   and trigger the warn-by-default [`incomplete_features` lint]
   by setting their type to `incomplete`:

   [`incomplete_features` lint]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#incomplete-features

   ```rust ignore
   /// Allows deref patterns.
   (incomplete, deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121)),
   ```

   Feature flags related to a lang experiment must be marked as `incomplete`
   until an RFC is accepted for the feature.

   To avoid [semantic merge conflicts],
   use `CURRENT_RUSTC_VERSION` instead of `1.70` or another explicit version number.

   [semantic merge conflicts]: https://bors.tech/essay/2017/02/02/pitch/

1. Prevent usage of the new feature unless the feature gate is set.
   You can check it in most places in the compiler
   using the expression `tcx.features().$feature_name()`.

    If the feature gate is not set,
    you should either maintain the pre-feature behavior or raise an error,
    depending on what makes sense.
    Errors should generally use [`rustc_session::errors::feature_err`].
    For an example of adding an error, see [#81015].

   For features introducing new syntax, pre-expansion gating should be used instead.
   During parsing, when the new syntax is parsed,
   the symbol must be inserted to the current crate's [`GatedSpans`]
   via `self.psess.gated_spans.gate(sym::my_feature, span)`.

   After being inserted to the gated spans,
   the span must be checked in the [`rustc_ast_passes::feature_gate::check_crate`] function,
   which actually denies features.
   Exactly how it is gated depends on the exact type of feature,
   but most likely will use the `gate_all!()` macro.

1. Add a test to ensure the feature cannot be used without a feature gate,
   by creating `tests/ui/feature-gates/feature-gate-$feature_name.rs`.
   You can generate the corresponding `.stderr` file
   by running `./x test tests/ui/feature-gates/ --bless`.

1. Add a section to the unstable book,
   in `src/doc/unstable-book/src/language-features/$feature_name.md`.

1. Write a lot of tests for the new feature, preferably in `tests/ui/$feature_name/`.
   PRs without tests will not be accepted!

1. Get your PR reviewed and land it.
   You have now successfully implemented a feature in Rust!

[`GatedSpans`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.GatedSpans.html
[#81015]: https://github.com/rust-lang/rust/pull/81015
[`rustc_session::errors::feature_err`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/errors/fn.feature_err.html
[`rustc_ast_passes::feature_gate::check_crate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_passes/feature_gate/fn.check_crate.html
[value the stability of Rust]: https://github.com/rust-lang/rfcs/blob/master/text/1122-language-semver.md
[stability in code]: #stability-in-code
[here]: ./stabilization-guide.md
[tracking issue]: #tracking-issues
[guidance for compiler flags]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html?highlight=unstable%20flag#compiler-flags
[`UnstableOptions`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/options/struct.UnstableOptions.html

## Adding unstable compiler flags

For compiler-internal experiments, diagnostics, debugging aids, and temporary implementation
controls, a `-Z` flag can be more appropriate than a language feature gate.
Feature gates should still be preferred for user-facing language features,
especially when crates need to opt in from source code.

Before adding a new flag, check the compiler team's [guidance for compiler flags].
Some flags, especially those intended for direct nightly user workflows or broader
ecosystem use, may need additional sign-off beyond an r+ on the implementation PR.

When adding a new `-Z` flag:

1. Add the option to [`UnstableOptions`] in
   `compiler/rustc_session/src/options.rs`.
   The option name is written as snake_case in the struct and is exposed as
   kebab-case on the command line.
   Choose the parser, default value, and dependency tracking marker carefully.
   Use `[UNTRACKED]` for flags that only affect diagnostics or debugging output,
   and use `[TRACKED]` when changing the flag can change compilation results.

1. Update the option tests in `compiler/rustc_interface/src/tests.rs`.
   `options.rs` also has a short checklist near the `UnstableOptions` list for
   files that need to stay in sync.

1. Use the option through `sess.opts.unstable_opts.$flag_name` or
   `tcx.sess.opts.unstable_opts.$flag_name`.
   If bootstrap or rustdoc needs to pass the flag internally,
   thread it through the relevant command construction code as part of the same
   change.

1. Add focused tests for the behavior controlled by the flag.
   For example, UI tests can use `//@ compile-flags: -Zyour-flag`,
   while rustdoc behavior usually belongs in `tests/rustdoc`.

1. If the flag is meant for users of nightly rustc or rustdoc,
   document it in the unstable book under `src/doc/unstable-book/src/compiler-flags`.

Before opening the PR, run `./x test tidy` and the narrow test suite that exercises the new flag.

## Call for testing

Once the implementation is complete,
the feature will be available to nightly users but not yet part of stable Rust.
This is a good time to write a blog post on [the main Rust blog][rust-blog]
and issue a "call for testing".

Some earlier such blog posts include:

1. [The push for GATs stabilization](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push/)
2. [Changes to `impl Trait` in Rust 2024](https://blog.rust-lang.org/2024/09/05/impl-trait-capture-rules.html)
3. [Async Closures MVP: Call for Testing!](https://blog.rust-lang.org/inside-rust/2024/08/09/async-closures-call-for-testing/)

Alternatively, [*This Week in Rust*][twir] has a [section][twir-cft] for this.
One example of this having been used is:

- [Call for testing on boolean literals as cfg predicates](https://github.com/rust-lang/rust/issues/131204#issuecomment-2569314526)

Which option to choose might depend on how significant the language change is,
though note that the [*This Week in Rust*][twir] section might be less visible
than a dedicated post on the main Rust blog.

## Polishing

Giving users a polished experience means more than just implementing the feature in rustc.
We need to think about all of the tools and resources that we ship.
This work includes:

- Documenting the language feature in the [Rust Reference][reference].
- Extending [`rustfmt`] to format any new syntax (if applicable).
- Extending [`rust-analyzer`] (if applicable).
  The extent of this work can depend on the nature of the language feature,
  as some features don't need to be blocked on *full* support.
   - When a language feature degrades the user experience
     simply by existing before support is implemented in [`rust-analyzer`],
     that may lead the lang team to raise a blocking concern.
   - Examples of such might include new syntax that [`rust-analyzer`] can't parse
     or type inference changes it doesn't understand when those lead to bogus diagnostics.

## Stabilization

The final step in the feature lifecycle is [stabilization][stab],
which is when the feature becomes available to all Rust users.
At this point,
backward incompatible changes are generally no longer permitted
(see the lang team's [defined semver policies](https://rust-lang.github.io/rfcs/1122-language-semver.html) for details).
To learn more about stabilization, see the [stabilization guide][stab].


[stab]: ./stabilization-guide.md
[rust-blog]: https://github.com/rust-lang/blog.rust-lang.org/
[twir]: https://github.com/rust-lang/this-week-in-rust
[twir-cft]: https://this-week-in-rust.org/blog/2025/01/22/this-week-in-rust-583/#calls-for-testing
[`rustfmt`]: https://github.com/rust-lang/rustfmt
[`rust-analyzer`]: https://github.com/rust-lang/rust-analyzer
[reference]: https://github.com/rust-lang/reference

---

### Src Doc Rustc Dev Guide Src Incrcomp Debugging (`src/doc/rustc-dev-guide/src/incrcomp-debugging.md`)

# Debugging and testing dependencies

## Testing the dependency graph

There are various ways to write tests against the dependency graph.
 The simplest mechanisms are the `#[rustc_if_this_changed]` and
`#[rustc_then_this_would_need]` annotations.
These are used in [ui] tests to test
whether the expected set of paths exist in the dependency graph.

[`tests/ui/dep-graph/dep-graph-caller-callee.rs`]: https://github.com/rust-lang/rust/blob/HEAD/tests/ui/dep-graph/dep-graph-caller-callee.rs
[ui]: tests/ui.md

As an example, see [`tests/ui/dep-graph/dep-graph-caller-callee.rs`], or the tests below.

```rust,ignore
#[rustc_if_this_changed]
fn foo() { }

#[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK
fn bar() { foo(); }
```

This should be read as
> If this (`foo`) is changed, then this (i.e. `bar`)'s TypeckTables would need to be changed.

Technically, what occurs is that the test is expected to emit the string "OK" on
stderr, associated to this line.

You could also add the lines

```rust,ignore
#[rustc_then_this_would_need(TypeckTables)] //~ ERROR no path
fn baz() { }
```

Whose meaning is
> If `foo` is changed, then `baz`'s TypeckTables does not need to be changed.
> The macro must emit an error, and the error message must contains "no path".

Recall that the `//~ ERROR OK` is a comment from the point of view of the Rust
code we test, but is meaningful from the point of view of the test itself.

## Debugging the dependency graph

### Dumping the graph

The compiler is also capable of dumping the dependency graph for your debugging pleasure.
To do so, pass the `-Z dump-dep-graph` flag.
The graph will be dumped to `dep_graph.{txt,dot}` in the current
directory.
You can override the filename with the `RUST_DEP_GRAPH` environment variable.

Frequently, though, the full dep graph is quite overwhelming and not particularly helpful.
Therefore, the compiler also allows you to filter the graph.
You can filter in three ways:

1. All edges originating in a particular set of nodes (usually a single node).
2. All edges reaching a particular set of nodes.
3. All edges that lie between given start and end nodes.

To filter, use the `RUST_DEP_GRAPH_FILTER` environment variable, which should
look like one of the following:

```text
source_filter     // nodes originating from source_filter
-> target_filter  // nodes that can reach target_filter
source_filter -> target_filter // nodes in between source_filter and target_filter
```

`source_filter` and `target_filter` are a `&`-separated list of strings.
A node is considered to match a filter if all of those strings appear in its label.
So, for example:

```text
RUST_DEP_GRAPH_FILTER='-> TypeckTables'
```

would select the predecessors of all `TypeckTables` nodes.
Usually though you want the `TypeckTables` node for some particular fn, so you might write:

```text
RUST_DEP_GRAPH_FILTER='-> TypeckTables & bar'
```

This will select only the predecessors of `TypeckTables` nodes for functions
with `bar` in their name.

Perhaps you are finding that when you change `foo` you need to re-type-check
`bar`, but you don't think you should have to.
In that case, you might do:

```text
RUST_DEP_GRAPH_FILTER='Hir & foo -> TypeckTables & bar'
```

This will dump out all the nodes that lead from `Hir(foo)` to
`TypeckTables(bar)`, from which you can (hopefully) see the source of the erroneous edge.

### Tracking down incorrect edges

Sometimes, after you dump the dependency graph, you will find some
path that should not exist, but you will not be quite sure how it came to be.
**When the compiler is built with debug assertions,** it can help you track that down.
Simply set the `RUST_FORBID_DEP_GRAPH_EDGE` environment variable to a filter.
Every edge created in the dep-graph
will be tested against that filter – if it matches, a `bug!` is
reported, so you can easily see the backtrace (`RUST_BACKTRACE=1`).

The syntax for these filters is the same as described in the previous section.
However, note that this filter is applied to every **edge**
and doesn't handle longer paths in the graph, unlike the previous section.

Example:

You find that there is a path from the `Hir` of `foo` to the type
check of `bar` and you don't think there should be.
You dump the dep-graph as described in the previous section and open `dep-graph.txt`
to see something like:

```text
Hir(foo) -> Collect(bar)
Collect(bar) -> TypeckTables(bar)
```

That first edge looks suspicious to you.
So you set `RUST_FORBID_DEP_GRAPH_EDGE` to `Hir&foo -> Collect&bar`, re-run, and
then observe the backtrace.
Voila, bug fixed!

---

--- METRICS ---
- Files Extracted: 100
- Estimated Token Budget: ~137443 tokens
- Canonical Reference: https://codewiki.google/github.com/rust-lang/rust
