about summary refs log tree commit diff
path: root/src/doc/rustc-dev-guide
diff options
context:
space:
mode:
Diffstat (limited to 'src/doc/rustc-dev-guide')
-rw-r--r--src/doc/rustc-dev-guide/.github/workflows/ci.yml4
-rw-r--r--src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml3
-rw-r--r--src/doc/rustc-dev-guide/README.md6
-rw-r--r--src/doc/rustc-dev-guide/book.toml11
-rw-r--r--src/doc/rustc-dev-guide/pagetoc.css84
-rw-r--r--src/doc/rustc-dev-guide/pagetoc.js104
-rw-r--r--src/doc/rustc-dev-guide/rust-version2
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md1
-rw-r--r--src/doc/rustc-dev-guide/src/appendix/humorust.md2
-rw-r--r--src/doc/rustc-dev-guide/src/asm.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/backend-agnostic.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/implicit-caller-location.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/monomorph.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/updating-llvm.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/moves_and_initialization/move_paths.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference/constraint_propagation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference/lifetime_parameters.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference/placeholders_and_universes.md2
-rw-r--r--src/doc/rustc-dev-guide/src/bug-fix-procedure.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md6
-rw-r--r--src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/new-target.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/optimized-build.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/suggested.md2
-rw-r--r--src/doc/rustc-dev-guide/src/compiler-debugging.md2
-rw-r--r--src/doc/rustc-dev-guide/src/compiler-src.md2
-rw-r--r--src/doc/rustc-dev-guide/src/const-eval/interpret.md2
-rw-r--r--src/doc/rustc-dev-guide/src/contributing.md2
-rw-r--r--src/doc/rustc-dev-guide/src/coroutine-closures.md2
-rw-r--r--src/doc/rustc-dev-guide/src/crates-io.md2
-rw-r--r--src/doc/rustc-dev-guide/src/debugging-support-in-rustc.md2
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics.md2
-rw-r--r--src/doc/rustc-dev-guide/src/early_late_parameters.md2
-rw-r--r--src/doc/rustc-dev-guide/src/getting-started.md2
-rw-r--r--src/doc/rustc-dev-guide/src/git.md2
-rw-r--r--src/doc/rustc-dev-guide/src/guides/editions.md2
-rw-r--r--src/doc/rustc-dev-guide/src/hir.md2
-rw-r--r--src/doc/rustc-dev-guide/src/implementing_new_features.md2
-rw-r--r--src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/macro-expansion.md2
-rw-r--r--src/doc/rustc-dev-guide/src/mir/construction.md2
-rw-r--r--src/doc/rustc-dev-guide/src/mir/dataflow.md2
-rw-r--r--src/doc/rustc-dev-guide/src/mir/drop-elaboration.md2
-rw-r--r--src/doc/rustc-dev-guide/src/mir/index.md2
-rw-r--r--src/doc/rustc-dev-guide/src/name-resolution.md2
-rw-r--r--src/doc/rustc-dev-guide/src/normalization.md2
-rw-r--r--src/doc/rustc-dev-guide/src/overview.md2
-rw-r--r--src/doc/rustc-dev-guide/src/panic-implementation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/profile-guided-optimization.md2
-rw-r--r--src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md2
-rw-r--r--src/doc/rustc-dev-guide/src/queries/incremental-compilation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md2
-rw-r--r--src/doc/rustc-dev-guide/src/queries/salsa.md2
-rw-r--r--src/doc/rustc-dev-guide/src/query.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals/search.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc.md2
-rw-r--r--src/doc/rustc-dev-guide/src/solve/candidate-preference.md427
-rw-r--r--src/doc/rustc-dev-guide/src/stability.md5
-rw-r--r--src/doc/rustc-dev-guide/src/stabilization_guide.md2
-rw-r--r--src/doc/rustc-dev-guide/src/test-implementation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/adding.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/compiletest.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/directives.md10
-rw-r--r--src/doc/rustc-dev-guide/src/tests/docker.md15
-rw-r--r--src/doc/rustc-dev-guide/src/tests/intro.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/running.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ui.md10
-rw-r--r--src/doc/rustc-dev-guide/src/thir.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tracing.md2
-rw-r--r--src/doc/rustc-dev-guide/src/traits/goals-and-clauses.md2
-rw-r--r--src/doc/rustc-dev-guide/src/traits/lowering-to-logic.md2
-rw-r--r--src/doc/rustc-dev-guide/src/traits/resolution.md2
-rw-r--r--src/doc/rustc-dev-guide/src/ty.md2
-rw-r--r--src/doc/rustc-dev-guide/src/type-inference.md2
-rw-r--r--src/doc/rustc-dev-guide/src/typing_parameter_envs.md2
-rw-r--r--src/doc/rustc-dev-guide/src/variance.md2
-rw-r--r--src/doc/rustc-dev-guide/src/walkthrough.md2
-rw-r--r--src/doc/rustc-dev-guide/triagebot.toml3
82 files changed, 651 insertions, 174 deletions
diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml
index daf5223cbd4..6eabb999fb0 100644
--- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml
+++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml
@@ -17,7 +17,6 @@ jobs:
       MDBOOK_VERSION: 0.4.48
       MDBOOK_LINKCHECK2_VERSION: 0.9.1
       MDBOOK_MERMAID_VERSION: 0.12.6
-      MDBOOK_TOC_VERSION: 0.11.2
       MDBOOK_OUTPUT__LINKCHECK__FOLLOW_WEB_LINKS: ${{ github.event_name != 'pull_request' }}
       DEPLOY_DIR: book/html
       BASE_SHA: ${{ github.event.pull_request.base.sha }}
@@ -34,7 +33,7 @@ jobs:
         with:
           path: |
             ~/.cargo/bin
-          key: ${{ runner.os }}-${{ env.MDBOOK_VERSION }}--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ env.MDBOOK_TOC_VERSION }}--${{ env.MDBOOK_MERMAID_VERSION }}
+          key: ${{ runner.os }}-${{ env.MDBOOK_VERSION }}--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ env.MDBOOK_MERMAID_VERSION }}
 
       - name: Restore cached Linkcheck
         if: github.event_name == 'schedule'
@@ -57,7 +56,6 @@ jobs:
         run: |
           cargo install mdbook --version ${{ env.MDBOOK_VERSION }}
           cargo install mdbook-linkcheck2 --version ${{ env.MDBOOK_LINKCHECK2_VERSION }}
-          cargo install mdbook-toc --version ${{ env.MDBOOK_TOC_VERSION }}
           cargo install mdbook-mermaid --version ${{ env.MDBOOK_MERMAID_VERSION }}
 
       - name: Check build
diff --git a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml
index ad570ee4595..04d6469aeaa 100644
--- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml
+++ b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml
@@ -11,10 +11,11 @@ jobs:
     if: github.repository == 'rust-lang/rustc-dev-guide'
     uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main
     with:
+      github-app-id: ${{ vars.APP_CLIENT_ID }}
       zulip-stream-id: 196385
       zulip-bot-email:  "rustc-dev-guide-gha-notif-bot@rust-lang.zulipchat.com"
       pr-base-branch: master
       branch-name: rustc-pull
     secrets:
       zulip-api-token: ${{ secrets.ZULIP_API_TOKEN }}
