diff --git a/.travis.yml b/.travis.yml index 1e5d86993..1d6747258 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/README.md b/README.md index c8507374e..459564364 100644 --- a/README.md +++ b/README.md @@ -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 `` 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 diff --git a/book.toml b/book.toml index af9cd167f..bad4fe1aa 100644 --- a/book.toml +++ b/book.toml @@ -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" diff --git a/src/about-this-guide.md b/src/about-this-guide.md index 740a8c7bc..d12f5a7a3 100644 --- a/src/about-this-guide.md +++ b/src/about-this-guide.md @@ -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_ diff --git a/src/backend/backend-agnostic.md b/src/backend/backend-agnostic.md index e02bbfe52..52532c258 100644 --- a/src/backend/backend-agnostic.md +++ b/src/backend/backend-agnostic.md @@ -1,5 +1,7 @@ # Backend Agnostic Codegen + + As of January 2021, `rustc_codegen_ssa` provides an abstract interface for all backends to implement, to allow other codegen backends (e.g. [Cranelift]). diff --git a/src/backend/implicit-caller-location.md b/src/backend/implicit-caller-location.md index a621b57b1..02eea5bab 100644 --- a/src/backend/implicit-caller-location.md +++ b/src/backend/implicit-caller-location.md @@ -1,9 +1,11 @@ # Implicit Caller Location + + 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::() == 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. diff --git a/src/backend/monomorph.md b/src/backend/monomorph.md index e678b4f76..0457c1841 100644 --- a/src/backend/monomorph.md +++ b/src/backend/monomorph.md @@ -1,5 +1,7 @@ # Monomorphization + + 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 | diff --git a/src/backend/updating-llvm.md b/src/backend/updating-llvm.md index 015514bab..df91c8d01 100644 --- a/src/backend/updating-llvm.md +++ b/src/backend/updating-llvm.md @@ -1,5 +1,7 @@ # Updating LLVM + + 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 diff --git a/src/borrow_check/moves_and_initialization/move_paths.md b/src/borrow_check/moves_and_initialization/move_paths.md index 2c7c73038..e38b923cf 100644 --- a/src/borrow_check/moves_and_initialization/move_paths.md +++ b/src/borrow_check/moves_and_initialization/move_paths.md @@ -1,5 +1,7 @@ # Move paths + + 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, Vec) = (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 diff --git a/src/borrow_check/region_inference.md b/src/borrow_check/region_inference.md index d8cfab00c..e14bc4157 100644 --- a/src/borrow_check/region_inference.md +++ b/src/borrow_check/region_inference.md @@ -1,5 +1,7 @@ # Region inference (NLL) + + The MIR-based region checking code is located in [the `rustc_mir::borrow_check` module][nll]. diff --git a/src/borrow_check/region_inference/constraint_propagation.md b/src/borrow_check/region_inference/constraint_propagation.md index 1389628c8..f0a7f7353 100644 --- a/src/borrow_check/region_inference/constraint_propagation.md +++ b/src/borrow_check/region_inference/constraint_propagation.md @@ -1,5 +1,7 @@ # Constraint propagation + + 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 diff --git a/src/borrow_check/region_inference/lifetime_parameters.md b/src/borrow_check/region_inference/lifetime_parameters.md index 9d6b229ef..c65b8ce5a 100644 --- a/src/borrow_check/region_inference/lifetime_parameters.md +++ b/src/borrow_check/region_inference/lifetime_parameters.md @@ -1,5 +1,7 @@ # Universal regions + + "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" diff --git a/src/borrow_check/region_inference/member_constraints.md b/src/borrow_check/region_inference/member_constraints.md index 4aa63a13c..fd65acf1a 100644 --- a/src/borrow_check/region_inference/member_constraints.md +++ b/src/borrow_check/region_inference/member_constraints.md @@ -1,5 +1,7 @@ # Member constraints + + 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 diff --git a/src/borrow_check/region_inference/placeholders_and_universes.md b/src/borrow_check/region_inference/placeholders_and_universes.md index 169f1b486..20775038b 100644 --- a/src/borrow_check/region_inference/placeholders_and_universes.md +++ b/src/borrow_check/region_inference/placeholders_and_universes.md @@ -1,5 +1,7 @@ # Placeholders and universes + + From time to time we have to reason about regions that we can't concretely know. For example, consider this program: diff --git a/src/bug-fix-procedure.md b/src/bug-fix-procedure.md index 69732b627..66b200f9e 100644 --- a/src/bug-fix-procedure.md +++ b/src/bug-fix-procedure.md @@ -1,4 +1,7 @@ # Rustc Bug Fix Procedure + + + 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 diff --git a/src/building/bootstrapping.md b/src/building/bootstrapping.md index 3e5cabbe8..0ddd2e5e8 100644 --- a/src/building/bootstrapping.md +++ b/src/building/bootstrapping.md @@ -1,5 +1,7 @@ # Bootstrapping the Compiler + + This subchapter is about the bootstrapping process. ## What is bootstrapping? How does it work? diff --git a/src/compiler-debugging.md b/src/compiler-debugging.md index a04ef0ea9..ecb9e30c2 100644 --- a/src/compiler-debugging.md +++ b/src/compiler-debugging.md @@ -1,6 +1,8 @@ # Debugging the compiler [debugging]: #debugging + + 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 diff --git a/src/compiler-src.md b/src/compiler-src.md index bcf169a13..5965fd374 100644 --- a/src/compiler-src.md +++ b/src/compiler-src.md @@ -1,11 +1,13 @@ # High-level overview of the compiler source + + > **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 diff --git a/src/contributing.md b/src/contributing.md index cc1605d1a..83d5e95cb 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -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) + 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 `` marker. [rdg]: https://rustc-dev-guide.rust-lang.org/ [rdgrepo]: https://github.com/rust-lang/rustc-dev-guide diff --git a/src/debugging-support-in-rustc.md b/src/debugging-support-in-rustc.md index 5422e18dc..559031148 100644 --- a/src/debugging-support-in-rustc.md +++ b/src/debugging-support-in-rustc.md @@ -1,5 +1,7 @@ # Debugging support in the Rust compiler + + 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 diff --git a/src/diagnostics.md b/src/diagnostics.md index c88074748..f59844d4c 100644 --- a/src/diagnostics.md +++ b/src/diagnostics.md @@ -1,5 +1,7 @@ # 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. diff --git a/src/getting-started.md b/src/getting-started.md index d70c3776e..0fc5cd8e8 100644 --- a/src/getting-started.md +++ b/src/getting-started.md @@ -1,5 +1,7 @@ # Getting Started + + 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). diff --git a/src/git.md b/src/git.md index 8775b70e6..611c47124 100644 --- a/src/git.md +++ b/src/git.md @@ -1,5 +1,7 @@ # 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. diff --git a/src/hir.md b/src/hir.md index 014136bde..51e18973b 100644 --- a/src/hir.md +++ b/src/hir.md @@ -1,5 +1,7 @@ # 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 @@ -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 -### 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 diff --git a/src/llvm-coverage-instrumentation.md b/src/llvm-coverage-instrumentation.md index 23117f527..88831f69d 100644 --- a/src/llvm-coverage-instrumentation.md +++ b/src/llvm-coverage-instrumentation.md @@ -1,5 +1,7 @@ # LLVM Source-Based Code Coverage + + `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 diff --git a/src/macro-expansion.md b/src/macro-expansion.md index 40342a703..352d826d3 100644 --- a/src/macro-expansion.md +++ b/src/macro-expansion.md @@ -1,5 +1,7 @@ # Macro expansion + + > `rustc_ast`, `rustc_expand`, and `rustc_builtin_macros` are all undergoing > refactoring, so some of the links in this chapter may be broken. diff --git a/src/mir/construction.md b/src/mir/construction.md index 010305556..d2c5a6f34 100644 --- a/src/mir/construction.md +++ b/src/mir/construction.md @@ -1,5 +1,7 @@ # THIR and MIR construction + + The lowering of [HIR] to [MIR] occurs for the following (probably incomplete) list of items: diff --git a/src/mir/dataflow.md b/src/mir/dataflow.md index e3413c5e9..9958f19b9 100644 --- a/src/mir/dataflow.md +++ b/src/mir/dataflow.md @@ -1,5 +1,7 @@ # Dataflow Analysis + + 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` diff --git a/src/mir/index.md b/src/mir/index.md index 55a4a4349..5d1376975 100644 --- a/src/mir/index.md +++ b/src/mir/index.md @@ -1,5 +1,7 @@ # The MIR (Mid-level IR) + + 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 diff --git a/src/miri.md b/src/miri.md index 71a7e6cde..d0766a07b 100644 --- a/src/miri.md +++ b/src/miri.md @@ -1,5 +1,7 @@ # Miri + + 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. diff --git a/src/name-resolution.md b/src/name-resolution.md index 3785e3aa7..2eb76384c 100644 --- a/src/name-resolution.md +++ b/src/name-resolution.md @@ -1,5 +1,7 @@ # Name resolution + + 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. diff --git a/src/overview.md b/src/overview.md index 4fe40c42f..5a63d6066 100644 --- a/src/overview.md +++ b/src/overview.md @@ -1,5 +1,7 @@ # Overview of the Compiler + + This chapter is about the overall process of compiling a program -- how everything fits together. diff --git a/src/panic-implementation.md b/src/panic-implementation.md index 7c10ae215..66e61548e 100644 --- a/src/panic-implementation.md +++ b/src/panic-implementation.md @@ -1,13 +1,15 @@ -### Panicking in rust ### +# Panicking in rust -#### Step 1: Invocation of the `panic!` macro. + + +## 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` diff --git a/src/profile-guided-optimization.md b/src/profile-guided-optimization.md index 09587e6bf..145bb053c 100644 --- a/src/profile-guided-optimization.md +++ b/src/profile-guided-optimization.md @@ -1,5 +1,7 @@ # Profile Guided Optimization + + `rustc` supports doing profile-guided optimization (PGO). This chapter describes what PGO is and how the support for it is implemented in `rustc`. diff --git a/src/queries/incremental-compilation-in-detail.md b/src/queries/incremental-compilation-in-detail.md index c00ed042e..f0c6dcacd 100644 --- a/src/queries/incremental-compilation-in-detail.md +++ b/src/queries/incremental-compilation-in-detail.md @@ -1,5 +1,7 @@ # Incremental Compilation In Detail + + The incremental compilation scheme is, in essence, a surprisingly simple extension to the overall query system. It relies on the fact that: diff --git a/src/queries/incremental-compilation.md b/src/queries/incremental-compilation.md index 5ff189f96..abef144d7 100644 --- a/src/queries/incremental-compilation.md +++ b/src/queries/incremental-compilation.md @@ -1,5 +1,7 @@ # Incremental compilation + + 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" – diff --git a/src/queries/profiling.md b/src/queries/profiling.md index f124d453a..8cd4c07d8 100644 --- a/src/queries/profiling.md +++ b/src/queries/profiling.md @@ -1,4 +1,7 @@ # Profiling Queries + + + In an effort to support _incremental compilation_, the latest design of the Rust compiler consists of a _query-based_ model. diff --git a/src/queries/query-evaluation-model-in-detail.md b/src/queries/query-evaluation-model-in-detail.md index 54f750bbd..51501d3d5 100644 --- a/src/queries/query-evaluation-model-in-detail.md +++ b/src/queries/query-evaluation-model-in-detail.md @@ -1,7 +1,7 @@ - - # The Query Evaluation Model in Detail + + 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 diff --git a/src/rustdoc-internals.md b/src/rustdoc-internals.md index 895263b53..78ceb8db6 100644 --- a/src/rustdoc-internals.md +++ b/src/rustdoc-internals.md @@ -1,5 +1,7 @@ # Rustdoc internals + + This page describes rustdoc's passes and modes. For an overview of rustdoc, see [`rustdoc`](./rustdoc.md). diff --git a/src/salsa.md b/src/salsa.md index 36aeb18bf..38db066c5 100644 --- a/src/salsa.md +++ b/src/salsa.md @@ -1,5 +1,7 @@ # How Salsa works + + 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 diff --git a/src/stability.md b/src/stability.md index c9e7056d6..69e434c07 100644 --- a/src/stability.md +++ b/src/stability.md @@ -1,5 +1,7 @@ # Stability attributes + + This section is about the stability attributes and schemes that allow stable APIs to use unstable APIs internally in the rustc standard library. diff --git a/src/stabilization_guide.md b/src/stabilization_guide.md index 2cdb0037b..f4f58c392 100644 --- a/src/stabilization_guide.md +++ b/src/stabilization_guide.md @@ -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 + ## Documentation PRs diff --git a/src/test-implementation.md b/src/test-implementation.md index 230e2fe36..1a9283b59 100644 --- a/src/test-implementation.md +++ b/src/test-implementation.md @@ -1,4 +1,7 @@ -### The `#[test]` attribute +# The `#[test]` attribute + + + 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: diff --git a/src/tests/adding.md b/src/tests/adding.md index 774ccc3ef..868bad2d7 100644 --- a/src/tests/adding.md +++ b/src/tests/adding.md @@ -1,5 +1,7 @@ # Adding new tests + + **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 diff --git a/src/tests/intro.md b/src/tests/intro.md index 04deb427a..cab06df55 100644 --- a/src/tests/intro.md +++ b/src/tests/intro.md @@ -1,5 +1,7 @@ # The compiler testing framework + + 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 diff --git a/src/tests/running.md b/src/tests/running.md index 4fe61f30a..842a73c07 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -1,5 +1,7 @@ # Running tests + + You can run the tests using `x.py`. The most basic command – which you will almost never want to use! – is as follows: diff --git a/src/traits/goals-and-clauses.md b/src/traits/goals-and-clauses.md index 9aaab96fa..4315b3e0f 100644 --- a/src/traits/goals-and-clauses.md +++ b/src/traits/goals-and-clauses.md @@ -1,5 +1,7 @@ # Goals and clauses + + 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)` in the `loud_insert` example because we will verify `WellFormed(HashSet)` for each call site of -`loud_insert`. +`loud_insert`. #### Outlives(Type: Region), Outlives(Region: Region) e.g. `Outlives(&'a str: 'b)`, `Outlives('a: 'static)` diff --git a/src/traits/lowering-to-logic.md b/src/traits/lowering-to-logic.md index cc8b3bf80..1248d4346 100644 --- a/src/traits/lowering-to-logic.md +++ b/src/traits/lowering-to-logic.md @@ -1,5 +1,7 @@ # Lowering to logic + + 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 diff --git a/src/traits/resolution.md b/src/traits/resolution.md index 3041b85d8..863631320 100644 --- a/src/traits/resolution.md +++ b/src/traits/resolution.md @@ -1,5 +1,7 @@ # Trait resolution (old-style) + + This chapter describes the general process of _trait resolution_ and points out some non-obvious things. diff --git a/src/ty.md b/src/ty.md index 49f6405fa..9ee2ccfe2 100644 --- a/src/ty.md +++ b/src/ty.md @@ -1,5 +1,7 @@ # The `ty` module: representing types + + 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`). diff --git a/src/type-inference.md b/src/type-inference.md index 9c548364d..9d23b6278 100644 --- a/src/type-inference.md +++ b/src/type-inference.md @@ -1,5 +1,7 @@ # Type inference + + Type inference is the process of automatic detection of the type of an expression. diff --git a/src/variance.md b/src/variance.md index af23330e8..c03de7a20 100644 --- a/src/variance.md +++ b/src/variance.md @@ -1,5 +1,7 @@ # Variance of type and lifetime parameters + + For a more general background on variance, see the [background] appendix. [background]: ./appendix/background.html diff --git a/src/walkthrough.md b/src/walkthrough.md index 8a41b3dd8..b0d040942 100644 --- a/src/walkthrough.md +++ b/src/walkthrough.md @@ -1,5 +1,7 @@ # Walkthrough: a typical contribution + + 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.