Add mdbook-toc, markers, and documentation (#1028)

* Add mdbook-toc to travis, book.toml  and documentation

* Add toc markers

* Whitespace cleanup and some punctuation

* Addressed comments
This commit is contained in:
Iñaki Garay 2021-01-20 14:33:11 -03:00 committed by GitHub
parent d8d5bbcfe3
commit 7a80b01e01
53 changed files with 177 additions and 76 deletions

View File

@ -13,6 +13,7 @@ install:
- source ~/.cargo/env || true
- cargo install mdbook --version '^0.4.5'
- cargo install mdbook-linkcheck --version '^0.7.2'
- cargo install mdbook-toc --version '^0.6.1'
script:
- git checkout -b ci
- git rebase origin/master

View File

@ -40,7 +40,7 @@ rustdocs][rustdocs].
To build a local static HTML site, install [`mdbook`](https://github.com/rust-lang/mdBook) with:
```
> cargo install mdbook mdbook-linkcheck
> cargo install mdbook mdbook-linkcheck mdbook-toc
```
and execute the following command in the root of the repository:
@ -56,6 +56,11 @@ The build files are found in the `book` directory.
We use `mdbook-linkcheck` to validate URLs included in our documentation.
`linkcheck` will be run automatically when you build with the instructions in the section above.
### Table of Contents
We use `mdbook-toc` to auto-generate TOCs for long sections. You can invoke the preprocessor by
including the `<!-- toc -->` marker at the place where you want the TOC.
### Pre-commit script
We also test that line lengths are less than 100 columns. To test this locally,
@ -95,7 +100,7 @@ but we leave these instructions for when we do it again in the future.
7. Click on the log and Ctrl-f to get a search box in the log
8. Search for rustc-dev-guide. This gets you to the place where the links are checked. It is usually ~11K lines into the log
8. Search for rustc-dev-guide. This gets you to the place where the links are checked. It is usually ~11K lines into the log.
9. Look at the links in the log near that point in the log

View File

@ -6,6 +6,10 @@ description = "A guide to developing rustc"
[build]
create-missing = false
[preprocessor.toc]
command = "mdbook-toc"
renderer = ["html"]
[output.html]
git-repository-url = "https://github.com/rust-lang/rustc-dev-guide"

View File

@ -47,7 +47,7 @@ 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.md#contributing-to-rustc-dev-guide.
[subsection on writing documentation in this guide]: contributing.md#contributing-to-rustc-dev-guide
> “All conditioned things are impermanent — when one sees this with wisdom, one turns away from
> suffering.” _The Dhammapada, verse 277_

View File

@ -1,5 +1,7 @@
# Backend Agnostic Codegen
<!-- toc -->
As of January 2021, `rustc_codegen_ssa` provides an abstract interface for all backends to
implement, to allow other codegen backends (e.g. [Cranelift]).

View File

@ -1,9 +1,11 @@
# Implicit Caller Location
<!-- toc -->
Approved in [RFC 2091], this feature enables the accurate reporting of caller location during panics
initiated from functions like `Option::unwrap`, `Result::expect`, and `Index::index`. This feature
adds the [`#[track_caller]`][attr-reference] attribute for functions, the
[`caller_location`][intrinsic] intrinsic, and the stabilization-friendly
initiated from functions like `Option::unwrap`, `Result::expect`, and `Index::index`. This feature
adds the [`#[track_caller]`][attr-reference] attribute for functions, the
[`caller_location`][intrinsic] intrinsic, and the stabilization-friendly
[`core::panic::Location::caller`][wrapper] wrapper.
## Motivating Example
@ -28,25 +30,25 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
As of 1.42, we get a much more helpful message:
```
$ rustc +1.42.0 example.rs; example.exe
$ rustc +1.42.0 example.rs; example.exe
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', example.rs:3:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
These error messages are achieved through a combination of changes to `panic!` internals to make use
of `core::panic::Location::caller` and a number of `#[track_caller]` annotations in the standard
of `core::panic::Location::caller` and a number of `#[track_caller]` annotations in the standard
library which propagate caller information.
## Reading Caller Location
Previously, `panic!` made use of the `file!()`, `line!()`, and `column!()` macros to construct a
[`Location`] pointing to where the panic occurred. These macros couldn't be given an overridden
location, so functions which intentionally invoked `panic!` couldn't provide their own location,
location, so functions which intentionally invoked `panic!` couldn't provide their own location,
hiding the actual source of error.
Internally, `panic!()` now calls [`core::panic::Location::caller()`][wrapper] to find out where it
was expanded. This function is itself annotated with `#[track_caller]` and wraps the
[`caller_location`][intrinsic] compiler intrinsic implemented by rustc. This intrinsic is easiest
Internally, `panic!()` now calls [`core::panic::Location::caller()`][wrapper] to find out where it
was expanded. This function is itself annotated with `#[track_caller]` and wraps the
[`caller_location`][intrinsic] compiler intrinsic implemented by rustc. This intrinsic is easiest
explained in terms of how it works in a `const` context.
## Caller Location in `const`
@ -56,20 +58,20 @@ to find the right location and allocating a const value to return.
### Finding the right `Location`
In a const context we "walk up the stack" from where the intrinsic is invoked, stopping when we
In a const context we "walk up the stack" from where the intrinsic is invoked, stopping when we
reach the first function call in the stack which does *not* have the attribute. This walk is in
[`InterpCx::find_closest_untracked_caller_location()`][const-find-closest].
Starting at the bottom, we iterate up over stack [`Frame`][const-frame]s in the
Starting at the bottom, we iterate up over stack [`Frame`][const-frame]s in the
[`InterpCx::stack`][const-stack], calling
[`InstanceDef::requires_caller_location`][requires-location] on the
[`InstanceDef::requires_caller_location`][requires-location] on the
[`Instance`s from each `Frame`][frame-instance]. We stop once we find one that returns `false` and
return the span of the *previous* frame which was the "topmost" tracked function.
### Allocating a static `Location`
Once we have a `Span`, we need to allocate static memory for the `Location`, which is performed by
the [`TyCtxt::const_caller_location()`][const-location-query] query. Internally this calls
Once we have a `Span`, we need to allocate static memory for the `Location`, which is performed by
the [`TyCtxt::const_caller_location()`][const-location-query] query. Internally this calls
[`InterpCx::alloc_caller_location()`][alloc-location] and results in a unique
[memory kind][location-memory-kind] (`MemoryKind::CallerLocation`). The SSA codegen backend is able
to emit code for these same values, and we use this code there as well.
@ -78,14 +80,14 @@ Once our `Location` has been allocated in static memory, our intrinsic returns a
## Generating code for `#[track_caller]` callees
To generate efficient code for a tracked function and its callers, we need to provide the same
To generate efficient code for a tracked function and its callers, we need to provide the same
behavior from the intrinsic's point of view without having a stack to walk up at runtime. We invert
the approach: as we grow the stack down we pass an additional argument to calls of tracked functions
rather than walking up the stack when the intrinsic is called. That additional argument can be
returned wherever the caller location is queried.
The argument we append is of type `&'static core::panic::Location<'static>`. A reference was chosen
to avoid unnecessary copying because a pointer is a third the size of
to avoid unnecessary copying because a pointer is a third the size of
`std::mem::size_of::<core::panic::Location>() == 24` at time of writing.
When generating a call to a function which is tracked, we pass the location argument the value of
@ -151,12 +153,12 @@ probably the best we can do without modifying fully-stabilized type signatures.
> *Note:* We always emit a [`ReifyShim`] when taking a pointer to a tracked function. While the
> constraint here is imposed by codegen contexts, we don't know during MIR construction of the shim
> whether we'll be called in a const context (safe to ignore shim) or in a codegen context (unsafe
> whether we'll be called in a const context (safe to ignore shim) or in a codegen context (unsafe
> to ignore shim). Even if we did know, the results from const and codegen contexts must agree.
## The Attribute
The `#[track_caller]` attribute is checked alongside other codegen attributes to ensure the
The `#[track_caller]` attribute is checked alongside other codegen attributes to ensure the
function:
* has the `"Rust"` ABI (as opposed to e.g., `"C"`)
@ -171,7 +173,7 @@ used in both const and codegen contexts to ensure correct propagation.
When applied to trait method implementations, the attribute works as it does for regular functions.
When applied to a trait method prototype, the attribute applies to all implementations of the
When applied to a trait method prototype, the attribute applies to all implementations of the
method. When applied to a default trait method implementation, the attribute takes effect on
that implementation *and* any overrides.
@ -203,14 +205,14 @@ trait TrackedFourWays {
assert_tracked!();
}
/// Overrides of this implementation are tracked (it is too).
/// Overrides of this implementation are tracked (it is too).
#[track_caller]
fn default_tracked_to_override() {
assert_tracked!();
}
}
/// This impl uses the default impl for `default_tracked` and provides its own for
/// This impl uses the default impl for `default_tracked` and provides its own for
/// `default_tracked_to_override`.
impl TrackedFourWays for () {
fn blanket_tracked() {
@ -253,7 +255,7 @@ up on the tracking issue. During the course of implementing that, it was also di
implementation was possible without modifying the number of arguments in a function's MIR, which
would simplify later stages and unlock use in traits.
Because the RFC's implementation strategy could not readily support traits, the semantics were not
Because the RFC's implementation strategy could not readily support traits, the semantics were not
originally specified. They have since been implemented following the path which seemed most correct
to the author and reviewers.

View File

@ -1,5 +1,7 @@
# Monomorphization
<!-- toc -->
As you probably know, rust has a very expressive type system that has extensive
support for generic types. But of course, assembly is not generic, so we need
to figure out the concrete types of all the generics before the code can
@ -57,12 +59,12 @@ units](../appendix/glossary.md#codegen-unit).
## Codegen Unit (CGU) partitioning
For better incremental build times, the CGU partitioner creates two CGU for each source level
modules. One is for "stable" i.e. non-generic code and the other is more volatile code i.e.
For better incremental build times, the CGU partitioner creates two CGU for each source level
modules. One is for "stable" i.e. non-generic code and the other is more volatile code i.e.
monoporphized/specialized instances.
For depenencies, consider Crate A and Crate B, such that Crate B depends on Crate A.
The following table lists different scenarios for a function in Crate A that might be used by one
The following table lists different scenarios for a function in Crate A that might be used by one
or more modules in Crate B.
| Crate A function | Behavior |

View File

@ -1,5 +1,7 @@
# Updating LLVM
<!-- toc -->
The Rust compiler uses LLVM as its primary codegen backend today, and naturally
we want to at least occasionally update this dependency! Currently we do not
have a strict policy about when to update LLVM or what it can be updated to, but

View File

@ -1,5 +1,7 @@
# Move paths
<!-- toc -->
In reality, it's not enough to track initialization at the granularity
of local variables. Rust also allows us to do moves and initialization
at the field granularity:
@ -7,11 +9,11 @@ at the field granularity:
```rust,ignore
fn foo() {
let a: (Vec<u32>, Vec<u32>) = (vec![22], vec![44]);
// a.0 and a.1 are both initialized
let b = a.0; // moves a.0
// a.0 is not initialized, but a.1 still is
let c = a.0; // ERROR
@ -73,7 +75,7 @@ there is no need for a [`MovePathIndex`]. Some examples:
there would be no move-path for `foo[1]`.
- You cannot move from inside of a borrowed reference, so if we have e.g. `foo: &String`,
there would be no move-path for `*foo`.
These rules are enforced by the [`move_path_for`] function, which
converts a [`Place`] into a [`MovePathIndex`] -- in error cases like
those just discussed, the function returns an `Err`. This in turn
@ -102,7 +104,7 @@ of [`MoveData`]. There are two different methods:
[`LookupResult`] indicating the closest path it was able to find
that exists (e.g., for `foo[1]`, it might return just the path for
`foo`).
[`find`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir/dataflow/move_paths/struct.MovePathLookup.html#method.find
[`find_local`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir/dataflow/move_paths/struct.MovePathLookup.html#method.find_local
[`mir::Local`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Local.html
@ -120,7 +122,7 @@ just over the paths that are **actually referenced** in the source,
not all **possible** paths that could have been referenced). These
references are used for example in the
[`find_in_move_path_or_its_descendants`] function, which determines
whether a move-path (e.g., `a.b`) or any child of that move-path
whether a move-path (e.g., `a.b`) or any child of that move-path
(e.g.,`a.b.c`) matches a given predicate.
[`Place`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Place.html

View File

@ -1,5 +1,7 @@
# Region inference (NLL)
<!-- toc -->
The MIR-based region checking code is located in [the `rustc_mir::borrow_check`
module][nll].

View File

@ -1,5 +1,7 @@
# Constraint propagation
<!-- toc -->
The main work of the region inference is **constraint propagation**,
which is done in the [`propagate_constraints`] function. There are
three sorts of constraints that are used in NLL, and we'll explain how

View File

@ -1,5 +1,7 @@
# Universal regions
<!-- toc -->
"Universal regions" is the name that the code uses to refer to "named
lifetimes" -- e.g., lifetime parameters and `'static`. The name
derives from the fact that such lifetimes are "universally quantified"

View File

@ -1,5 +1,7 @@
# Member constraints
<!-- toc -->
A member constraint `'m member of ['c_1..'c_N]` expresses that the
region `'m` must be *equal* to some **choice regions** `'c_i` (for
some `i`). These constraints cannot be expressed by users, but they

View File

@ -1,5 +1,7 @@
# Placeholders and universes
<!-- toc -->
From time to time we have to reason about regions that we can't
concretely know. For example, consider this program:

View File

@ -1,4 +1,7 @@
# Rustc Bug Fix Procedure
<!-- toc -->
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

View File

@ -1,5 +1,7 @@
# Bootstrapping the Compiler
<!-- toc -->
This subchapter is about the bootstrapping process.
## What is bootstrapping? How does it work?

View File

@ -1,6 +1,8 @@
# Debugging the compiler
[debugging]: #debugging
<!-- toc -->
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
@ -9,14 +11,14 @@ chapter](./backend/debugging.md)).
## Configuring the compiler
By default, rustc is built without most debug information. To enable debug info,
set `debug = true` in your config.toml.
By default, rustc is built without most debug information. To enable debug info,
set `debug = true` in your config.toml.
Setting `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
Setting `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 `debug = true`. Check out the comments in config.toml.example for more info.
You will need to rebuild the compiler once you've changed any configuration options.
You will need to rebuild the compiler once you've changed any configuration options.
## `-Z` flags
@ -36,7 +38,7 @@ 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
In the default configuration (without `debug` set to `true`), you don't have line numbers
enabled, so the backtrace looks like this:
```text
@ -56,7 +58,7 @@ stack backtrace:
37: rustc_driver::run_compiler
```
If you set `debug = true`, you will get line numbers for the stack trace.
If you set `debug = true`, you will get line numbers for the stack trace.
Then the backtrace will look like this:
```text

View File

@ -1,11 +1,13 @@
# High-level overview of the compiler source
<!-- toc -->
> **NOTE**: The structure of the repository is going through a lot of
> transitions. In particular, we want to get to a point eventually where the
> top-level directory has separate directories for the compiler, build-system,
> std libs, etc, rather than one huge `src/` directory.
>
> As of this writing, the std libs have been moved to `library/` and the crates
> As of January 2021, the std libs have been moved to `library/` and the crates
> that make up the `rustc` compiler itself have been moved to `compiler/`
Now that we have [seen what the compiler does](./overview.md), let's take a

View File

@ -3,14 +3,7 @@
Thank you for your interest in contributing to Rust! There are many ways to
contribute, and we appreciate all of them.
* [Feature Requests](#feature-requests)
* [Bug Reports](#bug-reports)
* [The Build System](./building/how-to-build-and-run.md)
* [Pull Requests](#pull-requests)
* [Writing Documentation](#writing-documentation)
* [Issue Triage](#issue-triage)
* [Out-of-tree Contributions](#out-of-tree-contributions)
* [Helpful Links and Information](#helpful-links-and-information)
<!-- toc -->
If you have questions, please make a post on [internals.rust-lang.org][internals] or
hop on the [Rust Discord server][rust-discord] or [Rust Zulip server][rust-zulip].
@ -423,6 +416,9 @@ Just a few things to keep in mind:
- 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.
- If a text grows rather long (more than a few page scrolls) or complicated (more than four
subsections) it might benefit from having a Table of Contents at the beginning, which you can
auto-generate by including the `<!-- toc -->` marker.
[rdg]: https://rustc-dev-guide.rust-lang.org/
[rdgrepo]: https://github.com/rust-lang/rustc-dev-guide

View File

@ -1,5 +1,7 @@
# Debugging support in the Rust compiler
<!-- toc -->
This document explains the state of debugging tools support in the Rust compiler (rustc).
The document gives an overview of debugging tools like GDB, LLDB etc. and infrastructure
around Rust compiler to debug Rust code. If you want to learn how to debug the Rust compiler

View File

@ -1,5 +1,7 @@
# Errors and Lints
<!-- toc -->
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.

View File

@ -1,5 +1,7 @@
# Getting Started
<!-- toc -->
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 this
chapter on how to build and run the compiler](./building/how-to-build-and-run.md).

View File

@ -1,5 +1,7 @@
# Using Git
<!-- toc -->
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.

View File

@ -1,5 +1,7 @@
# The HIR
<!-- toc -->
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
@ -18,7 +20,7 @@ You can view the HIR representation of your code by passing the
cargo rustc -- -Z unpretty=hir-tree
```
### Out-of-band storage and the `Crate` type
## 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
@ -66,7 +68,7 @@ the compiler a chance to observe that you accessed the data for
<a name="hir-id"></a>
### Identifiers in the HIR
## Identifiers in the HIR
There are a bunch of different identifiers to refer to other nodes or definitions
in the HIR. In short:
@ -81,7 +83,7 @@ For more detailed information, check out the [chapter on identifiers][ids].
[`HirId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir_id/struct.HirId.html
[ids]: ./identifiers.md#in-the-hir
### The HIR Map
## The HIR Map
Most of the time when you are working with the HIR, you will do so via
the **HIR Map**, accessible in the tcx via [`tcx.hir()`] (and defined in
@ -124,7 +126,7 @@ calls like [`tcx.hir().get_parent_node(n)`][get_parent_node].
[get_parent_node]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.get_parent_node
### HIR Bodies
## 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

View File

@ -1,5 +1,7 @@
# LLVM Source-Based Code Coverage
<!-- toc -->
`rustc` supports detailed source-based code and test coverage analysis
with a command line option (`-Z instrument-coverage`) that instruments Rust
libraries and binaries with additional instructions and data, at compile time.
@ -32,7 +34,7 @@ Detailed instructions and examples are documented in the
[Coverage Map]: https://llvm.org/docs/CoverageMappingFormat.html
[unstable-book-sbcc]: https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/source-based-code-coverage.html
### Rust symbol mangling
## Rust symbol mangling
`-Z instrument-coverage` automatically enables Rust symbol mangling `v0` (as
if the user specified `-Z symbol-mangling-version=v0` option when invoking

View File

@ -1,5 +1,7 @@
# Macro expansion
<!-- toc -->
> `rustc_ast`, `rustc_expand`, and `rustc_builtin_macros` are all undergoing
> refactoring, so some of the links in this chapter may be broken.

View File

@ -1,5 +1,7 @@
# THIR and MIR construction
<!-- toc -->
The lowering of [HIR] to [MIR] occurs for the following (probably incomplete)
list of items:

View File

@ -1,5 +1,7 @@
# Dataflow Analysis
<!-- toc -->
If you work on the MIR, you will frequently come across various flavors of
[dataflow analysis][wiki]. `rustc` uses dataflow to find uninitialized
variables, determine what variables are live across a generator `yield`

View File

@ -1,5 +1,7 @@
# The MIR (Mid-level IR)
<!-- toc -->
MIR is Rust's _Mid-level Intermediate Representation_. It is
constructed from [HIR](../hir.html). MIR was introduced in
[RFC 1211]. It is a radically simplified form of Rust that is used for
@ -228,7 +230,7 @@ but [you can read about those below](#promoted)).
- **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
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 enum [`Place`]. There are a few

View File

@ -1,5 +1,7 @@
# Miri
<!-- toc -->
Miri (**MIR** **I**nterpreter) is a virtual machine for executing MIR without
compiling to machine code. It is usually invoked via `tcx.const_eval_*` functions.

View File

@ -1,5 +1,7 @@
# Name resolution
<!-- toc -->
In the previous chapters, we saw how the AST is built with all macros expanded.
We saw how doing that requires doing some name resolution to resolve imports
and macro names. In this chapter, we show how this is actually done and more.

View File

@ -1,5 +1,7 @@
# Overview of the Compiler
<!-- toc -->
This chapter is about the overall process of compiling a program -- how
everything fits together.

View File

@ -1,13 +1,15 @@
### Panicking in rust ###
# Panicking in rust
#### Step 1: Invocation of the `panic!` macro.
<!-- toc -->
## Step 1: Invocation of the `panic!` macro.
There are actually two panic macros - one defined in `core`, and one defined in `std`.
This is due to the fact that code in `core` can panic. `core` is built before `std`,
but we want panics to use the same machinery at runtime, whether they originate in `core`
or `std`.
##### core definition of panic!
### core definition of panic!
The `core` `panic!` macro eventually makes the following call (in `library/core/src/panicking.rs`):
@ -57,7 +59,7 @@ Rust source).
Thus, control flow will pass from core to std at runtime. This allows panics from `core`
to go through the same infrastructure that other panics use (panic hooks, unwinding, etc)
##### std implementation of panic!
### std implementation of panic!
This is where the actual panic-related logic begins. In `library/std/src/panicking.rs`,
control passes to `rust_panic_with_hook`. This method is responsible
@ -83,7 +85,7 @@ is suitable for passing across an FFI boundary.
Finally, we call `__rust_start_panic` with this `usize`. We have now entered the panic runtime.
#### Step 2: The panic runtime
## Step 2: The panic runtime
Rust provides two panic runtimes: `panic_abort` and `panic_unwind`. The user chooses
between them at build time via their `Cargo.toml`
@ -91,7 +93,7 @@ between them at build time via their `Cargo.toml`
`panic_abort` is extremely simple: its implementation of `__rust_start_panic` just aborts,
as you would expect.
`panic_unwind` is the more interesting case.
`panic_unwind` is the more interesting case.
In its implementation of `__rust_start_panic`, we take the `usize`, convert
it back to a `*mut &mut dyn BoxMeUp`, dereference it, and call `box_me_up`

View File

@ -1,5 +1,7 @@
# Profile Guided Optimization
<!-- toc -->
`rustc` supports doing profile-guided optimization (PGO).
This chapter describes what PGO is and how the support for it is
implemented in `rustc`.

View File

@ -1,5 +1,7 @@
# Incremental Compilation In Detail
<!-- toc -->
The incremental compilation scheme is, in essence, a surprisingly
simple extension to the overall query system. It relies on the fact that:

View File

@ -1,5 +1,7 @@
# Incremental compilation
<!-- toc -->
The incremental compilation scheme is, in essence, a surprisingly
simple extension to the overall query system. We'll start by describing
a slightly simplified variant of the real thing the "basic algorithm"

View File

@ -1,4 +1,7 @@
# Profiling Queries
<!-- toc -->
In an effort to support _incremental compilation_, the latest design of the Rust
compiler consists of a _query-based_ model.

View File

@ -1,7 +1,7 @@
# The Query Evaluation Model in Detail
<!-- toc -->
This chapter provides a deeper dive into the abstract model queries are built on.
It does not go into implementation details but tries to explain
the underlying logic. The examples here, therefore, have been stripped down and

View File

@ -1,5 +1,7 @@
# Rustdoc internals
<!-- toc -->
This page describes rustdoc's passes and modes. For an overview of rustdoc,
see [`rustdoc`](./rustdoc.md).

View File

@ -1,5 +1,7 @@
# How Salsa works
<!-- toc -->
This chapter is based on the explanation given by Niko Matsakis in this
[video](https://www.youtube.com/watch?v=_muY4HjSqVw) about
[Salsa](https://github.com/salsa-rs/salsa). To find out more you may

View File

@ -1,5 +1,7 @@
# Stability attributes
<!-- toc -->
This section is about the stability attributes and schemes that allow stable
APIs to use unstable APIs internally in the rustc standard library.

View File

@ -2,12 +2,9 @@
Once an unstable feature has been well-tested with no outstanding
concern, anyone may push for its stabilization. It involves the
following steps.
following steps:
- Documentation PRs
- Write a stabilization report
- FCP
- Stabilization PR
<!-- toc -->
## Documentation PRs

View File

@ -1,4 +1,7 @@
### The `#[test]` attribute
# The `#[test]` attribute
<!-- toc -->
Today, rust programmers rely on a built in attribute called `#[test]`. All
you have to do is mark a function as a test and include some asserts like so:
@ -35,7 +38,7 @@ What exactly is `rustc --test` doing?
[`rustc_ast` crate][rustc_ast]. Essentially, it's a fancy macro, that
rewrites the crate in 3 steps:
#### Step 1: Re-Exporting
## Step 1: Re-Exporting
As mentioned earlier, tests can exist inside private modules, so we need a
way of exposing them to the main function, without breaking any existing
@ -77,7 +80,8 @@ hand-written one, it will not share a Symbol. This technique prevents name
collision during code generation and is the foundation of Rust's macro
hygiene.
#### Step 2: Harness Generation
## Step 2: Harness Generation
Now that our tests are accessible from the root of our crate, we need to do
something with them. `rustc_ast` generates a module like so:
@ -99,7 +103,8 @@ called [`test`][test] that is part of Rust core, that implements all of the
runtime for testing. `test`'s interface is unstable, so the only stable way
to interact with it is through the `#[test]` macro.
#### Step 3: Test Object Generation
## Step 3: Test Object Generation
If you've written tests in Rust before, you may be familiar with some of the
optional attributes available on test functions. For example, a test can be
annotated with `#[should_panic]` if we expect the test to cause a panic. It
@ -137,7 +142,8 @@ self::test::TestDescAndFn{
Once we've constructed an array of these test objects, they're passed to the
test runner via the harness generated in step 2.
### Inspecting the generated code
## Inspecting the generated code
On nightly rust, there's an unstable flag called `unpretty` that you can use
to print out the module source after macro expansion:

View File

@ -1,5 +1,7 @@
# Adding new tests
<!-- toc -->
**In general, we expect every PR that fixes a bug in rustc to come
accompanied by a regression test of some kind.** This test should fail
in master but pass after the PR. These tests are really useful for

View File

@ -1,5 +1,7 @@
# The compiler testing framework
<!-- toc -->
The Rust project runs a wide variety of different tests, orchestrated by
the build system (`x.py test`). The main test harness for testing the
compiler itself is a tool called compiletest (located in the

View File

@ -1,5 +1,7 @@
# Running tests
<!-- toc -->
You can run the tests using `x.py`. The most basic command which
you will almost never want to use! is as follows:

View File

@ -1,5 +1,7 @@
# Goals and clauses
<!-- toc -->
In logic programming terms, a **goal** is something that you must
prove and a **clause** is something that you know is true. As
described in the [lowering to logic](./lowering-to-logic.html)
@ -196,7 +198,7 @@ it is okay to assume `FromEnv(T: Clone)` in the `loud_clone` example is that we
_also_ verify `WellFormed(T: Clone)` for each call site of `loud_clone`.
Similarly, it is okay to assume `FromEnv(HashSet<K>)` in the `loud_insert`
example because we will verify `WellFormed(HashSet<K>)` for each call site of
`loud_insert`.
`loud_insert`.
#### Outlives(Type: Region), Outlives(Region: Region)
e.g. `Outlives(&'a str: 'b)`, `Outlives('a: 'static)`

View File

@ -1,5 +1,7 @@
# Lowering to logic
<!-- toc -->
The key observation here is that the Rust trait system is basically a
kind of logic, and it can be mapped onto standard logical inference
rules. We can then look for solutions to those inference rules in a

View File

@ -1,5 +1,7 @@
# Trait resolution (old-style)
<!-- toc -->
This chapter describes the general process of _trait resolution_ and points out
some non-obvious things.

View File

@ -1,5 +1,7 @@
# The `ty` module: representing types
<!-- toc -->
The `ty` module defines how the Rust compiler represents types internally. It also defines the
*typing context* (`tcx` or `TyCtxt`), which is the central data structure in the compiler.
@ -189,7 +191,7 @@ There are many variants on the `TyKind` enum, which you can see by looking at it
- [**Array**][kindarray] Corresponds to `[T; n]`.
- [**RawPtr**][kindrawptr] Corresponds to `*mut T` or `*const T`.
- [**Ref**][kindref] `Ref` stands for safe references, `&'a mut T` or `&'a T`. `Ref` has some
associated parts, like `Ty<'tcx>` which is the type that the reference references.
associated parts, like `Ty<'tcx>` which is the type that the reference references.
`Region<'tcx>` is the lifetime or region of the reference and `Mutability` if the reference
is mutable or not.
- [**Param**][kindparam] Represents a type parameter (e.g. the `T` in `Vec<T>`).

View File

@ -1,5 +1,7 @@
# Type inference
<!-- toc -->
Type inference is the process of automatic detection of the type of an
expression.

View File

@ -1,5 +1,7 @@
# Variance of type and lifetime parameters
<!-- toc -->
For a more general background on variance, see the [background] appendix.
[background]: ./appendix/background.html

View File

@ -1,5 +1,7 @@
# Walkthrough: a typical contribution
<!-- toc -->
There are _a lot_ of ways to contribute to the rust compiler, including fixing
bugs, improving performance, helping design features, providing feedback on
existing features, etc. This chapter does not claim to scratch the surface.