-      token: ${{ secrets.GITHUB_TOKEN }}
+      github-app-secret: ${{ secrets.APP_PRIVATE_KEY }}
diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md
index 5932da467ab..1ad895aeda2 100644
--- a/src/doc/rustc-dev-guide/README.md
+++ b/src/doc/rustc-dev-guide/README.md
@@ -43,7 +43,7 @@ rustdocs][rustdocs].
 To build a local static HTML site, install [`mdbook`](https://github.com/rust-lang/mdBook) with:
 
 ```
-cargo install mdbook mdbook-linkcheck2 mdbook-toc mdbook-mermaid
+cargo install mdbook mdbook-linkcheck2 mdbook-mermaid
 ```
 
 and execute the following command in the root of the repository:
@@ -67,8 +67,8 @@ ENABLE_LINKCHECK=1 mdbook serve
 
 ### 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.
+Each page has a TOC that is automatically generated by `pagetoc.js`.
+There is an associated `pagetoc.css`, for styling.
 
 ## Synchronizing josh subtree with rustc
 
diff --git a/src/doc/rustc-dev-guide/book.toml b/src/doc/rustc-dev-guide/book.toml
index b84b1e7548a..daf237ed908 100644
--- a/src/doc/rustc-dev-guide/book.toml
+++ b/src/doc/rustc-dev-guide/book.toml
@@ -6,17 +6,18 @@ description = "A guide to developing the Rust compiler (rustc)"
 [build]
 create-missing = false
 
-[preprocessor.toc]
-command = "mdbook-toc"
-renderer = ["html"]
-
 [preprocessor.mermaid]
 command = "mdbook-mermaid"
 
 [output.html]
 git-repository-url = "https://github.com/rust-lang/rustc-dev-guide"
 edit-url-template = "https://github.com/rust-lang/rustc-dev-guide/edit/master/{path}"
-additional-js = ["mermaid.min.js", "mermaid-init.js"]
+additional-js = [
+  "mermaid.min.js",
+  "mermaid-init.js",
+  "pagetoc.js",
+]
+additional-css = ["pagetoc.css"]
 
 [output.html.search]
 use-boolean-and = true
diff --git a/src/doc/rustc-dev-guide/pagetoc.css b/src/doc/rustc-dev-guide/pagetoc.css
new file mode 100644
index 00000000000..fa709194f37
--- /dev/null
+++ b/src/doc/rustc-dev-guide/pagetoc.css
@@ -0,0 +1,84 @@
+/* Inspired by https://github.com/JorelAli/mdBook-pagetoc/tree/98ee241 (under WTFPL) */
+
+:root {
+    --toc-width: 270px;
+    --center-content-toc-shift: calc(-1 * var(--toc-width) / 2);
+}
+
+.nav-chapters {
+    /* adjust width of buttons that bring to the previous or the next page */
+    min-width: 50px;
+}
+
+@media only screen {
+    @media (max-width: 1179px) {
+        .sidebar-hidden #sidetoc {
+            display: none;
+        }
+    }
+
+    @media (max-width: 1439px) {
+        .sidebar-visible #sidetoc {
+            display: none;
+        }
+    }
+
+    @media (1180px <= width <= 1439px) {
+        .sidebar-hidden main {
+            position: relative;
+            left: var(--center-content-toc-shift);
+        }
+    }
+
+    @media (1440px <= width <= 1700px) {
+        .sidebar-visible main {
+            position: relative;
+            left: var(--center-content-toc-shift);
+        }
+    }
+
+    #sidetoc {
+        margin-left: calc(100% + 20px);
+    }
+    #pagetoc {
+        position: fixed;
+        /* adjust TOC width */
+        width: var(--toc-width);
+        height: calc(100vh - var(--menu-bar-height) - 0.67em * 4);
+        overflow: auto;
+    }
+    #pagetoc a {
+        border-left: 1px solid var(--sidebar-bg);
+        color: var(--fg);
+        display: block;
+        padding-bottom: 5px;
+        padding-top: 5px;
+        padding-left: 10px;
+        text-align: left;
+        text-decoration: none;
+    }
+    #pagetoc a:hover,
+    #pagetoc a.active {
+        background: var(--sidebar-bg);
+        color: var(--sidebar-active) !important;
+    }
+    #pagetoc .active {
+        background: var(--sidebar-bg);
+        color: var(--sidebar-active);
+    }
+    #pagetoc .pagetoc-H2 {
+        padding-left: 20px;
+    }
+    #pagetoc .pagetoc-H3 {
+        padding-left: 40px;
+    }
+    #pagetoc .pagetoc-H4 {
+        padding-left: 60px;
+    }
+}
+
+@media print {
+    #sidetoc {
+        display: none;
+    }
+}
diff --git a/src/doc/rustc-dev-guide/pagetoc.js b/src/doc/rustc-dev-guide/pagetoc.js
new file mode 100644
index 00000000000..927a5b10749
--- /dev/null
+++ b/src/doc/rustc-dev-guide/pagetoc.js
@@ -0,0 +1,104 @@
+// Inspired by https://github.com/JorelAli/mdBook-pagetoc/tree/98ee241 (under WTFPL)
+
+let activeHref = location.href;
+function updatePageToc(elem = undefined) {
+    let selectedPageTocElem = elem;
+    const pagetoc = document.getElementById("pagetoc");
+
+    function getRect(element) {
+        return element.getBoundingClientRect();
+    }
+
+    function overflowTop(container, element) {
+        return getRect(container).top - getRect(element).top;
+    }
+
+    function overflowBottom(container, element) {
+        return getRect(container).bottom - getRect(element).bottom;
+    }
+
+    // We've not selected a heading to highlight, and the URL needs updating
+    // so we need to find a heading based on the URL
+    if (selectedPageTocElem === undefined && location.href !== activeHref) {
+        activeHref = location.href;
+        for (const pageTocElement of pagetoc.children) {
+            if (pageTocElement.href === activeHref) {
+                selectedPageTocElem = pageTocElement;
+            }
+        }
+    }
+
+    // We still don't have a selected heading, let's try and find the most
+    // suitable heading based on the scroll position
+    if (selectedPageTocElem === undefined) {
+        const margin = window.innerHeight / 3;
+
+        const headers = document.getElementsByClassName("header");
+        for (let i = 0; i < headers.length; i++) {
+            const header = headers[i];
+            if (selectedPageTocElem === undefined && getRect(header).top >= 0) {
+                if (getRect(header).top < margin) {
+                    selectedPageTocElem = header;
+                } else {
+                    selectedPageTocElem = headers[Math.max(0, i - 1)];
+                }
+            }
+            // a very long last section's heading is over the screen
+            if (selectedPageTocElem === undefined && i === headers.length - 1) {
+                selectedPageTocElem = header;
+            }
+        }
+    }
+
+    // Remove the active flag from all pagetoc elements
+    for (const pageTocElement of pagetoc.children) {
+        pageTocElement.classList.remove("active");
+    }
+
+    // If we have a selected heading, set it to active and scroll to it
+    if (selectedPageTocElem !== undefined) {
+        for (const pageTocElement of pagetoc.children) {
+            if (selectedPageTocElem.href.localeCompare(pageTocElement.href) === 0) {
+                pageTocElement.classList.add("active");
+                if (overflowTop(pagetoc, pageTocElement) > 0) {
+                    pagetoc.scrollTop = pageTocElement.offsetTop;
+                }
+                if (overflowBottom(pagetoc, pageTocElement) < 0) {
+                    pagetoc.scrollTop -= overflowBottom(pagetoc, pageTocElement);
+                }
+            }
+        }
+    }
+}
+
+if (document.getElementById("sidetoc") === null &&
+    document.getElementsByClassName("header").length > 0) {
+    // The sidetoc element doesn't exist yet, let's create it
+
+    // Create the empty sidetoc and pagetoc elements
+    const sidetoc = document.createElement("div");
+    const pagetoc = document.createElement("div");
+    sidetoc.id = "sidetoc";
+    pagetoc.id = "pagetoc";
+    sidetoc.appendChild(pagetoc);
+
+    // And append them to the current DOM
+    const main = document.querySelector('main');
+    main.insertBefore(sidetoc, main.firstChild);
+
+    // Populate sidebar on load
+    window.addEventListener("load", () => {
+        for (const header of document.getElementsByClassName("header")) {
+            const link = document.createElement("a");
+            link.innerHTML = header.innerHTML;
+            link.href = header.hash;
+            link.classList.add("pagetoc-" + header.parentElement.tagName);
+            document.getElementById("pagetoc").appendChild(link);
+            link.onclick = () => updatePageToc(link);
+        }
+        updatePageToc();
+    });
+
+    // Update page table of contents selected heading on scroll
+    window.addEventListener("scroll", () => updatePageToc());
+}
diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version
index b631041b6bf..e9f1626f1fd 100644
--- a/src/doc/rustc-dev-guide/rust-version
+++ b/src/doc/rustc-dev-guide/rust-version
@@ -1 +1 @@
-2b5e239c6b86cde974b0ef0f8e23754fb08ff3c5
+383b9c447b61641e1f1a3850253944a897a60827
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index e3c0d50fcc7..9ded467d5cd 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -176,6 +176,7 @@
     - [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)
diff --git a/src/doc/rustc-dev-guide/src/appendix/humorust.md b/src/doc/rustc-dev-guide/src/appendix/humorust.md
index 6df3b212aa7..8681512ed56 100644
--- a/src/doc/rustc-dev-guide/src/appendix/humorust.md
+++ b/src/doc/rustc-dev-guide/src/appendix/humorust.md
@@ -3,7 +3,7 @@
 What's a project without a sense of humor? And frankly some of these are
 enlightening?
 
-- [Weird exprs test](https://github.com/rust-lang/rust/blob/master/tests/ui/weird-exprs.rs)
+- [Weird exprs test](https://github.com/rust-lang/rust/blob/master/tests/ui/expr/weird-exprs.rs)
 - [Ferris Rap](https://fitzgen.com/2018/12/13/rust-raps.html)
 - [The Genesis of Generic Germination](https://github.com/rust-lang/rust/pull/53645#issue-210543221)
 - [The Bastion of the Turbofish test](https://github.com/rust-lang/rust/blob/79d8a0fcefa5134db2a94739b1d18daa01fc6e9f/src/test/ui/bastion-of-the-turbofish.rs)
diff --git a/src/doc/rustc-dev-guide/src/asm.md b/src/doc/rustc-dev-guide/src/asm.md
index 1bb493e73d5..b5857d5465e 100644
--- a/src/doc/rustc-dev-guide/src/asm.md
+++ b/src/doc/rustc-dev-guide/src/asm.md
@@ -1,7 +1,5 @@
 # Inline assembly
 
-<!-- toc -->
-
 ## Overview
 
 Inline assembly in rustc mostly revolves around taking an `asm!` macro invocation and plumbing it
diff --git a/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md b/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
index 0f81d3cb48a..2fdda4eda99 100644
--- a/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
+++ b/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
@@ -1,7 +1,5 @@
 # Backend Agnostic Codegen
 
-<!-- toc -->
-
 [`rustc_codegen_ssa`]
 provides an abstract interface for all backends to implement,
 namely LLVM, [Cranelift], and [GCC].
diff --git a/src/doc/rustc-dev-guide/src/backend/implicit-caller-location.md b/src/doc/rustc-dev-guide/src/backend/implicit-caller-location.md
index c5ee00813a3..9ca4bcab078 100644
--- a/src/doc/rustc-dev-guide/src/backend/implicit-caller-location.md
+++ b/src/doc/rustc-dev-guide/src/backend/implicit-caller-location.md
@@ -1,7 +1,5 @@
 # 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
diff --git a/src/doc/rustc-dev-guide/src/backend/monomorph.md b/src/doc/rustc-dev-guide/src/backend/monomorph.md
index 7ebb4d2b1e8..e9d98597ee0 100644
--- a/src/doc/rustc-dev-guide/src/backend/monomorph.md
+++ b/src/doc/rustc-dev-guide/src/backend/monomorph.md
@@ -1,7 +1,5 @@
 # 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
diff --git a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
index 18c822aad79..ebef15d40ba 100644
--- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
+++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
@@ -1,7 +1,5 @@
 # Updating LLVM
 
-<!-- toc -->
-
 <!-- date-check: Aug 2024 -->
 Rust supports building against multiple LLVM versions:
 
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/moves_and_initialization/move_paths.md b/src/doc/rustc-dev-guide/src/borrow_check/moves_and_initialization/move_paths.md
index ad9c75d6296..95518fbc018 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/moves_and_initialization/move_paths.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/moves_and_initialization/move_paths.md
@@ -1,7 +1,5 @@
 # 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:
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md
index 85e71b4fa42..0d55ab95583 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md
@@ -1,7 +1,5 @@
 # Region inference (NLL)
 
-<!-- toc -->
-
 The MIR-based region checking code is located in [the `rustc_mir::borrow_check`
 module][nll].
 
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/constraint_propagation.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/constraint_propagation.md
index 4c30d25e040..c3f8c03cb29 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/constraint_propagation.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/constraint_propagation.md
@@ -1,7 +1,5 @@
 # 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
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/lifetime_parameters.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/lifetime_parameters.md
index fadfac40456..2d337dbc020 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/lifetime_parameters.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/lifetime_parameters.md
@@ -1,7 +1,5 @@
 # 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"
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
index fd7c87ffcea..2804c97724f 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
@@ -1,7 +1,5 @@
 # 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
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/placeholders_and_universes.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/placeholders_and_universes.md
index 91c8c452611..11fd2a5fc7d 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/placeholders_and_universes.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/placeholders_and_universes.md
@@ -1,7 +1,5 @@
 # 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:
 
diff --git a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md
index 55436261fde..6b13c97023f 100644
--- a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md
+++ b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md
@@ -1,7 +1,5 @@
 # Procedures for breaking changes
 
-<!-- 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
diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
index c9c0d64a604..9c5ebbd36c4 100644
--- a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
+++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
@@ -123,6 +123,12 @@ if [#96176][cleanup-compiler-for] is resolved.
 
 [cleanup-compiler-for]: https://github.com/rust-lang/rust/issues/96176
 
+### Rendering step graph
+
+When you run bootstrap with the `BOOTSTRAP_TRACING` environment variable configured, bootstrap will automatically output a DOT file that shows all executed steps and their dependencies. The files will have a prefix `bootstrap-steps`. You can use e.g. `xdot` to visualize the file or e.g. `dot -Tsvg` to convert the DOT file to a SVG file.
+
+A separate DOT file will be outputted for dry-run and non-dry-run execution.
+
 ### Using `tracing` in bootstrap
 
 Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need to be gated behind `tracing` feature. Examples:
diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md
index 2793ad43815..da425d8d39b 100644
--- a/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md
+++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md
@@ -1,7 +1,5 @@
 # What Bootstrapping does
 
-<!-- toc -->
-
 [*Bootstrapping*][boot] 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.
diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
index d29cd144810..b07d3533f59 100644
--- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
+++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
@@ -1,7 +1,5 @@
 # How to build and run the compiler
 
-<!-- toc -->
-
 <div class="warning">
 
 For `profile = "library"` users, or users who use `download-rustc = true | "if-unchanged"`, please be advised that
diff --git a/src/doc/rustc-dev-guide/src/building/new-target.md b/src/doc/rustc-dev-guide/src/building/new-target.md
index e11a2cd8ee5..436aec8ee26 100644
--- a/src/doc/rustc-dev-guide/src/building/new-target.md
+++ b/src/doc/rustc-dev-guide/src/building/new-target.md
@@ -6,8 +6,6 @@ relevant to your desired goal.
 
 See also the associated documentation in the [target tier policy].
 
-<!-- toc -->
-
 [target tier policy]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target
 
 ## Specifying a new LLVM
diff --git a/src/doc/rustc-dev-guide/src/building/optimized-build.md b/src/doc/rustc-dev-guide/src/building/optimized-build.md
index 62dfaca89d2..863ed9749fb 100644
--- a/src/doc/rustc-dev-guide/src/building/optimized-build.md
+++ b/src/doc/rustc-dev-guide/src/building/optimized-build.md
@@ -1,7 +1,5 @@
 # Optimized build of the compiler
 
-<!-- toc -->
-
 There are multiple additional build configuration options and techniques that can be used to compile a
 build of `rustc` that is as optimized as possible (for example when building `rustc` for a Linux
 distribution). The status of these configuration options for various Rust targets is tracked [here].
diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md
index c046161e77f..35c7e935b56 100644
--- a/src/doc/rustc-dev-guide/src/building/suggested.md
+++ b/src/doc/rustc-dev-guide/src/building/suggested.md
@@ -3,8 +3,6 @@
 The full bootstrapping process takes quite a while. Here are some suggestions to
 make your life easier.
 
-<!-- toc -->
-
 ## Installing a pre-push hook
 
 CI will automatically fail your build if it doesn't pass `tidy`, our internal
diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md
index 102e2020779..edd2aa6c5f6 100644
--- a/src/doc/rustc-dev-guide/src/compiler-debugging.md
+++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md
@@ -1,7 +1,5 @@
 # Debugging the compiler
 
-<!-- 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
diff --git a/src/doc/rustc-dev-guide/src/compiler-src.md b/src/doc/rustc-dev-guide/src/compiler-src.md
index 00aa9622684..d67bacb1b33 100644
--- a/src/doc/rustc-dev-guide/src/compiler-src.md
+++ b/src/doc/rustc-dev-guide/src/compiler-src.md
@@ -1,7 +1,5 @@
 # High-level overview of the compiler source
 
-<!-- toc -->
-
 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.
diff --git a/src/doc/rustc-dev-guide/src/const-eval/interpret.md b/src/doc/rustc-dev-guide/src/const-eval/interpret.md
index 51a539de5cb..08382b12ff0 100644
--- a/src/doc/rustc-dev-guide/src/const-eval/interpret.md
+++ b/src/doc/rustc-dev-guide/src/const-eval/interpret.md
@@ -1,7 +1,5 @@
 # Interpreter
 
-<!-- toc -->
-
 The interpreter is a virtual machine for executing MIR without compiling to
 machine code. It is usually invoked via `tcx.const_eval_*` functions. The
 interpreter is shared between the compiler (for compile-time function
diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md
index b3fcd79ec81..963bef3af8d 100644
--- a/src/doc/rustc-dev-guide/src/contributing.md
+++ b/src/doc/rustc-dev-guide/src/contributing.md
@@ -1,7 +1,5 @@
 # Contribution procedures
 
-<!-- toc -->
-
 ## Bug reports
 
 While bugs are unfortunate, they're a reality in software. We can't fix what we
diff --git a/src/doc/rustc-dev-guide/src/coroutine-closures.md b/src/doc/rustc-dev-guide/src/coroutine-closures.md
index 48cdba44a9f..2617c824a39 100644
--- a/src/doc/rustc-dev-guide/src/coroutine-closures.md
+++ b/src/doc/rustc-dev-guide/src/coroutine-closures.md
@@ -1,7 +1,5 @@
 # Async closures/"coroutine-closures"
 
-<!-- toc -->
-
 Please read [RFC 3668](https://rust-lang.github.io/rfcs/3668-async-closures.html) 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
diff --git a/src/doc/rustc-dev-guide/src/crates-io.md b/src/doc/rustc-dev-guide/src/crates-io.md
index 4431585a2f0..677b1fc0313 100644
--- a/src/doc/rustc-dev-guide/src/crates-io.md
+++ b/src/doc/rustc-dev-guide/src/crates-io.md
@@ -11,7 +11,7 @@ you should avoid adding dependencies to the compiler for several reasons:
 - The dependency may have transitive dependencies that have one of the above
   problems.
 
-<!-- date-check: Feb 2023 -->
+<!-- date-check: Aug 2025 -->
 Note that there is no official policy for vetting new dependencies to the compiler.
 Decisions are made on a case-by-case basis, during code review.
 
diff --git a/src/doc/rustc-dev-guide/src/debugging-support-in-rustc.md b/src/doc/rustc-dev-guide/src/debugging-support-in-rustc.md
index ac629934e0a..bd4f795ce03 100644
--- a/src/doc/rustc-dev-guide/src/debugging-support-in-rustc.md
+++ b/src/doc/rustc-dev-guide/src/debugging-support-in-rustc.md
@@ -1,7 +1,5 @@
 # Debugging support in the Rust compiler
 
-<!-- toc -->
-
 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.
diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md
index 33f5441d36e..82191e0a6ea 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics.md
@@ -1,7 +1,5 @@
 # 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.
 
diff --git a/src/doc/rustc-dev-guide/src/early_late_parameters.md b/src/doc/rustc-dev-guide/src/early_late_parameters.md
index 3f94b090566..c472bdc2c48 100644
--- a/src/doc/rustc-dev-guide/src/early_late_parameters.md
+++ b/src/doc/rustc-dev-guide/src/early_late_parameters.md
@@ -1,8 +1,6 @@
 
 # Early vs Late bound parameters
 
-<!-- toc -->
-
 > **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.
 
 ## What does it mean to be "early" bound or "late" bound
diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md
index d6c5c3ac852..04d2e37732f 100644
--- a/src/doc/rustc-dev-guide/src/getting-started.md
+++ b/src/doc/rustc-dev-guide/src/getting-started.md
@@ -3,8 +3,6 @@
 Thank you for your interest in contributing to Rust! There are many ways to
 contribute, and we appreciate all of them.
 
-<!-- toc -->
-
 If this is your first time contributing, the [walkthrough] chapter can give you a good example of
 how a typical contribution would go.
 
diff --git a/src/doc/rustc-dev-guide/src/git.md b/src/doc/rustc-dev-guide/src/git.md
index 8726ddfce20..447c6fd4546 100644
--- a/src/doc/rustc-dev-guide/src/git.md
+++ b/src/doc/rustc-dev-guide/src/git.md
@@ -1,7 +1,5 @@
 # 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.
diff --git a/src/doc/rustc-dev-guide/src/guides/editions.md b/src/doc/rustc-dev-guide/src/guides/editions.md
index 9a92d4ebcb5..b65fbb13cd1 100644
--- a/src/doc/rustc-dev-guide/src/guides/editions.md
+++ b/src/doc/rustc-dev-guide/src/guides/editions.md
@@ -1,7 +1,5 @@
 # Editions
 
-<!-- toc -->
-
 This chapter gives an overview of how Edition support works in rustc.
 This assumes that you are familiar with what Editions are (see the [Edition Guide]).
 
diff --git a/src/doc/rustc-dev-guide/src/hir.md b/src/doc/rustc-dev-guide/src/hir.md
index 72fb1070157..38ba33112f2 100644
--- a/src/doc/rustc-dev-guide/src/hir.md
+++ b/src/doc/rustc-dev-guide/src/hir.md
@@ -1,7 +1,5 @@
 # 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
diff --git a/src/doc/rustc-dev-guide/src/implementing_new_features.md b/src/doc/rustc-dev-guide/src/implementing_new_features.md
index 76cf2386c82..00bce8599e4 100644
--- a/src/doc/rustc-dev-guide/src/implementing_new_features.md
+++ b/src/doc/rustc-dev-guide/src/implementing_new_features.md
@@ -1,7 +1,5 @@
 # Implementing new language features
 
-<!-- toc -->
-
 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].**
diff --git a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
index 880363b94bf..288b90f33c3 100644
--- a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
+++ b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
@@ -1,7 +1,5 @@
 # LLVM source-based code coverage
 
-<!-- toc -->
-
 `rustc` supports detailed source-based code and test coverage analysis
 with a command line option (`-C instrument-coverage`) that instruments Rust
 libraries and binaries with additional instructions and data, at compile time.
diff --git a/src/doc/rustc-dev-guide/src/macro-expansion.md b/src/doc/rustc-dev-guide/src/macro-expansion.md
index a90f717004f..54d6d2b4e81 100644
--- a/src/doc/rustc-dev-guide/src/macro-expansion.md
+++ b/src/doc/rustc-dev-guide/src/macro-expansion.md
@@ -1,7 +1,5 @@
 # Macro expansion
 
-<!-- toc -->
-
 Rust has a very powerful macro system. In the previous chapter, we saw how
 the parser sets aside macros to be expanded (using temporary [placeholders]).
 This chapter is about the process of expanding those macros iteratively until
diff --git a/src/doc/rustc-dev-guide/src/mir/construction.md b/src/doc/rustc-dev-guide/src/mir/construction.md
index f2559a22b95..8360d9ff1a8 100644
--- a/src/doc/rustc-dev-guide/src/mir/construction.md
+++ b/src/doc/rustc-dev-guide/src/mir/construction.md
@@ -1,7 +1,5 @@
 # MIR construction
 
-<!-- toc -->
-
 The lowering of [HIR] to [MIR] occurs for the following (probably incomplete)
 list of items:
 
diff --git a/src/doc/rustc-dev-guide/src/mir/dataflow.md b/src/doc/rustc-dev-guide/src/mir/dataflow.md
index 85e57dd839b..970e61196c1 100644
--- a/src/doc/rustc-dev-guide/src/mir/dataflow.md
+++ b/src/doc/rustc-dev-guide/src/mir/dataflow.md
@@ -1,7 +1,5 @@
 # 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`
diff --git a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md
index 3b321fd44d1..4da612c83f0 100644
--- a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md
+++ b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md
@@ -1,7 +1,5 @@
 # Drop elaboration
 
-<!-- toc -->
-
 ## Dynamic drops
 
 According to the [reference][reference-drop]:
diff --git a/src/doc/rustc-dev-guide/src/mir/index.md b/src/doc/rustc-dev-guide/src/mir/index.md
index f355875aa15..8ba5f3ac8b7 100644
--- a/src/doc/rustc-dev-guide/src/mir/index.md
+++ b/src/doc/rustc-dev-guide/src/mir/index.md
@@ -1,7 +1,5 @@
 # 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
diff --git a/src/doc/rustc-dev-guide/src/name-resolution.md b/src/doc/rustc-dev-guide/src/name-resolution.md
index 719ebce8553..2e96382f779 100644
--- a/src/doc/rustc-dev-guide/src/name-resolution.md
+++ b/src/doc/rustc-dev-guide/src/name-resolution.md
@@ -1,7 +1,5 @@
 # Name resolution
 
-<!-- toc -->
-
 In the previous chapters, we saw how the [*Abstract Syntax Tree* (`AST`)][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
diff --git a/src/doc/rustc-dev-guide/src/normalization.md b/src/doc/rustc-dev-guide/src/normalization.md
index eb0962a4122..53e20f1c0db 100644
--- a/src/doc/rustc-dev-guide/src/normalization.md
+++ b/src/doc/rustc-dev-guide/src/normalization.md
@@ -1,7 +1,5 @@
 # Aliases and Normalization
 
-<!-- toc -->
-
 ## Aliases
 
 In Rust there are a number of types that are considered equal to some "underlying" type, for example inherent associated types, trait associated types, free type aliases (`type Foo = u32`), and opaque types (`-> impl RPIT`). We consider such types to be "aliases", alias types are represented by the [`TyKind::Alias`][tykind_alias] variant, with the kind of alias tracked by the [`AliasTyKind`][aliaskind] enum.
diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md
index 8a1a22fad66..12b76828b5c 100644
--- a/src/doc/rustc-dev-guide/src/overview.md
+++ b/src/doc/rustc-dev-guide/src/overview.md
@@ -1,7 +1,5 @@
 # Overview of the compiler
 
-<!-- toc -->
-
 This chapter is about the overall process of compiling a program -- how
 everything fits together.
 
diff --git a/src/doc/rustc-dev-guide/src/panic-implementation.md b/src/doc/rustc-dev-guide/src/panic-implementation.md
index 468190ffccd..dba3f2146d2 100644
--- a/src/doc/rustc-dev-guide/src/panic-implementation.md
+++ b/src/doc/rustc-dev-guide/src/panic-implementation.md
@@ -1,7 +1,5 @@
 # Panicking in Rust
 
-<!-- toc -->
-
 ## Step 1: Invocation of the `panic!` macro.
 
 There are actually two panic macros - one defined in `core`, and one defined in `std`.
diff --git a/src/doc/rustc-dev-guide/src/profile-guided-optimization.md b/src/doc/rustc-dev-guide/src/profile-guided-optimization.md
index 2fa81021045..4e3dadd406e 100644
--- a/src/doc/rustc-dev-guide/src/profile-guided-optimization.md
+++ b/src/doc/rustc-dev-guide/src/profile-guided-optimization.md
@@ -1,7 +1,5 @@
 # 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`.
diff --git a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md
index 18e0e25c531..46e38832e64 100644
--- a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md
+++ b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md
@@ -1,7 +1,5 @@
 # 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:
 
diff --git a/src/doc/rustc-dev-guide/src/queries/incremental-compilation.md b/src/doc/rustc-dev-guide/src/queries/incremental-compilation.md
index 6e5b4e8cc49..731ff3287d9 100644
--- a/src/doc/rustc-dev-guide/src/queries/incremental-compilation.md
+++ b/src/doc/rustc-dev-guide/src/queries/incremental-compilation.md
@@ -1,7 +1,5 @@
 # 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" –
diff --git a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
index 444e20bc580..c1a4373f7da 100644
--- a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
+++ b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
@@ -1,7 +1,5 @@
 # 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
diff --git a/src/doc/rustc-dev-guide/src/queries/salsa.md b/src/doc/rustc-dev-guide/src/queries/salsa.md
index 1a7b7fa9a68..dc7160edc22 100644
--- a/src/doc/rustc-dev-guide/src/queries/salsa.md
+++ b/src/doc/rustc-dev-guide/src/queries/salsa.md
@@ -1,7 +1,5 @@
 # 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
diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md
index 0ca1b360a70..8377a7b2f31 100644
--- a/src/doc/rustc-dev-guide/src/query.md
+++ b/src/doc/rustc-dev-guide/src/query.md
@@ -1,7 +1,5 @@
 # Queries: demand-driven compilation
 
-<!-- toc -->
-
 As described in [Overview of the compiler], the Rust compiler
 is still (as of <!-- date-check --> July 2021) transitioning from a
 traditional "pass-based" setup to a "demand-driven" system. The compiler query
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md
index 0234d4a920e..4affbafe477 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md
@@ -1,7 +1,5 @@
 # Rustdoc Internals
 
-<!-- toc -->
-
 This page describes [`rustdoc`]'s passes and modes. For an overview of `rustdoc`,
 see the ["Rustdoc overview" chapter](./rustdoc.md).
 
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md
index 3506431118b..beff0a94c1e 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md
@@ -7,8 +7,6 @@ in the crates in the doc bundle, and the second reads
 it, turns it into some in-memory structures, and
 scans them linearly to search.
 
-<!-- toc -->
-
 ## Search index format
 
 `search.js` calls this Raw, because it turns it into
diff --git a/src/doc/rustc-dev-guide/src/rustdoc.md b/src/doc/rustc-dev-guide/src/rustdoc.md
index 52ae48c3735..9290fcd3b41 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc.md
@@ -9,8 +9,6 @@ For more details about how rustdoc works, see the
 
 [Rustdoc internals]: ./rustdoc-internals.md
 
-<!-- toc -->
-
 `rustdoc` uses `rustc` internals (and, of course, the standard library), so you
 will have to build the compiler and `std` once before you can build `rustdoc`.
 
diff --git a/src/doc/rustc-dev-guide/src/solve/candidate-preference.md b/src/doc/rustc-dev-guide/src/solve/candidate-preference.md
new file mode 100644
index 00000000000..89605294735
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/solve/candidate-preference.md
@@ -0,0 +1,427 @@
+# Candidate preference
+
+There are multiple ways to prove `Trait` and `NormalizesTo` goals. Each such option is called a [`Candidate`]. If there are multiple applicable candidates, we prefer some candidates over others. We store the relevant information in their [`CandidateSource`].
+
+This preference may result in incorrect inference or region constraints and would therefore be unsound during coherence. Because of this, we simply try to merge all candidates in coherence.
+
+## `Trait` goals
+
+Trait goals merge their applicable candidates in [`fn merge_trait_candidates`]. This document provides additional details and references to explain *why* we've got the current preference rules.
+
+### `CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial))`
+
+Trivial builtin impls are builtin impls which are known to be always applicable for well-formed types. This means that if one exists, using another candidate should never have fewer constraints. We currently only consider `Sized` - and `MetaSized` - impls to be trivial.
+
+This is necessary to prevent a lifetime error for the following pattern
+
+```rust
+trait Trait<T>: Sized {}
+impl<'a> Trait<u32> for &'a str {}
+impl<'a> Trait<i32> for &'a str {}
+fn is_sized<T: Sized>(_: T) {}
+fn foo<'a, 'b, T>(x: &'b str)
+where
+    &'a str: Trait<T>,
+{
+    // Elaborating the `&'a str: Trait<T>` where-bound results in a
+    // `&'a str: Sized` where-bound. We do not want to prefer this
+    // over the builtin impl. 
+    is_sized(x);
+}
+```
+
+This preference is incorrect in case the builtin impl has a nested goal which relies on a non-param where-clause
+```rust
+struct MyType<'a, T: ?Sized>(&'a (), T);
+fn is_sized<T>() {}
+fn foo<'a, T: ?Sized>()
+where
+    (MyType<'a, T>,): Sized,
+    MyType<'static, T>: Sized,
+{
+    // The where-bound is trivial while the builtin `Sized` impl for tuples
+    // requires proving `MyType<'a, T>: Sized` which can only be proven by
+    // using the where-clause, adding an unnecessary `'static` constraint.
+    is_sized::<(MyType<'a, T>,)>();
+    //~^ ERROR lifetime may not live long enough
+}
+```
+
+### `CandidateSource::ParamEnv`
+
+Once there's at least one *non-global* `ParamEnv` candidate, we prefer *all* `ParamEnv` candidates over other candidate kinds.
+A where-bound is global if it is not higher-ranked and doesn't contain any generic parameters. It may contain `'static`.
+
+We try to apply where-bounds over other candidates as users tends to have the most control over them, so they can most easily
+adjust them in case our candidate preference is incorrect.
+
+#### Preference over `Impl` candidates
+
+This is necessary to avoid region errors in the following example
+
+```rust
+trait Trait<'a> {}
+impl<T> Trait<'static> for T {}
+fn impls_trait<'a, T: Trait<'a>>() {}
+fn foo<'a, T: Trait<'a>>() {
+    impls_trait::<'a, T>();
+}
+```
+
+We also need this as shadowed impls can result in currently ambiguous solver cycles: [trait-system-refactor-initiative#76]. Without preference we'd be forced to fail with ambiguity
+errors if the where-bound results in region constraints to avoid incompleteness.
+```rust
+trait Super {
+    type SuperAssoc;
+}
+
+trait Trait: Super<SuperAssoc = Self::TraitAssoc> {
+    type TraitAssoc;
+}
+
+impl<T, U> Trait for T
+where
+    T: Super<SuperAssoc = U>,
+{
+    type TraitAssoc = U;
+}
+
+fn overflow<T: Trait>() {
+    // We can use the elaborated `Super<SuperAssoc = Self::TraitAssoc>` where-bound
+    // to prove the where-bound of the `T: Trait` implementation. This currently results in
+    // overflow. 
+    let x: <T as Trait>::TraitAssoc;
+}
+```
+
+This preference causes a lot of issues. See [#24066]. Most of the
+issues are caused by prefering where-bounds over impls even if the where-bound guides type inference:
+```rust
+trait Trait<T> {
+    fn call_me(&self, x: T) {}
+}
+impl<T> Trait<u32> for T {}
+impl<T> Trait<i32> for T {}
+fn bug<T: Trait<U>, U>(x: T) {
+    x.call_me(1u32);
+    //~^ ERROR mismatched types
+}
+```
+However, even if we only apply this preference if the where-bound doesn't guide inference, it may still result
+in incorrect lifetime constraints:
+```rust
+trait Trait<'a> {}
+impl<'a> Trait<'a> for &'a str {}
+fn impls_trait<'a, T: Trait<'a>>(_: T) {}
+fn foo<'a, 'b>(x: &'b str)
+where
+    &'a str: Trait<'b>
+{
+    // Need to prove `&'x str: Trait<'b>` with `'b: 'x`.
+    impls_trait::<'b, _>(x);
+    //~^ ERROR lifetime may not live long enough
+}
+```
+
+#### Preference over `AliasBound` candidates
+
+This is necessary to avoid region errors in the following example
+```rust
+trait Bound<'a> {}
+trait Trait<'a> {
+    type Assoc: Bound<'a>;
+}
+
+fn impls_bound<'b, T: Bound<'b>>() {}
+fn foo<'a, 'b, 'c, T>()
+where
+    T: Trait<'a>,
+    for<'hr> T::Assoc: Bound<'hr>,
+{
+    impls_bound::<'b, T::Assoc>();
+    impls_bound::<'c, T::Assoc>();
+}
+```
+It can also result in unnecessary constraints
+```rust
+trait Bound<'a> {}
+trait Trait<'a> {
+    type Assoc: Bound<'a>;
+}
+
+fn impls_bound<'b, T: Bound<'b>>() {}
+fn foo<'a, 'b, T>()
+where
+    T: for<'hr> Trait<'hr>,
+    <T as Trait<'b>>::Assoc: Bound<'a>,
+{
+    // Using the where-bound for `<T as Trait<'a>>::Assoc: Bound<'a>`
+    // unnecessarily equates `<T as Trait<'a>>::Assoc` with the
+    // `<T as Trait<'b>>::Assoc` from the env.
+    impls_bound::<'a, <T as Trait<'a>>::Assoc>();
+    // For a `<T as Trait<'b>>::Assoc: Bound<'b>` the self type of the
+    // where-bound matches, but the arguments of the trait bound don't.
+    impls_bound::<'b, <T as Trait<'b>>::Assoc>();
+}
+```
+
+#### Why no preference for global where-bounds
+
+Global where-bounds are either fully implied by an impl or unsatisfiable. If they are unsatisfiable, we don't really care what happens. If a where-bound is fully implied then using the impl to prove the trait goal cannot result in additional constraints. For trait goals this is only useful for where-bounds which use `'static`:
+
+```rust
+trait A {
+    fn test(&self);
+}
+
+fn foo(x: &dyn A)
+where
+    dyn A + 'static: A, // Using this bound would lead to a lifetime error.
+{
+    x.test();
+}
+```
+More importantly, by using impls here we prevent global where-bounds from shadowing impls when normalizing associated types. There are no known issues from preferring impls over global where-bounds.
+
+#### Why still consider global where-bounds
+
+Given that we just use impls even if there exists a global where-bounds, you may ask why we don't just ignore these global where-bounds entirely: we use them to weaken the inference guidance from non-global where-bounds.
+
+Without a global where-bound, we currently prefer non-global where bounds even though there would be an applicable impl as well. By adding a non-global where-bound, this unnecessary inference guidance is disabled, allowing the following to compile:
+```rust
+fn check<Color>(color: Color)
+where
+    Vec: Into<Color> + Into<f32>,
+{
+    let _: f32 = Vec.into();
+    // Without the global `Vec: Into<f32>`  bound we'd
+    // eagerly use the non-global `Vec: Into<Color>` bound
+    // here, causing this to fail.
+}
+
+struct Vec;
+impl From<Vec> for f32 {
+    fn from(_: Vec) -> Self {
+        loop {}
+    }
+}
+```
+
+### `CandidateSource::AliasBound`
+
+We prefer alias-bound candidates over impls. We currently use this preference to guide type inference, causing the following to compile. I personally don't think this preference is desirable 🤷
+```rust
+pub trait Dyn {
+    type Word: Into<u64>;
+    fn d_tag(&self) -> Self::Word;
+    fn tag32(&self) -> Option<u32> {
+        self.d_tag().into().try_into().ok()
+        // prove `Self::Word: Into<?0>` and then select a method
+        // on `?0`, needs eager inference.
+    }
+}
+```
+```rust
+fn impl_trait() -> impl Into<u32> {
+    0u16
+}
+
+fn main() {
+    // There are two possible types for `x`:
+    // - `u32` by using the "alias bound" of `impl Into<u32>`
+    // - `impl Into<u32>`, i.e. `u16`, by using `impl<T> From<T> for T`
+    //
+    // We infer the type of `x` to be `u32` even though this is not
+    // strictly necessary and can even lead to surprising errors.
+    let x = impl_trait().into();
+    println!("{}", std::mem::size_of_val(&x));
+}
+```
+This preference also avoids ambiguity due to region constraints, I don't know whether people rely on this in practice.
+```rust
+trait Bound<'a> {}
+impl<T> Bound<'static> for T {}
+trait Trait<'a> {
+    type Assoc: Bound<'a>;
+}
+
+fn impls_bound<'b, T: Bound<'b>>() {}
+fn foo<'a, T: Trait<'a>>() {
+    // Should we infer this to `'a` or `'static`.
+    impls_bound::<'_, T::Assoc>();
+}
+```
+
+### `CandidateSource::BuiltinImpl(BuiltinImplSource::Object(_))`
+
+We prefer builtin trait object impls over user-written impls. This is **unsound** and should be remoed in the future. See [#57893](https://github.com/rust-lang/rust/issues/57893) and [#141347](https://github.com/rust-lang/rust/pull/141347) for more details.
+
+## `NormalizesTo` goals
+
+The candidate preference behavior during normalization is implemented in [`fn assemble_and_merge_candidates`].
+
+### Where-bounds shadow impls
+
+Normalization of associated items does not consider impls if the corresponding trait goal has been proven via a `ParamEnv` or `AliasBound` candidate.
+This means that for where-bounds which do not constrain associated types, the associated types remain *rigid*.
+
+This is necessary to avoid unnecessary region constraints from applying impls.
+```rust
+trait Trait<'a> {
+    type Assoc;
+}
+impl Trait<'static> for u32 {
+    type Assoc = u32;
+}
+
+fn bar<'b, T: Trait<'b>>() -> T::Assoc { todo!() }
+fn foo<'a>()
+where
+    u32: Trait<'a>,
+{
+    // Normalizing the return type would use the impl, proving
+    // the `T: Trait` where-bound would use the where-bound, resulting
+    // in different region constraints.
+    bar::<'_, u32>();
+}
+```
+
+### We always consider `AliasBound` candidates
+
+In case the where-bound does not specify the associated item, we consider `AliasBound` candidates instead of treating the alias as rigid, even though the trait goal was proven via a `ParamEnv` candidate.
+
+```rust
+trait Super {
+    type Assoc;
+}
+trait Bound {
+    type Assoc: Super<Assoc = u32>;
+}
+trait Trait: Super {}
+
+// Elaborating the environment results in a `T::Assoc: Super` where-bound.
+// This where-bound must not prevent normalization via the `Super<Assoc = u32>`
+// item bound.
+fn heck<T: Bound<Assoc: Trait>>(x: <T::Assoc as Super>::Assoc) -> u32 {
+    x
+}
+```
+Using such an alias can result in additional region constraints, cc [#133044].
+```rust
+trait Bound<'a> {
+    type Assoc;
+}
+trait Trait {
+    type Assoc: Bound<'static, Assoc = u32>;
+}
+
+fn heck<'a, T: Trait<Assoc: Bound<'a>>>(x: <T::Assoc as Bound<'a>>::Assoc) {
+    // Normalizing the associated type requires `T::Assoc: Bound<'static>` as it
+    // uses the `Bound<'static>` alias-bound instead of keeping the alias rigid.
+    drop(x);
+}
+```
+
+### We prefer `ParamEnv` candidates over `AliasBound`
+
+While we use `AliasBound` candidates if the where-bound does not specify the associated type, in case it does, we prefer the where-bound.
+This is necessary for the following example:
+```rust
+// Make sure we prefer the `I::IntoIterator: Iterator<Item = ()>`
+// where-bound over the `I::Intoiterator: Iterator<Item = I::Item>`
+// alias-bound.
+
+trait Iterator {
+    type Item;
+}
+
+trait IntoIterator {
+    type Item;
+    type IntoIter: Iterator<Item = Self::Item>;
+}
+
+fn normalize<I: Iterator<Item = ()>>() {}
+
+fn foo<I>()
+where
+    I: IntoIterator,
+    I::IntoIter: Iterator<Item = ()>,
+{
+    // We need to prefer the `I::IntoIterator: Iterator<Item = ()>`
+    // where-bound over the `I::Intoiterator: Iterator<Item = I::Item>`
+    // alias-bound.
+    normalize::<I::IntoIter>();
+}
+```
+
+### We always consider where-bounds
+
+Even if the trait goal was proven via an impl, we still prefer `ParamEnv` candidates, if any exist.
+
+#### We prefer "orphaned" where-bounds
+
+We add "orphaned" `Projection` clauses into the `ParamEnv` when normalizing item bounds of GATs and RPITIT in `fn check_type_bounds`.
+We need to prefer these `ParamEnv` candidates over impls and other where-bounds. 
+```rust
+#![feature(associated_type_defaults)]
+trait Foo {
+    // We should be able to prove that `i32: Baz<Self>` because of
+    // the impl below, which requires that `Self::Bar<()>: Eq<i32>`
+    // which is true, because we assume `for<T> Self::Bar<T> = i32`.
+    type Bar<T>: Baz<Self> = i32;
+}
+trait Baz<T: ?Sized> {}
+impl<T: Foo + ?Sized> Baz<T> for i32 where T::Bar<()>: Eq<i32> {}
+trait Eq<T> {}
+impl<T> Eq<T> for T {}
+```
+
+I don't fully understand the cases where this preference is actually necessary and haven't been able to exploit this in fun ways yet, but 🤷
+
+#### We prefer global where-bounds over impls
+
+This is necessary for the following to compile. I don't know whether anything relies on it in practice 🤷
+```rust
+trait Id {
+    type This;
+}
+impl<T> Id for T {
+    type This = T;
+}
+
+fn foo<T>(x: T) -> <u32 as Id>::This
+where
+    u32: Id<This = T>,
+{
+    x
+}
+```
+This means normalization can result in additional region constraints, cc [#133044].
+```rust
+trait Trait {
+    type Assoc;
+}
+
+impl Trait for &u32 {
+    type Assoc = u32;
+}
+
+fn trait_bound<T: Trait>() {}
+fn normalize<T: Trait<Assoc = u32>>() {}
+
+fn foo<'a>()
+where
+    &'static u32: Trait<Assoc = u32>,
+{
+    trait_bound::<&'a u32>(); // ok, proven via impl
+    normalize::<&'a u32>(); // error, proven via where-bound
+}
+```
+
+[`Candidate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/assembly/struct.Candidate.html
+[`CandidateSource`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/enum.CandidateSource.html
+[`fn merge_trait_candidates`]: https://github.com/rust-lang/rust/blob/e3ee7f7aea5b45af3b42b5e4713da43876a65ac9/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs#L1342-L1424
+[`fn assemble_and_merge_candidates`]: https://github.com/rust-lang/rust/blob/e3ee7f7aea5b45af3b42b5e4713da43876a65ac9/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs#L920-L1003
+[trait-system-refactor-initiative#76]: https://github.com/rust-lang/trait-system-refactor-initiative/issues/76
+[#24066]: https://github.com/rust-lang/rust/issues/24066
+[#133044]: https://github.com/rust-lang/rust/issues/133044
\ No newline at end of file
diff --git a/src/doc/rustc-dev-guide/src/stability.md b/src/doc/rustc-dev-guide/src/stability.md
index 230925252ba..c26d34273d7 100644
--- a/src/doc/rustc-dev-guide/src/stability.md
+++ b/src/doc/rustc-dev-guide/src/stability.md
@@ -6,8 +6,6 @@ APIs to use unstable APIs internally in the rustc standard library.
 **NOTE**: this section is for *library* features, not *language* features. For instructions on
 stabilizing a language feature see [Stabilizing Features](./stabilization_guide.md).
 
-<!-- toc -->
-
 ## unstable
 
 The `#[unstable(feature = "foo", issue = "1234", reason = "lorem ipsum")]`
@@ -183,4 +181,7 @@ the `deprecated_in_future` lint is triggered which is default `allow`, but most
 of the standard library raises it to a warning with
 `#![warn(deprecated_in_future)]`.
 
+## unstable_feature_bound
+The `#[unstable_feature_bound(foo)]` attribute can be used together with `#[unstable]` attribute to mark an `impl` of stable type and stable trait as unstable. In std/core, an item annotated with `#[unstable_feature_bound(foo)]` can only be used by another item that is also annotated with `#[unstable_feature_bound(foo)]`. Outside of std/core, using an item with `#[unstable_feature_bound(foo)]` requires the feature to be enabled with `#![feature(foo)]` attribute on the crate. Currently, only `impl`s and free functions can be annotated with `#[unstable_feature_bound]`.
+
 [blog]: https://www.ralfj.de/blog/2018/07/19/const.html
diff --git a/src/doc/rustc-dev-guide/src/stabilization_guide.md b/src/doc/rustc-dev-guide/src/stabilization_guide.md
index f155272e5a2..e399930fc52 100644
--- a/src/doc/rustc-dev-guide/src/stabilization_guide.md
+++ b/src/doc/rustc-dev-guide/src/stabilization_guide.md
@@ -6,8 +6,6 @@
 
 Once an unstable feature has been well-tested with no outstanding concerns, anyone may push for its stabilization, though involving the people who have worked on it is prudent. Follow these steps:
 
-<!-- toc -->
-
 ## Write an RFC, if needed
 
 If the feature was part of a [lang experiment], the lang team generally will want to first accept an RFC before stabilization.
diff --git a/src/doc/rustc-dev-guide/src/test-implementation.md b/src/doc/rustc-dev-guide/src/test-implementation.md
index e906dd29f25..f09d7363199 100644
--- a/src/doc/rustc-dev-guide/src/test-implementation.md
+++ b/src/doc/rustc-dev-guide/src/test-implementation.md
@@ -1,7 +1,5 @@
 # The `#[test]` attribute
 
-<!-- toc -->
-
 
 
 Many Rust programmers rely on a built-in attribute called `#[test]`. All
diff --git a/src/doc/rustc-dev-guide/src/tests/adding.md b/src/doc/rustc-dev-guide/src/tests/adding.md
index 895eabfbd56..e5c26bef11d 100644
--- a/src/doc/rustc-dev-guide/src/tests/adding.md
+++ b/src/doc/rustc-dev-guide/src/tests/adding.md
@@ -1,7 +1,5 @@
 # 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 preventing us from repeating the
diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md
index a108dfdef9b..4980ed845d6 100644
--- a/src/doc/rustc-dev-guide/src/tests/compiletest.md
+++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md
@@ -1,7 +1,5 @@
 # Compiletest
 
-<!-- toc -->
-
 ## Introduction
 
 `compiletest` is the main test harness of the Rust test suite. It allows test
diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md
index 89e4d3e9b58..f4ba9a044e6 100644
--- a/src/doc/rustc-dev-guide/src/tests/directives.md
+++ b/src/doc/rustc-dev-guide/src/tests/directives.md
@@ -1,7 +1,5 @@
 # Compiletest directives
 
-<!-- toc -->
-
 <!--
 FIXME(jieyouxu) completely revise this chapter.
 -->
@@ -52,6 +50,8 @@ not be exhaustive. Directives can generally be found by browsing the
 
 ### Auxiliary builds
 
+See [Building auxiliary crates](compiletest.html#building-auxiliary-crates)
+
 | Directive             | Explanation                                                                                           | Supported test suites | Possible values                               |
 |-----------------------|-------------------------------------------------------------------------------------------------------|-----------------------|-----------------------------------------------|
 | `aux-bin`             | Build a aux binary, made available in `auxiliary/bin` relative to test directory                      | All except `run-make` | Path to auxiliary `.rs` file                  |
@@ -61,8 +61,7 @@ not be exhaustive. Directives can generally be found by browsing the
 | `proc-macro`          | Similar to `aux-build`, but for aux forces host and don't use `-Cprefer-dynamic`[^pm].                | All except `run-make` | Path to auxiliary proc-macro `.rs` file       |
 | `build-aux-docs`      | Build docs for auxiliaries as well.  Note that this only works with `aux-build`, not `aux-crate`.     | All except `run-make` | N/A                                           |
 
-[^pm]: please see the Auxiliary proc-macro section in the
-    [compiletest](./compiletest.md) chapter for specifics.
+[^pm]: please see the [Auxiliary proc-macro section](compiletest.html#auxiliary-proc-macro) in the compiletest chapter for specifics.
 
 ### Controlling outcome expectations
 
@@ -298,6 +297,7 @@ See [Pretty-printer](compiletest.md#pretty-printer-tests).
 - [`should-ice`](compiletest.md#incremental-tests) — incremental cfail should
       ICE
 - [`reference`] — an annotation linking to a rule in the reference
+- `disable-gdb-pretty-printers` — disable gdb pretty printers for debuginfo tests
 
 [`reference`]: https://github.com/rust-lang/reference/blob/master/docs/authoring.md#test-rule-annotations
 
@@ -358,7 +358,7 @@ described below:
   - Example: `x86_64-unknown-linux-gnu`
 
 See
-[`tests/ui/commandline-argfile.rs`](https://github.com/rust-lang/rust/blob/master/tests/ui/argfile/commandline-argfile.rs)
+[`tests/ui/argfile/commandline-argfile.rs`](https://github.com/rust-lang/rust/blob/master/tests/ui/argfile/commandline-argfile.rs)
 for an example of a test that uses this substitution.
 
 [output normalization]: ui.md#normalization
diff --git a/src/doc/rustc-dev-guide/src/tests/docker.md b/src/doc/rustc-dev-guide/src/tests/docker.md
index 032da1ca1e8..ae093984223 100644
--- a/src/doc/rustc-dev-guide/src/tests/docker.md
+++ b/src/doc/rustc-dev-guide/src/tests/docker.md
@@ -6,12 +6,12 @@ need to install Docker on a Linux, Windows, or macOS system (typically Linux
 will be much faster than Windows or macOS because the latter use virtual
 machines to emulate a Linux environment).
 
-Jobs running in CI are configured through a set of bash scripts, and it is not always trivial to reproduce their behavior locally. If you want to run a CI job locally in the simplest way possible, you can use a provided helper Python script that tries to replicate what happens on CI as closely as possible:
+Jobs running in CI are configured through a set of bash scripts, and it is not always trivial to reproduce their behavior locally. If you want to run a CI job locally in the simplest way possible, you can use a provided helper `citool` that tries to replicate what happens on CI as closely as possible:
 
 ```bash
-python3 src/ci/github-actions/ci.py run-local <job-name>
+cargo run --manifest-path src/ci/citool/Cargo.toml run-local <job-name>
 # For example:
-python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux-alt
+cargo run --manifest-path src/ci/citool/Cargo.toml run-local dist-x86_64-linux-alt
 ```
 
 If the above script does not work for you, you would like to have more control of the Docker image execution, or you want to understand what exactly happens during Docker job execution, then continue reading below.
@@ -53,15 +53,6 @@ Some additional notes about using the interactive mode:
   containers. With the container name, run `docker exec -it <CONTAINER>
   /bin/bash` where `<CONTAINER>` is the container name like `4ba195e95cef`.
 
-The approach described above is a relatively low-level interface for running the Docker images
-directly. If you want to run a full CI Linux job locally with Docker, in a way that is as close to CI as possible, you can use the following command:
-
-```bash
-cargo run --manifest-path src/ci/citool/Cargo.toml run-local <job-name>
-# For example:
-cargo run --manifest-path src/ci/citool/Cargo.toml run-local dist-x86_64-linux-alt
-```
-
 [Docker]: https://www.docker.com/
 [`src/ci/docker`]: https://github.com/rust-lang/rust/tree/master/src/ci/docker
 [`src/ci/docker/run.sh`]: https://github.com/rust-lang/rust/blob/master/src/ci/docker/run.sh
diff --git a/src/doc/rustc-dev-guide/src/tests/intro.md b/src/doc/rustc-dev-guide/src/tests/intro.md
index 79b96c450a8..b90c16d602c 100644
--- a/src/doc/rustc-dev-guide/src/tests/intro.md
+++ b/src/doc/rustc-dev-guide/src/tests/intro.md
@@ -1,7 +1,5 @@
 # Testing the compiler
 
-<!-- toc -->
-
 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
diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md
index 6526fe9c235..f6e313062cd 100644
--- a/src/doc/rustc-dev-guide/src/tests/running.md
+++ b/src/doc/rustc-dev-guide/src/tests/running.md
@@ -1,7 +1,5 @@
 # Running tests
 
-<!-- toc -->
-
 You can run the entire test collection using `x`. But note that running the
 *entire* test collection is almost never what you want to do during local
 development because it takes a really long time. For local development, see the
diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md
index 782f78d7614..25dd5814cf6 100644
--- a/src/doc/rustc-dev-guide/src/tests/ui.md
+++ b/src/doc/rustc-dev-guide/src/tests/ui.md
@@ -1,7 +1,5 @@
 # UI tests
 
-<!-- toc -->
-
 UI tests are a particular [test suite](compiletest.md#test-suites) of
 compiletest.
 
@@ -25,9 +23,9 @@ If you need to work with `#![no_std]` cross-compiling tests, consult the
 
 ## General structure of a test
 
-A test consists of a Rust source file located anywhere in the `tests/ui`
-directory, but they should be placed in a suitable sub-directory. For example,
-[`tests/ui/hello.rs`] is a basic hello-world test.
+A test consists of a Rust source file located in the `tests/ui` directory.
+**Tests must be placed in the appropriate subdirectory** based on their purpose
+and testing category - placing tests directly in `tests/ui` is not permitted.
 
 Compiletest will use `rustc` to compile the test, and compare the output against
 the expected output which is stored in a `.stdout` or `.stderr` file located
@@ -46,8 +44,6 @@ pass/fail expectations](#controlling-passfail-expectations).
 By default, a test is built as an executable binary. If you need a different
 crate type, you can use the `#![crate_type]` attribute to set it as needed.
 
-[`tests/ui/hello.rs`]: https://github.com/rust-lang/rust/blob/master/tests/ui/hello.rs
-
 ## Output comparison
 
 UI tests store the expected output from the compiler in `.stderr` and `.stdout`
diff --git a/src/doc/rustc-dev-guide/src/thir.md b/src/doc/rustc-dev-guide/src/thir.md
index 73d09ad80bf..3d3dafaef49 100644
--- a/src/doc/rustc-dev-guide/src/thir.md
+++ b/src/doc/rustc-dev-guide/src/thir.md
@@ -1,7 +1,5 @@
 # The THIR
 
-<!-- toc -->
-
 The THIR ("Typed High-Level Intermediate Representation"), previously called HAIR for
 "High-Level Abstract IR", is another IR used by rustc that is generated after
 [type checking]. It is (as of <!-- date-check --> January 2024) used for
diff --git a/src/doc/rustc-dev-guide/src/tracing.md b/src/doc/rustc-dev-guide/src/tracing.md
index 0cfdf306e92..5e5b81fc65b 100644
--- a/src/doc/rustc-dev-guide/src/tracing.md
+++ b/src/doc/rustc-dev-guide/src/tracing.md
@@ -1,7 +1,5 @@
 # Using tracing to debug the compiler
 
-<!-- toc -->
-
 The compiler has a lot of [`debug!`] (or `trace!`) calls, which print out logging information
 at many points. These are very useful to at least narrow down the location of
 a bug if not to find it entirely, or just to orient yourself as to why the
diff --git a/src/doc/rustc-dev-guide/src/traits/goals-and-clauses.md b/src/doc/rustc-dev-guide/src/traits/goals-and-clauses.md
index 40fd4581bf3..2884ca5a05a 100644
--- a/src/doc/rustc-dev-guide/src/traits/goals-and-clauses.md
+++ b/src/doc/rustc-dev-guide/src/traits/goals-and-clauses.md
@@ -1,7 +1,5 @@
 # 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)
diff --git a/src/doc/rustc-dev-guide/src/traits/lowering-to-logic.md b/src/doc/rustc-dev-guide/src/traits/lowering-to-logic.md
index 1248d434610..cc8b3bf800c 100644
--- a/src/doc/rustc-dev-guide/src/traits/lowering-to-logic.md
+++ b/src/doc/rustc-dev-guide/src/traits/lowering-to-logic.md
@@ -1,7 +1,5 @@
 # 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
diff --git a/src/doc/rustc-dev-guide/src/traits/resolution.md b/src/doc/rustc-dev-guide/src/traits/resolution.md
index c62b0593694..ccb2b04268e 100644
--- a/src/doc/rustc-dev-guide/src/traits/resolution.md
+++ b/src/doc/rustc-dev-guide/src/traits/resolution.md
@@ -1,7 +1,5 @@
 # Trait resolution (old-style)
 
-<!-- toc -->
-
 This chapter describes the general process of _trait resolution_ and points out
 some non-obvious things.
 
diff --git a/src/doc/rustc-dev-guide/src/ty.md b/src/doc/rustc-dev-guide/src/ty.md
index 767ac3fdba2..4055f475e99 100644
--- a/src/doc/rustc-dev-guide/src/ty.md
+++ b/src/doc/rustc-dev-guide/src/ty.md
@@ -1,7 +1,5 @@
 # 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.
 
diff --git a/src/doc/rustc-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md
index 888eb2439c5..2243205f129 100644
--- a/src/doc/rustc-dev-guide/src/type-inference.md
+++ b/src/doc/rustc-dev-guide/src/type-inference.md
@@ -1,7 +1,5 @@
 # Type inference
 
-<!-- toc -->
-
 Type inference is the process of automatic detection of the type of an
 expression.
 
diff --git a/src/doc/rustc-dev-guide/src/typing_parameter_envs.md b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md
index e21bc5155da..db15467a47a 100644
--- a/src/doc/rustc-dev-guide/src/typing_parameter_envs.md
+++ b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md
@@ -1,7 +1,5 @@
 # Typing/Parameter Environments
 
-<!-- toc -->
-
 ## Typing Environments
 
 When interacting with the type system there are a few variables to consider that can affect the results of trait solving. The set of in-scope where clauses, and what phase of the compiler type system operations are being performed in (the [`ParamEnv`][penv] and [`TypingMode`][tmode] structs respectively).
diff --git a/src/doc/rustc-dev-guide/src/variance.md b/src/doc/rustc-dev-guide/src/variance.md
index ad4fa4adfdd..7aa01407155 100644
--- a/src/doc/rustc-dev-guide/src/variance.md
+++ b/src/doc/rustc-dev-guide/src/variance.md
@@ -1,7 +1,5 @@
 # Variance of type and lifetime parameters
 
-<!-- toc -->
-
 For a more general background on variance, see the [background] appendix.
 
 [background]: ./appendix/background.html
diff --git a/src/doc/rustc-dev-guide/src/walkthrough.md b/src/doc/rustc-dev-guide/src/walkthrough.md
index 48b3f8bb15d..b4c3379347e 100644
--- a/src/doc/rustc-dev-guide/src/walkthrough.md
+++ b/src/doc/rustc-dev-guide/src/walkthrough.md
@@ -1,7 +1,5 @@
 # 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.
diff --git a/src/doc/rustc-dev-guide/triagebot.toml b/src/doc/rustc-dev-guide/triagebot.toml
index b3f4c2d281c..3ac5d57a52b 100644
--- a/src/doc/rustc-dev-guide/triagebot.toml
+++ b/src/doc/rustc-dev-guide/triagebot.toml
@@ -62,9 +62,6 @@ allow-unauthenticated = [
 # Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html
 [issue-links]
 
-# Automatically close and reopen PRs made by bots to run CI on them
-[bot-pull-requests]
-
 [behind-upstream]
 days-threshold = 7