From 4bbbd5802ddfce52d02f5cdc191f22019078df06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 5 Jan 2025 18:12:52 +0100 Subject: [PATCH 001/447] Preparing for merge from rustc --- rust-version | 1 + 1 file changed, 1 insertion(+) diff --git a/rust-version b/rust-version index e69de29bb..876c32dcf 100644 --- a/rust-version +++ b/rust-version @@ -0,0 +1 @@ +dcfa38fe234de9304169afc6638e81d0dd222c06 From 1dad69ebd457edf61377ae3041ab8e3858255f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 6 Jan 2025 11:30:59 +0100 Subject: [PATCH 002/447] Add rustc-dev-guide to the list of repositories managed by josh (#2197) --- src/external-repos.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/external-repos.md b/src/external-repos.md index a7ab3d773..8f9819300 100644 --- a/src/external-repos.md +++ b/src/external-repos.md @@ -21,6 +21,7 @@ The following external projects are managed using some form of a `subtree`: * [rustfmt](https://github.com/rust-lang/rustfmt) * [rust-analyzer](https://github.com/rust-lang/rust-analyzer) * [rustc_codegen_cranelift](https://github.com/rust-lang/rustc_codegen_cranelift) +* [rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide) In contrast to `submodule` dependencies (see below for those), the `subtree` dependencies are just regular files and directories which can @@ -38,8 +39,9 @@ implement a new tool feature or test, that should happen in one collective rustc * Using the [josh] tool * `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo)) * `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147)) + * `rustc-dev-guide` ([sync guide](https://github.com/rust-lang/rustc-dev-guide#synchronizing-josh-subtree-with-rustc)) -The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh, you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. If you want to migrate a subtree from `git subtree` to josh, you can check out [this guide](https://hackmd.io/7pOuxnkdQDaL1Y1FQr65xg). +The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh, you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. If you want to migrate a repository dependency from `git subtree` or `git submodule` to josh, you can check out [this guide](https://hackmd.io/7pOuxnkdQDaL1Y1FQr65xg). Below you can find a guide on how to perform push and pull synchronization with the main rustc repo using `git subtree`, although these instructions might differ repo from repo. From 32835d18d80af8c47d6167172ea37712628277b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 6 Jan 2025 00:32:06 +0800 Subject: [PATCH 003/447] Only keep label description in Forge docs --- src/contributing.md | 62 +-------------------------------------------- 1 file changed, 1 insertion(+), 61 deletions(-) diff --git a/src/contributing.md b/src/contributing.md index ad1d33265..9817326f0 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -422,68 +422,8 @@ Just a few things to keep in mind: ## Issue triage -Sometimes, an issue will stay open, even though the bug has been fixed. -And sometimes, the original bug may go stale because something has changed in the meantime. +Please see . -It can be helpful to go through older bug reports and make sure that they are still valid. -Load up an older issue, double check that it's still true, -and leave a comment letting us know if it is or is not. -The [least recently updated sort][lru] is good for finding issues like this. - -[Thanks to `@rustbot`][rustbot], anyone can help triage issues by adding -appropriate labels to issues that haven't been triaged yet: - -[lru]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-asc -[rustbot]: ./rustbot.md - - - -| Labels | Color | Description | -|--------|-------|-------------| -| [A-] |  Yellow | The **area** of the project an issue relates to. | -| [B-] |  Magenta | Issues which are **blockers**. | -| [beta-] |  Dark Blue | Tracks changes which need to be [backported to beta][beta-backport] | -| [C-] |  Light Purple | The **category** of an issue. | -| [D-] |  Mossy Green | Issues for **diagnostics**. | -| [E-] |  Green | The **experience** level necessary to fix an issue. | -| [F-] |  Peach | Issues for **nightly features**. | -| [I-] |  Red | The **importance** of the issue. | -| [I-\*-nominated] |  Red | The issue has been nominated for discussion at the next meeting of the corresponding team. | -| [I-prioritize] |  Red | The issue has been nominated for prioritization by the team tagged with a **T**-prefixed label. | -| [L-] |  Teal | The relevant **lint**. | -| [metabug] |  Purple | Bugs that collect other bugs. | -| [O-] |  Purple Grey | The **operating system** or platform that the issue is specific to. | -| [P-] |  Orange | The issue **priority**. These labels can be assigned by anyone that understand the issue and is able to prioritize it, and remove the [I-prioritize] label. | -| [regression-] |  Pink | Tracks regressions from a stable release. | -| [relnotes] |  Light Orange | Changes that should be documented in the release notes of the next release. | -| [S-] |  Gray | Tracks the **status** of pull requests. | -| [S-tracking-] |  Steel Blue | Tracks the **status** of [tracking issues]. | -| [stable-] |  Dark Blue | Tracks changes which need to be [backported to stable][stable-backport] in anticipation of a point release. | -| [T-] |  Blue | Denotes which **team** the issue belongs to. | -| [WG-] |  Green | Denotes which **working group** the issue belongs to. | - - -[A-]: https://github.com/rust-lang/rust/labels?q=A -[B-]: https://github.com/rust-lang/rust/labels?q=B -[C-]: https://github.com/rust-lang/rust/labels?q=C -[D-]: https://github.com/rust-lang/rust/labels?q=D -[E-]: https://github.com/rust-lang/rust/labels?q=E -[F-]: https://github.com/rust-lang/rust/labels?q=F -[I-]: https://github.com/rust-lang/rust/labels?q=I -[L-]: https://github.com/rust-lang/rust/labels?q=L -[O-]: https://github.com/rust-lang/rust/labels?q=O -[P-]: https://github.com/rust-lang/rust/labels?q=P -[S-]: https://github.com/rust-lang/rust/labels?q=S -[T-]: https://github.com/rust-lang/rust/labels?q=T -[WG-]: https://github.com/rust-lang/rust/labels?q=WG [stable-]: https://github.com/rust-lang/rust/labels?q=stable [beta-]: https://github.com/rust-lang/rust/labels?q=beta [I-\*-nominated]: https://github.com/rust-lang/rust/labels?q=nominated From 0fd52366ca06dc505859b6dba7bea4e6ed959818 Mon Sep 17 00:00:00 2001 From: Max Heller Date: Tue, 7 Jan 2025 03:00:59 -0500 Subject: [PATCH 004/447] Fix broken raw HTML (#2198) --- src/appendix/glossary.md | 2 +- src/bug-fix-procedure.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/appendix/glossary.md b/src/appendix/glossary.md index bf3475a98..a7c3236d3 100644 --- a/src/appendix/glossary.md +++ b/src/appendix/glossary.md @@ -69,7 +69,7 @@ Term | Meaning rib | A data structure in the name resolver that keeps track of a single scope for names. ([see more](../name-resolution.md)) RPIT | A return-position `impl Trait`. ([see the reference](https://doc.rust-lang.org/reference/types/impl-trait.html#abstract-return-types)). RPITIT | A return-position `impl Trait` in trait. Unlike RPIT, this is desugared to a generic associated type (GAT). Introduced in [RFC 3425](https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html). ([see more](../return-position-impl-trait-in-trait.md)) -scrutinee | A scrutinee is the expression that is matched on in `match` expressions and similar pattern matching constructs. For example, in `match x { A => 1, B => 2 }`, the expression `x` is the scrutinee. +scrutinee | A scrutinee is the expression that is matched on in `match` expressions and similar pattern matching constructs. For example, in `match x { A => 1, B => 2 }`, the expression `x` is the scrutinee. `sess` | The compiler _session_, which stores global data used throughout compilation side tables | Because the [AST](#ast) and HIR are immutable once created, we often carry extra information about them in the form of hashtables, indexed by the id of a particular node. sigil | Like a keyword but composed entirely of non-alphanumeric tokens. For example, `&` is a sigil for references. diff --git a/src/bug-fix-procedure.md b/src/bug-fix-procedure.md index 4857cf5e0..e6a16df6d 100644 --- a/src/bug-fix-procedure.md +++ b/src/bug-fix-procedure.md @@ -227,7 +227,7 @@ that we use for unstable features: Ideally, breaking changes should have landed on the **stable branch** of the compiler before they are finalized. - + ### Removing a lint From 280d73878ad8bf003a7646622e00ae9e3cf8090f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 7 Jan 2025 18:48:02 +0100 Subject: [PATCH 005/447] Update rustc-dev-guide --- src/building/optimized-build.md | 2 +- src/tests/ci.md | 7 +++---- src/tests/docker.md | 9 +++++++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/building/optimized-build.md b/src/building/optimized-build.md index 3080dc6bf..8feda5982 100644 --- a/src/building/optimized-build.md +++ b/src/building/optimized-build.md @@ -126,4 +126,4 @@ Here is an example of how can `opt-dist` be used locally (outside of CI): [`Environment`]: https://github.com/rust-lang/rust/blob/ee451f8faccf3050c76cdcd82543c917b40c7962/src/tools/opt-dist/src/environment.rs#L5 > Note: if you want to run the actual CI pipeline, instead of running `opt-dist` locally, -> you can execute `DEPLOY=1 src/ci/docker/run.sh dist-x86_64-linux`. +> you can execute `python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux`. diff --git a/src/tests/ci.md b/src/tests/ci.md index 5e27a2fd7..0ad1d2a28 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -28,7 +28,7 @@ Our CI is primarily executed on [GitHub Actions], with a single workflow defined in [`.github/workflows/ci.yml`], which contains a bunch of steps that are unified for all CI jobs that we execute. When a commit is pushed to a corresponding branch or a PR, the workflow executes the -[`calculate-job-matrix.py`] script, which dynamically generates the specific CI +[`ci.py`] script, which dynamically generates the specific CI jobs that should be executed. This script uses the [`jobs.yml`] file as an input, which contains a declarative configuration of all our CI jobs. @@ -299,8 +299,7 @@ platform’s custom [Docker container]. This has a lot of advantages for us: - We can avoid reinstalling tools (like QEMU or the Android emulator) every time thanks to Docker image caching. - Users can run the same tests in the same environment locally by just running - `src/ci/docker/run.sh image-name`, which is awesome to debug failures. Note - that there are only linux docker images available locally due to licensing and + `python3 src/ci/github-actions/ci.py run-local `, which is awesome to debug failures. Note that there are only linux docker images available locally due to licensing and other restrictions. The docker images prefixed with `dist-` are used for building artifacts while @@ -413,7 +412,7 @@ To learn more about the dashboard, see the [Datadog CI docs]. [GitHub Actions]: https://github.com/rust-lang/rust/actions [`jobs.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/jobs.yml [`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/master/.github/workflows/ci.yml -[`calculate-job-matrix.py`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/calculate-job-matrix.py +[`ci.py`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/ci.py [rust-lang-ci]: https://github.com/rust-lang-ci/rust/actions [bors]: https://github.com/bors [homu]: https://github.com/rust-lang/homu diff --git a/src/tests/docker.md b/src/tests/docker.md index 31e3825f5..a0aa8bd3e 100644 --- a/src/tests/docker.md +++ b/src/tests/docker.md @@ -45,6 +45,15 @@ Some additional notes about using the Docker images: containers. With the container name, run `docker exec -it /bin/bash` where `` 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 +python3 src/ci/github-actions/ci.py run-local +# For example: +python3 src/ci/github-actions/ci.py 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 From 8789c2cf9b73b68c6a6fbab64ef92ec50d9c3f72 Mon Sep 17 00:00:00 2001 From: Samson <16504129+sagudev@users.noreply.github.com> Date: Tue, 7 Jan 2025 21:29:45 +0100 Subject: [PATCH 006/447] Fix rib example related zulip thread: https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp/topic/Ribs.20in.20name.20resolution --- src/name-resolution.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/name-resolution.md b/src/name-resolution.md index 2727b8142..719ebce85 100644 --- a/src/name-resolution.md +++ b/src/name-resolution.md @@ -120,9 +120,9 @@ even though they should be visible by ordinary scoping rules. An example: fn do_something(val: T) { // <- New rib in both types and values (1) // `val` is accessible, as is the helper function // `T` is accessible - let helper = || { // New rib on `helper` (2) and another on the block (3) + let helper = || { // New rib on the block (2) // `val` is accessible here - }; // End of (3) + }; // End of (2), new rib on `helper` (3) // `val` is accessible, `helper` variable shadows `helper` function fn helper() { // <- New rib in both types and values (4) // `val` is not accessible here, (4) is not transparent for locals @@ -130,7 +130,7 @@ fn do_something(val: T) { // <- New rib in both types and values (1) } // End of (4) let val = T::default(); // New rib (5) // `val` is the variable, not the parameter here -} // End of (5), (2) and (1) +} // End of (5), (3) and (1) ``` Because the rules for different namespaces are a bit different, each namespace From 55ac466fd7ffacc7e6d5b274a56b292738a57442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 8 Jan 2025 13:40:40 +0100 Subject: [PATCH 007/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 876c32dcf..651db7864 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -dcfa38fe234de9304169afc6638e81d0dd222c06 +9c87288a7d2f03625a813df6d3bfe43c09ad4f5a From 57d1e6b068512d2dd52e7e90a2b96240899ff36a Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 6 Jan 2025 08:58:29 +0100 Subject: [PATCH 008/447] Save linkcheck cache always --- .github/workflows/ci.yml | 22 ++++++++++++++++------ book.toml | 4 +++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 07c20d8d8..1b5c41417 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,12 +35,13 @@ jobs: ~/.cargo/bin key: ${{ runner.os }}-${{ env.MDBOOK_VERSION }}--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ env.MDBOOK_TOC_VERSION }}--${{ env.MDBOOK_MERMAID_VERSION }} - - name: Cache linkcheck - uses: actions/cache@v4 + - name: Restore cached Linkcheck + if: github.event_name == 'schedule' + id: cache-linkcheck-restore + uses: actions/cache/restore@v4 with: - path: | - ~/book/linkcheck - key: ${{ runner.os }}-${{ hashFiles('./book/linkcheck') }} + path: book/linkcheck/cache.json + key: linkcheck - name: Install latest nightly Rust toolchain if: steps.mdbook-cache.outputs.cache-hit != 'true' @@ -57,7 +58,16 @@ jobs: cargo install mdbook-mermaid --version ${{ env.MDBOOK_MERMAID_VERSION }} - name: Check build - run: ENABLE_LINKCHECK=1 mdbook build + run: mdbook build + continue-on-error: true + + - name: Save cached Linkcheck + id: cache-linkcheck-save + if: github.event_name == 'schedule' + uses: actions/cache/save@v4 + with: + path: book/linkcheck/cache.json + key: linkcheck - name: Deploy to gh-pages if: github.event_name == 'push' diff --git a/book.toml b/book.toml index 2f67aecf6..67069d993 100644 --- a/book.toml +++ b/book.toml @@ -52,7 +52,9 @@ exclude = [ # 500 is returned for HEAD request "code\\.visualstudio\\.com/docs/editor/tasks", ] -cache-timeout = 86400 +# The scheduled CI runs every day and so we need to reuse a part of the cache +# in order to face "Server returned 429 Too Many Requests" errors for github.com. +cache-timeout = 90000 warning-policy = "error" [output.html.redirect] From 10c76e1bfc6fe65c0dd0c3304349ae12339758bb Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 8 Jan 2025 17:06:15 +0100 Subject: [PATCH 009/447] Update key --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b5c41417..3c45ad164 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: uses: actions/cache/restore@v4 with: path: book/linkcheck/cache.json - key: linkcheck + key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }} - name: Install latest nightly Rust toolchain if: steps.mdbook-cache.outputs.cache-hit != 'true' @@ -58,7 +58,7 @@ jobs: cargo install mdbook-mermaid --version ${{ env.MDBOOK_MERMAID_VERSION }} - name: Check build - run: mdbook build + run: ENABLE_LINKCHECK=1 mdbook build continue-on-error: true - name: Save cached Linkcheck @@ -67,7 +67,7 @@ jobs: uses: actions/cache/save@v4 with: path: book/linkcheck/cache.json - key: linkcheck + key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }} - name: Deploy to gh-pages if: github.event_name == 'push' From c92957d38a6486dbcb7ac0668e4b24b02f94ccbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 8 Jan 2025 15:26:14 +0100 Subject: [PATCH 010/447] Print an explicit message if the base repo head commit is up-to-date --- josh-sync/src/sync.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/josh-sync/src/sync.rs b/josh-sync/src/sync.rs index da21a4c9a..1c1757a46 100644 --- a/josh-sync/src/sync.rs +++ b/josh-sync/src/sync.rs @@ -45,6 +45,11 @@ impl GitSync { let josh_url = format!("http://localhost:{JOSH_PORT}/{UPSTREAM_REPO}.git@{commit}{JOSH_FILTER}.git"); + let previous_base_commit = sh.read_file("rust-version")?.trim().to_string(); + if previous_base_commit == commit { + return Err(anyhow::anyhow!("No changes since last pull")); + } + // Update rust-version file. As a separate commit, since making it part of // the merge has confused the heck out of josh in the past. // We pass `--no-verify` to avoid running git hooks. From 482ebfbbae7d4a4b20b25378c4ba2d13a1734101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 8 Jan 2025 17:17:03 +0100 Subject: [PATCH 011/447] Error if there is nothing to pull --- josh-sync/src/sync.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/josh-sync/src/sync.rs b/josh-sync/src/sync.rs index 1c1757a46..eff80b109 100644 --- a/josh-sync/src/sync.rs +++ b/josh-sync/src/sync.rs @@ -81,12 +81,22 @@ impl GitSync { }; let num_roots_before = num_roots()?; + let sha = cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout; + // Merge the fetched commit. const MERGE_COMMIT_MESSAGE: &str = "Merge from rustc"; cmd!(sh, "git merge FETCH_HEAD --no-verify --no-ff -m {MERGE_COMMIT_MESSAGE}") .run() .context("FAILED to merge new commits, something went wrong")?; + let current_sha = cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout; + if current_sha == sha { + cmd!(sh, "git reset --hard HEAD^") + .run() + .expect("FAILED to clean up after creating the preparation commit"); + return Err(anyhow::anyhow!("No merge was performed, nothing to pull. Rolled back the preparation commit.")); + } + // Check that the number of roots did not increase. if num_roots()? != num_roots_before { bail!("Josh created a new root commit. This is probably not the history you want."); From bb0051a0061b8f20484cad3ba315163118ea62ad Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 9 Jan 2025 13:24:42 -0800 Subject: [PATCH 012/447] ci: Remove incorrect use of `continue-on-error` This will cause the CI build to be marked successful even if the build failed. Instead, use `if: '!cancelled()'` to always save the cache (except when the job is cancelled), even if the linkcheck failed. See https://stackoverflow.com/a/58859404 for more. --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c45ad164..006bcce44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,11 +59,10 @@ jobs: - name: Check build run: ENABLE_LINKCHECK=1 mdbook build - continue-on-error: true - name: Save cached Linkcheck id: cache-linkcheck-save - if: github.event_name == 'schedule' + if: ${{ !cancelled() && github.event_name == 'schedule' }} uses: actions/cache/save@v4 with: path: book/linkcheck/cache.json From 42768820febab846c1bdf326fe81705af65920f4 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 10 Jan 2025 08:16:37 -0800 Subject: [PATCH 013/447] Document how to find the configuration used in CI This documents how to determine which settings are used in CI, since I see this question come up regularly. We currently don't have a great way to answer the question, but at least there is something. --- src/tests/ci.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tests/ci.md b/src/tests/ci.md index 5e27a2fd7..3940928f9 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -410,6 +410,21 @@ To learn more about the dashboard, see the [Datadog CI docs]. [Datadog CI docs]: https://docs.datadoghq.com/continuous_integration/ [public dashboard]: https://p.datadoghq.com/sb/3a172e20-e9e1-11ed-80e3-da7ad0900002-b5f7bb7e08b664a06b08527da85f7e30 +## Determining the CI configuration + +If you want to determine which `config.toml` settings are used in CI for a +particular job, it is probably easiest to just look at the build log. To do +this: + +1. Go to + + to find the most recently successful build, and click on it. +2. Choose the job you are interested in on the left-hand side. +3. Click on the gear icon and choose "View raw logs" +4. Search for the string "Configure the build" +5. All of the build settings are listed below that starting with the + `configure:` prefix. + [GitHub Actions]: https://github.com/rust-lang/rust/actions [`jobs.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/jobs.yml [`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/master/.github/workflows/ci.yml From cd9705f029884ccde7b021ed49c42607b174749c Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 10 Jan 2025 08:26:52 -0800 Subject: [PATCH 014/447] Fix calculate-job-matrix.py link --- src/tests/ci.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/ci.md b/src/tests/ci.md index 5e27a2fd7..e325b8e38 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -28,7 +28,7 @@ Our CI is primarily executed on [GitHub Actions], with a single workflow defined in [`.github/workflows/ci.yml`], which contains a bunch of steps that are unified for all CI jobs that we execute. When a commit is pushed to a corresponding branch or a PR, the workflow executes the -[`calculate-job-matrix.py`] script, which dynamically generates the specific CI +[`src/ci/github-actions/ci.py`] script, which dynamically generates the specific CI jobs that should be executed. This script uses the [`jobs.yml`] file as an input, which contains a declarative configuration of all our CI jobs. @@ -413,7 +413,7 @@ To learn more about the dashboard, see the [Datadog CI docs]. [GitHub Actions]: https://github.com/rust-lang/rust/actions [`jobs.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/jobs.yml [`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/master/.github/workflows/ci.yml -[`calculate-job-matrix.py`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/calculate-job-matrix.py +[`src/ci/github-actions/ci.py`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/ci.py [rust-lang-ci]: https://github.com/rust-lang-ci/rust/actions [bors]: https://github.com/bors [homu]: https://github.com/rust-lang/homu From 4c02798cb44de021b8fffd056bc3a138f9329840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 8 Jan 2025 17:54:02 +0100 Subject: [PATCH 015/447] Add CI workflow for performing rustc-pull --- .github/workflows/rustc-pull.yml | 55 ++++++++++++++++++++++++++++++++ triagebot.toml | 3 ++ 2 files changed, 58 insertions(+) create mode 100644 .github/workflows/rustc-pull.yml diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml new file mode 100644 index 000000000..dcb90b84d --- /dev/null +++ b/.github/workflows/rustc-pull.yml @@ -0,0 +1,55 @@ +name: rustc-pull + +on: + workflow_dispatch: + schedule: + # Run at 04:00 UTC every Monday + - cron: '0 4 * * 1' + +jobs: + pull: + if: github.repository == 'rust-lang/rustc-dev-guide' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - uses: actions/checkout@v4 + with: + # We need the full history for josh to work + fetch-depth: '0' + - name: Install stable Rust toolchain + run: rustup update stable + - uses: Swatinem/rust-cache@v2 + with: + workspaces: "josh-sync" + # Cache the josh directory with checked out rustc + cache-directories: "/home/runner/.cache/rustc-dev-guide-josh" + - name: Install josh + run: RUSTFLAGS="--cap-lints warn" cargo +stable install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04 + - name: Setup bot git name and email + run: | + git config --global user.name 'The rustc-dev-guide Cronjob Bot' + git config --global user.email 'github-actions@github.com' + - name: Perform rustc-pull + run: cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull + - name: Push changes to a branch + run: | + # Update a sticky branch that is used only for rustc pulls + BRANCH="rustc-pull" + git switch -c $BRANCH + git push -u origin $BRANCH --force + - name: Create pull request + run: | + # Check if an open pull request for an rustc pull update already exists + # If it does, the previous push has just updated it + # If not, we create it now + RESULT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | length' --json title` + if [[ "$RESULT" -eq 0 ]]; then + echo "Creating new pull request" + gh pr create -B master --title 'Rustc pull update' --body 'Latest update from rustc.' + else + echo "Updated existing pull request" + fi + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/triagebot.toml b/triagebot.toml index ccb0de862..12aa0b7b8 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -6,3 +6,6 @@ allow-unauthenticated = [ "waiting-on-author", "blocked", ] + +# Automatically close and reopen PRs made by bots to run CI on them +[bot-pull-requests] From eecd68cf55b686a8e60d39aff4b11801a296fd16 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 12 Jan 2025 08:47:57 +0300 Subject: [PATCH 016/447] rustc-dev-guide: update outdated LLVM stamp filename Signed-off-by: onur-ozkan --- src/backend/debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/debugging.md b/src/backend/debugging.md index 275a1777a..805291017 100644 --- a/src/backend/debugging.md +++ b/src/backend/debugging.md @@ -56,7 +56,7 @@ These tools include: By default, the Rust build system does not check for changes to the LLVM source code or its build configuration settings. So, if you need to rebuild the LLVM that is linked -into `rustc`, first delete the file `llvm-finished-building`, which should be located +into `rustc`, first delete the file `.llvm-stamp`, which should be located in `build//llvm/`. The default rustc compilation pipeline has multiple codegen units, which is From a58b85a26cfd908bb14e8c2cb6304d80ff100001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sun, 12 Jan 2025 11:41:34 +0800 Subject: [PATCH 017/447] rustc-dev-guide: document `BOOTSTRAP_TRACING` and bootstrap `tracing` setup --- src/SUMMARY.md | 1 + .../bootstrapping/debugging-bootstrap.md | 100 ++++++++++++++++++ .../tracing-output-example.png | Bin 0 -> 140711 bytes src/building/bootstrapping/intro.md | 3 + 4 files changed, 104 insertions(+) create mode 100644 src/building/bootstrapping/debugging-bootstrap.md create mode 100644 src/building/bootstrapping/debugging-bootstrap/tracing-output-example.png diff --git a/src/SUMMARY.md b/src/SUMMARY.md index a8fddbc75..91c4aeacb 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -75,6 +75,7 @@ - [Prologue](./building/bootstrapping/intro.md) - [What Bootstrapping does](./building/bootstrapping/what-bootstrapping-does.md) - [How Bootstrap does it](./building/bootstrapping/how-bootstrap-does-it.md) +- [Debugging bootstrap](./building/bootstrapping/debugging-bootstrap.md) # High-level Compiler Architecture diff --git a/src/building/bootstrapping/debugging-bootstrap.md b/src/building/bootstrapping/debugging-bootstrap.md new file mode 100644 index 000000000..972b4a8fb --- /dev/null +++ b/src/building/bootstrapping/debugging-bootstrap.md @@ -0,0 +1,100 @@ +# Debugging bootstrap + +> FIXME: this page could be expanded + +## `tracing` in bootstrap + +Bootstrap has conditional [`tracing`][tracing] setup to provide structured logging. + +[tracing]: https://docs.rs/tracing/0.1.41/tracing/index.html + +### Enabling `tracing` output + +Bootstrap will conditionally enable `tracing` output if the `BOOTSTRAP_TRACING` env var is set. + +Example usage: + +```bash +$ BOOTSTRAP_TRACING=TRACE ./x build library --stage 1 +``` + +Example output[^experimental]: + +![Example bootstrap tracing output](./debugging-bootstrap/tracing-output-example.png) + +[^experimental]: This shows what's *possible* with the infra in an experimental implementation. + +The env var `BOOTSTRAP_TRACING` accepts a [`tracing` env-filter][tracing-env-filter]. The `TRACE` filter will enable *all* `trace` level or less verbose level tracing output. + +[tracing-env-filter]: https://docs.rs/tracing-subscriber/0.3.19/tracing_subscriber/filter/struct.EnvFilter.html + +### Using `tracing` in bootstrap + +Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need to be gated behind `tracing` feature. Examples: + +```rs +#[cfg(feature = "tracing")] +use tracing::{instrument, trace}; + +struct Foo; + +impl Step for Foo { + type Output = (); + + #[cfg_attr(feature = "tracing", instrument(level = "trace", name = "Foo::should_run", skip_all))] + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + #[cfg(feature = "tracing")] + trace!(?run, "entered Foo::should_run"); + + todo!() + } + + #[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "Foo::run", + skip_all, + fields(compiler = ?builder.compiler), + ), + )] + fn run(self, builder: &Builder<'_>) -> Self::Output { + #[cfg(feature = "tracing")] + trace!(?run, "entered Foo::run"); + + todo!() + } +} +``` + +For `#[instrument]`, it's recommended to: + +- Gate it behind `trace` level for fine-granularity, possibly `debug` level for core functions. +- Explicitly pick an instrumentation name via `name = ".."` to distinguish between e.g. `run` of different steps. +- Take care to not cause diverging behavior via tracing, e.g. building extra things only when tracing infra is enabled. + +### Enabling `tracing` bootstrap feature in rust-analyzer + +You can adjust your `settings.json`'s `rust-analyzer.check.overrideCommand` and `rust-analyzer.cargo.buildScripts.overrideCommand` if you want to also enable `logging` cargo feature by default in your editor. This is mostly useful if you want proper r-a completions and such when working on bootstrap itself. + +```json +"rust-analyzer.check.overrideCommand": [ + "BOOTSTRAP_TRACING=1", // <- BOOTSTRAP_TRACING=1 won't enable tracing filter, but it will activate bootstrap's `tracing` feature + "python3", + "x.py", + "check", + "--json-output", + "--build-dir=build-rust-analyzer" +], +``` + +```json +"rust-analyzer.cargo.buildScripts.overrideCommand": [ + "BOOTSTRAP_TRACING=1", // <- note this + "python3", + "x.py", + "check", + "--json-output", + "--build-dir=build-rust-analyzer" +], +``` diff --git a/src/building/bootstrapping/debugging-bootstrap/tracing-output-example.png b/src/building/bootstrapping/debugging-bootstrap/tracing-output-example.png new file mode 100644 index 0000000000000000000000000000000000000000..745aec50d4a36563fa2701a3647506b29576518a GIT binary patch literal 140711 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

(^WK44=cvB_&R#yN?@avo_z#Y8bN?d# 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

z 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 literal 0 HcmV?d00001 diff --git a/src/building/bootstrapping/intro.md b/src/building/bootstrapping/intro.md index f829884fb..f72918c83 100644 --- a/src/building/bootstrapping/intro.md +++ b/src/building/bootstrapping/intro.md @@ -17,5 +17,8 @@ In this section, we give a high-level overview of [what Bootstrap does](./what-bootstrapping-does.md), followed by a high-level introduction to [how Bootstrap does it](./how-bootstrap-does-it.md). +Additionally, see [debugging bootstrap](./debugging-bootstrap.md) to learn +about debugging methods. + [boot]: https://en.wikipedia.org/wiki/Bootstrapping_(compilers) [ocaml-compiler]: https://github.com/rust-lang/rust/tree/ef75860a0a72f79f97216f8aaa5b388d98da6480/src/boot From 1cd70aaa2c6d84eae8effc74180ad3b5d6ef16b7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 14 Jan 2025 17:00:12 +0100 Subject: [PATCH 018/447] rustc-dev-guide: add note about not adding rustc_allowed_through_unstable_modules to more items --- src/stability.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/stability.md b/src/stability.md index 1bfe911c9..230925252 100644 --- a/src/stability.md +++ b/src/stability.md @@ -34,7 +34,8 @@ Previously, due to a [rustc bug], stable items inside unstable modules were available to stable code in that location. As of September 2024, items with [accidentally stabilized paths] are marked with the `#[rustc_allowed_through_unstable_modules]` attribute -to prevent code dependent on those paths from breaking. +to prevent code dependent on those paths from breaking. Do *not* add this attribute +to any more items unless that is needed to avoid breaking changes. The `unstable` attribute may also have the `soft` value, which makes it a future-incompatible deny-by-default lint instead of a hard error. This is used From 7a4c3d3c30d5dcff62722bfb9edf963e4d8c0c77 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Tue, 14 Jan 2025 21:48:24 -0800 Subject: [PATCH 019/447] Fix some broken links * Rename `StringReader -> Lexer` * Remove deleted `Query` struct * Update some internal links --- src/appendix/code-index.md | 3 +-- src/guides/editions.md | 4 ++-- src/overview.md | 4 ++-- src/the-parser.md | 6 +++--- src/ty_module/param_ty_const_regions.md | 4 ++-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/appendix/code-index.md b/src/appendix/code-index.md index c33887d72..b96ede68e 100644 --- a/src/appendix/code-index.md +++ b/src/appendix/code-index.md @@ -14,17 +14,16 @@ Item | Kind | Short description | Chapter | `Diag` | struct | A struct for a compiler diagnostic, such as an error or lint | [Emitting Diagnostics] | [compiler/rustc_errors/src/diagnostic.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html) `DocContext` | struct | A state container used by rustdoc when crawling through a crate to gather its documentation | [Rustdoc] | [src/librustdoc/core.rs](https://github.com/rust-lang/rust/blob/master/src/librustdoc/core.rs) `HirId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/hir_id.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir_id/struct.HirId.html) +`Lexer` | struct | This is the lexer used during parsing. It consumes characters from the raw source code being compiled and produces a series of tokens for use by the rest of the parser | [The parser] | [compiler/rustc_parse/src/lexer/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html) `NodeId` | struct | One of four types of HIR node identifiers. Being phased out | [Identifiers in the HIR] | [compiler/rustc_ast/src/ast.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/node_id/struct.NodeId.html) `P` | struct | An owned immutable smart pointer. By contrast, `&T` is not owned, and `Box` is not immutable. | None | [compiler/rustc_ast/src/ptr.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ptr/struct.P.html) `ParamEnv` | struct | Information about generic parameters or `Self`, useful for working with associated or generic items | [Parameter Environment] | [compiler/rustc_middle/src/ty/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html) `ParseSess` | struct | This struct contains information about a parsing session | [The parser] | [compiler/rustc_session/src/parse/parse.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.ParseSess.html) -`Query` | struct | Represents the result of query to the `Compiler` interface and allows stealing, borrowing, and returning the results of compiler passes. | [The Rustc Driver and Interface] | [compiler/rustc_interface/src/queries.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/queries/struct.Query.html) `Rib` | struct | Represents a single scope of names | [Name resolution] | [compiler/rustc_resolve/src/lib.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.Rib.html) `Session` | struct | The data associated with a compilation session | [The parser], [The Rustc Driver and Interface] | [compiler/rustc_session/src/session.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html) `SourceFile` | struct | Part of the `SourceMap`. Maps AST nodes to their source code for a single source file. Was previously called FileMap | [The parser] | [compiler/rustc_span/src/lib.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.SourceFile.html) `SourceMap` | struct | Maps AST nodes to their source code. It is composed of `SourceFile`s. Was previously called CodeMap | [The parser] | [compiler/rustc_span/src/source_map.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/source_map/struct.SourceMap.html) `Span` | struct | A location in the user's source code, used for error reporting primarily | [Emitting Diagnostics] | [compiler/rustc_span/src/span_encoding.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html) -`StringReader` | struct | This is the lexer used during parsing. It consumes characters from the raw source code being compiled and produces a series of tokens for use by the rest of the parser | [The parser] | [compiler/rustc_parse/src/lexer/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.StringReader.html) `rustc_ast::token_stream::TokenStream` | struct | An abstract sequence of tokens, organized into `TokenTree`s | [The parser], [Macro expansion] | [compiler/rustc_ast/src/tokenstream.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/tokenstream/struct.TokenStream.html) `TraitDef` | struct | This struct contains a trait's definition with type information | [The `ty` modules] | [compiler/rustc_middle/src/ty/trait_def.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait_def/struct.TraitDef.html) `TraitRef` | struct | The combination of a trait and its input types (e.g. `P0: Trait`) | [Trait Solving: Goals and Clauses] | [compiler/rustc_middle/src/ty/sty.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.TraitRef.html) diff --git a/src/guides/editions.md b/src/guides/editions.md index 336e391df..ea2071677 100644 --- a/src/guides/editions.md +++ b/src/guides/editions.md @@ -91,7 +91,7 @@ stability. ## Edition parsing For the most part, the lexer is edition-agnostic. -Within [`StringReader`], tokens can be modified based on edition-specific behavior. +Within [`Lexer`], tokens can be modified based on edition-specific behavior. For example, C-String literals like `c"foo"` are split into multiple tokens in editions before 2021. This is also where things like reserved prefixes are handled for the 2021 edition. @@ -114,7 +114,7 @@ For example, the deprecated `start...end` pattern syntax emits the [`ellipsis_inclusive_range_patterns`] lint on editions before 2021, and in 2021 is an hard error via the `emit_err` method. -[`StringReader`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.StringReader.html +[`Lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html [`ParseSess::edition`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.ParseSess.html#structfield.edition [`ellipsis_inclusive_range_patterns`]: https://doc.rust-lang.org/nightly/rustc/lints/listing/warn-by-default.html#ellipsis-inclusive-range-patterns diff --git a/src/overview.md b/src/overview.md index cc17eaa9e..21ab00406 100644 --- a/src/overview.md +++ b/src/overview.md @@ -38,7 +38,7 @@ Unicode character encoding. The token stream passes through a higher-level lexer located in [`rustc_parse`] to prepare for the next stage of the compile process. The -[`StringReader`] `struct` is used at this stage to perform a set of validations +[`Lexer`] `struct` is used at this stage to perform a set of validations and turn strings into interned symbols (_interning_ is discussed later). [String interning] is a way of storing only one immutable copy of each distinct string value. @@ -153,7 +153,7 @@ the final binary. [`rustc_parse::parser::Parser`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html [`rustc_parse`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html [`simplify_try`]: https://github.com/rust-lang/rust/pull/66282 -[`StringReader`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.StringReader.html +[`Lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html [`Ty<'tcx>`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html [borrow checking]: borrow_check.md [codegen]: backend/codegen.md diff --git a/src/the-parser.md b/src/the-parser.md index 703ef2794..60a71ae38 100644 --- a/src/the-parser.md +++ b/src/the-parser.md @@ -52,7 +52,7 @@ the token stream, and then execute the parser to get a [`Crate`] (the root AST node). To minimize the amount of copying that is done, -both [`StringReader`] and [`Parser`] have lifetimes which bind them to the parent [`ParseSess`]. +both [`Lexer`] and [`Parser`] have lifetimes which bind them to the parent [`ParseSess`]. This contains all the information needed while parsing, as well as the [`SourceMap`] itself. Note that while parsing, we may encounter macro definitions or invocations. @@ -67,7 +67,7 @@ Code for lexical analysis is split between two crates: constituting tokens. Although it is popular to implement lexers as generated finite state machines, the lexer in [`rustc_lexer`] is hand-written. -- [`StringReader`] integrates [`rustc_lexer`] with data structures specific to +- [`Lexer`] integrates [`rustc_lexer`] with data structures specific to `rustc`. Specifically, it adds `Span` information to tokens returned by [`rustc_lexer`] and interns identifiers. @@ -76,7 +76,7 @@ Code for lexical analysis is split between two crates: [`ParseSess`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.ParseSess.html [`rustc_lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lexer/index.html [`SourceMap`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/source_map/struct.SourceMap.html -[`StringReader`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.StringReader.html +[`Lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html [ast module]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/index.html [ast]: ./ast-validation.md [parser]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/index.html diff --git a/src/ty_module/param_ty_const_regions.md b/src/ty_module/param_ty_const_regions.md index 6b467724f..e6dfe8a66 100644 --- a/src/ty_module/param_ty_const_regions.md +++ b/src/ty_module/param_ty_const_regions.md @@ -65,7 +65,7 @@ The rules against shadowing make this difficult but those language rules could c ### Lifetime parameters -In contrast to `Ty`/`Const`'s `Param` singular `Param` variant, lifetimes have two variants for representing region parameters: [`RegionKind::EarlyParam`] and [`RegionKind::LateParam`]. The reason for this is due to function's distinguishing between [early and late bound parameters](../early-late-bound-params/early-late-bound-summary.md) which is discussed in an earlier chapter (see link). +In contrast to `Ty`/`Const`'s `Param` singular `Param` variant, lifetimes have two variants for representing region parameters: [`RegionKind::EarlyParam`] and [`RegionKind::LateParam`]. The reason for this is due to function's distinguishing between [early and late bound parameters][ch_early_late_bound] which is discussed in an earlier chapter (see link). `RegionKind::EarlyParam` is structured identically to `Ty/Const`'s `Param` variant, it is simply a `u32` index and a `Symbol`. For lifetime parameters defined on non-function items we always use `ReEarlyParam`. For functions we use `ReEarlyParam` for any early bound parameters and `ReLateParam` for any late bound parameters. Note that just like `Ty` and `Const` params we often debug format them as `'SYMBOL/#INDEX`, see for example: @@ -85,7 +85,7 @@ fn foo<'a, 'b, T: 'a>(one: T, two: &'a &'b u32) -> &'b u32 { `RegionKind::LateParam` will be discussed more in the chapter on [instantiating binders][ch_instantiating_binders]. -[ch_early_late_bound]: ../early-late-bound-params/early-late-bound-summary.md +[ch_early_late_bound]: ../early_late_parameters.md [ch_binders]: ./binders.md [ch_instantiating_binders]: ./instantiating_binders.md [`BoundRegionKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.BoundRegionKind.html From b4940bbed6c572fd703f13ead070484f4a79cc47 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Tue, 14 Jan 2025 23:01:42 -0800 Subject: [PATCH 020/447] fix some more typos --- src/backend/backend-agnostic.md | 2 +- src/closure.md | 2 +- src/const-eval.md | 2 +- src/diagnostics.md | 2 +- src/opaque-types-impl-trait-inference.md | 2 +- src/solve/caching.md | 4 ++-- src/solve/invariants.md | 4 ++-- src/solve/the-solver.md | 4 ++-- src/traits/implied-bounds.md | 4 ++-- src/ty_module/binders.md | 2 +- src/ty_module/early_binder.md | 2 +- src/ty_module/param_ty_const_regions.md | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/backend/backend-agnostic.md b/src/backend/backend-agnostic.md index 3521c00f5..0f81d3cb4 100644 --- a/src/backend/backend-agnostic.md +++ b/src/backend/backend-agnostic.md @@ -45,7 +45,7 @@ heavily on other parts of the crate. The separation of the code must not affect the logic of the code nor its performance. For these reasons, the separation process involves two transformations that -have to be done at the same time for the resulting code to compile : +have to be done at the same time for the resulting code to compile: 1. replace all the LLVM-specific types by generics inside function signatures and structure definitions; diff --git a/src/closure.md b/src/closure.md index 718a0e5d7..427919cd5 100644 --- a/src/closure.md +++ b/src/closure.md @@ -157,7 +157,7 @@ The other option is to step through the code using lldb or gdb. 1. `rust-lldb build/host/stage1/bin/rustc test.rs` 2. In lldb: - 1. `b upvar.rs:134` // Setting the breakpoint on a certain line in the upvar.rs file` + 1. `b upvar.rs:134` // Setting the breakpoint on a certain line in the upvar.rs file 2. `r` // Run the program until it hits the breakpoint Let's start with [`upvar.rs`][upvar]. This file has something called diff --git a/src/const-eval.md b/src/const-eval.md index ee0269601..69329a3e0 100644 --- a/src/const-eval.md +++ b/src/const-eval.md @@ -17,7 +17,7 @@ Prominent examples are: * need to be known to check for overlapping patterns Additionally constant evaluation can be used to reduce the workload or binary -size at runtime by precomputing complex operations at compiletime and only +size at runtime by precomputing complex operations at compile time and only storing the result. All uses of constant evaluation can either be categorized as "influencing the type system" diff --git a/src/diagnostics.md b/src/diagnostics.md index ccd101165..709e9d4f8 100644 --- a/src/diagnostics.md +++ b/src/diagnostics.md @@ -111,7 +111,7 @@ Here are a few examples: their crate, making this a hard error would make refactoring and development very painful. - [future-incompatible lints]: - these are silencable lints. + these are silenceable lints. It was decided that making them fixed errors would cause too much breakage, so warnings are instead emitted, and will eventually be turned into fixed (hard) errors. diff --git a/src/opaque-types-impl-trait-inference.md b/src/opaque-types-impl-trait-inference.md index c56d51a4b..bdf4e4cd8 100644 --- a/src/opaque-types-impl-trait-inference.md +++ b/src/opaque-types-impl-trait-inference.md @@ -78,7 +78,7 @@ If that fails, we reveal the hidden type of the opaque type, but only to prove this specific trait bound, not in general. Revealing is done by invoking the `type_of` query on the `DefId` of the opaque type. The query will internally request the hidden types from the defining function(s) -and return that (see [the section on `type_of`](#Within-the-type_of-query) for more details). +and return that (see [the section on `type_of`](#within-the-type_of-query) for more details). #### Flowchart of type checking steps diff --git a/src/solve/caching.md b/src/solve/caching.md index 72b90c59b..e568d47ca 100644 --- a/src/solve/caching.md +++ b/src/solve/caching.md @@ -98,8 +98,8 @@ TODO: write this :3 [req-depth-ck]: https://github.com/rust-lang/rust/blob/7606c13961ddc1174b70638e934df0439b7dc515/compiler/rustc_middle/src/traits/solve/cache.rs#L76-L86 [update-depth]: https://github.com/rust-lang/rust/blob/7606c13961ddc1174b70638e934df0439b7dc515/compiler/rustc_trait_selection/src/solve/search_graph.rs#L308 [rem-depth]: https://github.com/rust-lang/rust/blob/7606c13961ddc1174b70638e934df0439b7dc515/compiler/rustc_middle/src/traits/solve/cache.rs#L124 -[^1]: This is overly restrictive: if all nested goal return the overflow response with some -availabledepth `n`, then their result should be the same for any depths smaller than `n`. +[^1]: This is overly restrictive: if all nested goals return the overflow response with some +available depth `n`, then their result should be the same for any depths smaller than `n`. We can implement this optimization in the future. [chapter on coinduction]: ./coinduction.md diff --git a/src/solve/invariants.md b/src/solve/invariants.md index c16a3aeb2..588da490a 100644 --- a/src/solve/invariants.md +++ b/src/solve/invariants.md @@ -33,7 +33,7 @@ inference variables in both the lhs and rhs, the now potentially structurally di types should still be equal to each other. Needed to prevent goals from succeeding in HIR typeck and then failing in MIR borrowck. -If this does invariant is broken MIR typeck ends up failing with an ICE. +If this invariant is broken MIR typeck ends up failing with an ICE. ### Applying inference results from a goal does not change its result ❌ @@ -91,7 +91,7 @@ it can easily result in unsoundness, e.g. [#57893](https://github.com/rust-lang/ If a trait goal holds with an empty environment, there should be a unique `impl`, either user-defined or builtin, which is used to prove that goal. This is -necessary to select a unique method. It +necessary to select a unique method. We do however break this invariant in few cases, some of which are due to bugs, some by design: diff --git a/src/solve/the-solver.md b/src/solve/the-solver.md index f7d82d117..006fb649d 100644 --- a/src/solve/the-solver.md +++ b/src/solve/the-solver.md @@ -25,7 +25,7 @@ a separate "probe", to not leak inference constraints to the other candidates. We then try to merge the assembled candidates via `EvalCtxt::merge_candidates`. -## Important concepts and design pattern +## Important concepts and design patterns ### `EvalCtxt::add_goal` @@ -64,7 +64,7 @@ eagerly instantiates `'a` with a placeholder and then recursively proves Some goals can be proven in multiple ways. In these cases we try each option in a separate "probe" and then attempt to merge the resulting responses by using `EvalCtxt::try_merge_responses`. If merging the responses fails, we use -`EvalCtxt::flounder` instead, returning ambiguity. For some goals, we try +`EvalCtxt::flounder` instead, returning ambiguity. For some goals, we try to incompletely prefer some choices over others in case `EvalCtxt::try_merge_responses` fails. diff --git a/src/traits/implied-bounds.md b/src/traits/implied-bounds.md index 911553ad3..63b09a43f 100644 --- a/src/traits/implied-bounds.md +++ b/src/traits/implied-bounds.md @@ -41,7 +41,7 @@ requirements of impls and functions as explicit predicates. These bounds are not added to the `ParamEnv` of the affected item itself. For lexical region resolution they are added using [`fn OutlivesEnvironment::with_bounds`]. -Similarly,during MIR borrowck we add them using +Similarly, during MIR borrowck we add them using [`fn UniversalRegionRelationsBuilder::add_implied_bounds`]. [We add implied bounds for the function signature and impl header in MIR borrowck][mir]. @@ -81,4 +81,4 @@ This results in multiple unsoundnesses: [#25860]: https://github.com/rust-lang/rust/issues/25860 [#84591]: https://github.com/rust-lang/rust/issues/84591 -[#100051]: https://github.com/rust-lang/rust/issues/100051 \ No newline at end of file +[#100051]: https://github.com/rust-lang/rust/issues/100051 diff --git a/src/ty_module/binders.md b/src/ty_module/binders.md index 6f31103d7..defb7cde5 100644 --- a/src/ty_module/binders.md +++ b/src/ty_module/binders.md @@ -16,7 +16,7 @@ Usages of these parameters is represented by the `RegionKind::Bound` (or `TyKind - A [`BoundVar`] which specifies which of the parameters the `Binder` introduces we are referring to. - We also sometimes store some extra information for diagnostics reasons via the [`BoundTyKind`]/[`BoundRegionKind`] but this is not important for type equality or more generally the semantics of `Ty`. (omitted from the above example) -In debug output (and also informally when talking to eachother) we tend to write these bound variables in the format of `^DebruijnIndex_BoundVar`. The above example would instead be written as `Binder(fn(&'^0_0), &[BoundVariableKind::Region])`. Sometimes when the `DebruijnIndex` is `0` we just omit it and would write `^0`. +In debug output (and also informally when talking to each other) we tend to write these bound variables in the format of `^DebruijnIndex_BoundVar`. The above example would instead be written as `Binder(fn(&'^0_0), &[BoundVariableKind::Region])`. Sometimes when the `DebruijnIndex` is `0` we just omit it and would write `^0`. Another concrete example, this time a mixture of `for<'a>` in a where clause and a type: ``` diff --git a/src/ty_module/early_binder.md b/src/ty_module/early_binder.md index e8ff3a530..d83d73c95 100644 --- a/src/ty_module/early_binder.md +++ b/src/ty_module/early_binder.md @@ -48,7 +48,7 @@ fn bar(foo: Foo) { In the compiler the `instantiate` call for this is done in [`FieldDef::ty`] ([src][field_def_ty_src]), at some point during type checking `bar` we will wind up calling `FieldDef::ty(x, &[u32, f32])` in order to obtain the type of `foo.x`. **Note on indices:** It is a bug if the index of a `Param` does not match what the `EarlyBinder` binds. For -example, if the index is out of bounds or the index index of a lifetime corresponds to a type parameter. +example, if the index is out of bounds or the index of a lifetime corresponds to a type parameter. These sorts of errors are caught earlier in the compiler during name resolution where we disallow references to generics parameters introduced by items that should not be nameable by the inner item. diff --git a/src/ty_module/param_ty_const_regions.md b/src/ty_module/param_ty_const_regions.md index e6dfe8a66..c52f0c0df 100644 --- a/src/ty_module/param_ty_const_regions.md +++ b/src/ty_module/param_ty_const_regions.md @@ -53,7 +53,7 @@ Concretely given the `ty::Generics` for the item the parameter is defined on, if The index fully defines the `Ty` and is the only part of `TyKind::Param` that matters for reasoning about the code we are compiling. -Generally we do not care what the name is and only use the index is included for diagnostics and debug logs as otherwise it would be +Generally we do not care what the name is and only use the index. The name is included for diagnostics and debug logs as otherwise it would be incredibly difficult to understand the output, i.e. `Vec: Sized` vs `Vec: Sized`. In debug output, parameter types are often printed out as `{name}/#{index}`, for example in the function `foo` if we were to debug print `Vec` it would be written as `Vec`. From 46458edee5b278670883443c526c134ed494d1f3 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 15 Jan 2025 14:20:48 +0100 Subject: [PATCH 021/447] nyaa --- src/borrow_check/region_inference/closure_constraints.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/borrow_check/region_inference/closure_constraints.md b/src/borrow_check/region_inference/closure_constraints.md index be279b773..b95c9f723 100644 --- a/src/borrow_check/region_inference/closure_constraints.md +++ b/src/borrow_check/region_inference/closure_constraints.md @@ -31,9 +31,9 @@ It starts by calling `fn try_promote_type_test_subject`. This function takes the We then promote the `lower_bound` into the context of the caller. If the lower bound is equal to a placeholder, we replace it with `'static` -We then look at all universal regions `uv` which are required to outlive `lower_bound`, i.e. for which borrow checking adding region constraints. For each of these we then emit a `ClosureOutlivesRequirement` for non-local universal regions which are known to outlive `uv`. +We then look at all universal regions `uv` which are required to be outlived by `lower_bound`, i.e. for which borrow checking added region constraints. For each of these we then emit a `ClosureOutlivesRequirement` for all non-local universal regions which are known to outlive `uv`. -As we've already built the region graph of the closure at this point and emitted errors if that one is inconsistent, we are also able to assume that the outlive constraints `uv: lower_bound` hold. +As we've already built the region graph of the closure at this point and separately check that it is consistent, we are also able to assume the outlive constraints `uv: lower_bound` here. So if we have a type-outlives bounds we can't prove, e.g. `T: 'local_infer`, we use the region graph to go to universal variables `'a` with `'a: local_infer`. In case `'a` are local, we then use the assumed outlived constraints to go to non-local ones. From e9d9b29d0699b060c1dfc01d09cb46fa0db2babd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Fri, 17 Jan 2025 08:40:04 +0800 Subject: [PATCH 022/447] compiletest: fix outdated `rustdoc-js` test suite name --- src/tests/directives.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 69f4c8641..ea9caf8d0 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -248,7 +248,7 @@ Consider writing the test as a proper incremental test instead. | Directive | Explanation | Supported test suites | Possible values | |-------------|--------------------------------------------------------------|------------------------------------------|---------------------------| -| `doc-flags` | Flags passed to `rustdoc` when building the test or aux file | `rustdoc`, `js-doc-test`, `rustdoc-json` | Any valid `rustdoc` flags | +| `doc-flags` | Flags passed to `rustdoc` when building the test or aux file | `rustdoc`, `rustdoc-js`, `rustdoc-json` | Any valid `rustdoc` flags | ` marker at the place where you want the TOC. This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the following commands to synchronize the subtree in both directions. +You'll need to install `josh-proxy` locally via + +``` +cargo +stable install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04 +``` +Older versions of `josh-proxy` may not round trip commits losslessly so it is important to install this exact version. + ### Pull changes from `rust-lang/rust` into this repository 1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide` 2) Run the pull command From 0ae03351d2f6a4e877698d2e17a395cc6d76eb7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 20 Jan 2025 13:51:50 +0100 Subject: [PATCH 026/447] Add portable SIMD to list of subtrees --- src/external-repos.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/external-repos.md b/src/external-repos.md index 8f9819300..f3170c922 100644 --- a/src/external-repos.md +++ b/src/external-repos.md @@ -18,6 +18,7 @@ The following external projects are managed using some form of a `subtree`: * [clippy](https://github.com/rust-lang/rust-clippy) * [miri](https://github.com/rust-lang/miri) +* [portable-simd](https://github.com/rust-lang/portable-simd) * [rustfmt](https://github.com/rust-lang/rustfmt) * [rust-analyzer](https://github.com/rust-lang/rust-analyzer) * [rustc_codegen_cranelift](https://github.com/rust-lang/rustc_codegen_cranelift) @@ -34,6 +35,7 @@ implement a new tool feature or test, that should happen in one collective rustc * Using `git subtree` * `clippy` ([sync guide](https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html#performing-the-sync-from-rust-langrust-to-clippy)) + * `portable-simd` ([sync script](https://github.com/rust-lang/portable-simd/blob/master/subtree-sync.sh)) * `rustfmt` * `rustc_codegen_cranelift` ([sync script](https://github.com/rust-lang/rustc_codegen_cranelift/blob/113af154d459e41b3dc2c5d7d878e3d3a8f33c69/scripts/rustup.sh#L7)) * Using the [josh] tool From c89935feca87f791143be2a94923fee322f04657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 20 Jan 2025 14:11:57 +0100 Subject: [PATCH 027/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 651db7864..9693bfd63 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -9c87288a7d2f03625a813df6d3bfe43c09ad4f5a +ecda83b30f0f68cf5692855dddc0bc38ee8863fc From f9cb2ec0e7ac73a2ffa15316a0dc7f86eeba1242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 20 Jan 2025 17:30:09 +0100 Subject: [PATCH 028/447] Send a message to Zulip when a sync finishes --- .github/workflows/rustc-pull.yml | 34 ++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index dcb90b84d..87a3ee2e7 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -10,6 +10,8 @@ jobs: pull: if: github.repository == 'rust-lang/rustc-dev-guide' runs-on: ubuntu-latest + outputs: + pr_url: ${{ steps.update-pr.outputs.pr_url }} permissions: contents: write pull-requests: write @@ -40,6 +42,7 @@ jobs: git switch -c $BRANCH git push -u origin $BRANCH --force - name: Create pull request + id: update-pr run: | # Check if an open pull request for an rustc pull update already exists # If it does, the previous push has just updated it @@ -47,9 +50,36 @@ jobs: RESULT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | length' --json title` if [[ "$RESULT" -eq 0 ]]; then echo "Creating new pull request" - gh pr create -B master --title 'Rustc pull update' --body 'Latest update from rustc.' + PR_URL=gh pr create -B master --title 'Rustc pull update' --body 'Latest update from rustc.' + echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT else - echo "Updated existing pull request" + PR_URL=gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title + echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + send-zulip-message: + needs: [pull] + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + - name: Compute message + id: message + run: | + if [ "${{ needs.pull.result }}" == "failure" ]; + then + WORKFLOW_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + echo "message=Rustc pull sync failed. Check out the [workflow URL]($WORKFLOW_URL)." >> $GITHUB_OUTPUT + else + echo "message=Rustc pull sync succeeded. Check out the [PR](${{ needs.pull.outputs.pr_url }})." >> $GITHUB_OUTPUT + fi + - name: Send a Zulip message about updated PR + uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 + with: + api-key: ${{ secrets.ZULIP_API_TOKEN }} + email: "rustc-dev-guide-gha-notif-bot@rust-lang.zulipchat.com" + organization-url: "https://rust-lang.zulipchat.com" + to: 196385 + type: "stream" + topic: "Subtree sync automation" + content: ${{ steps.message.outputs.message }} From 3543f80951b15788044a6e483b7cf02fa0aa7423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 6 Jan 2025 17:23:28 +0100 Subject: [PATCH 029/447] Add test for checking used glibc symbols --- src/tests/directives.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/directives.md b/src/tests/directives.md index e80857b7a..426a6ff1d 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -152,6 +152,8 @@ Some examples of `X` in `ignore-X` or `only-X`: `compare-mode-split-dwarf`, `compare-mode-split-dwarf-single` - The two different test modes used by coverage tests: `ignore-coverage-map`, `ignore-coverage-run` +- When testing a dist toolchain: `dist` + - This needs to be enabled with `COMPILETEST_ENABLE_DIST_TESTS=1` The following directives will check rustc build settings and target settings: From 7fb252d7fe8dd1d7f5e6f1d3f842ae40de95a900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 21 Jan 2025 17:00:28 +0100 Subject: [PATCH 030/447] Add `@bors rollup=never` to rustc-push PR body --- josh-sync/src/sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/josh-sync/src/sync.rs b/josh-sync/src/sync.rs index eff80b109..7ff5e018d 100644 --- a/josh-sync/src/sync.rs +++ b/josh-sync/src/sync.rs @@ -180,7 +180,7 @@ impl GitSync { ); println!( // Open PR with `subtree update` title to silence the `no-merges` triagebot check - " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=Rustc+dev+guide+subtree+update&body=r?+@ghost" + " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=Rustc+dev+guide+subtree+update&body=@bors+rollup=never%0Ar?+@ghost" ); drop(josh); From 851d9a5b20dee21ac7dfd31d811379856bdece56 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:00:36 +0000 Subject: [PATCH 031/447] Remove set_make_codegen_backend and set_file_loader They can both be set inside the config callback too. --- examples/rustc-driver-example.rs | 13 ++++++------- examples/rustc-driver-interacting-with-the-ast.rs | 13 ++++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/examples/rustc-driver-example.rs b/examples/rustc-driver-example.rs index 576bbcea9..b77172841 100644 --- a/examples/rustc-driver-example.rs +++ b/examples/rustc-driver-example.rs @@ -19,7 +19,7 @@ use std::path::Path; use rustc_ast_pretty::pprust::item_to_string; use rustc_data_structures::sync::Lrc; use rustc_driver::{Compilation, RunCompiler}; -use rustc_interface::interface::Compiler; +use rustc_interface::interface::{Compiler, Config}; use rustc_middle::ty::TyCtxt; struct MyFileLoader; @@ -51,6 +51,10 @@ fn main() { struct MyCallbacks; impl rustc_driver::Callbacks for MyCallbacks { + fn config(&mut self, config: &mut Config) { + config.file_loader = Some(Box::new(MyFileLoader)); + } + fn after_crate_root_parsing( &mut self, _compiler: &Compiler, @@ -83,10 +87,5 @@ impl rustc_driver::Callbacks for MyCallbacks { } fn main() { - match RunCompiler::new(&["main.rs".to_string()], &mut MyCallbacks) { - mut compiler => { - compiler.set_file_loader(Some(Box::new(MyFileLoader))); - compiler.run(); - } - } + RunCompiler::new(&["main.rs".to_string()], &mut MyCallbacks).run(); } diff --git a/examples/rustc-driver-interacting-with-the-ast.rs b/examples/rustc-driver-interacting-with-the-ast.rs index 90a85d5db..6c06bbed5 100644 --- a/examples/rustc-driver-interacting-with-the-ast.rs +++ b/examples/rustc-driver-interacting-with-the-ast.rs @@ -19,7 +19,7 @@ use std::path::Path; use rustc_ast_pretty::pprust::item_to_string; use rustc_data_structures::sync::Lrc; use rustc_driver::{Compilation, RunCompiler}; -use rustc_interface::interface::Compiler; +use rustc_interface::interface::{Compiler, Config}; use rustc_middle::ty::TyCtxt; struct MyFileLoader; @@ -51,6 +51,10 @@ fn main() { struct MyCallbacks; impl rustc_driver::Callbacks for MyCallbacks { + fn config(&mut self, config: &mut Config) { + config.file_loader = Some(Box::new(MyFileLoader)); + } + fn after_crate_root_parsing( &mut self, _compiler: &Compiler, @@ -90,10 +94,5 @@ impl rustc_driver::Callbacks for MyCallbacks { } fn main() { - match RunCompiler::new(&["main.rs".to_string()], &mut MyCallbacks) { - mut compiler => { - compiler.set_file_loader(Some(Box::new(MyFileLoader))); - compiler.run(); - } - } + RunCompiler::new(&["main.rs".to_string()], &mut MyCallbacks).run(); } From 76f7584f6a008bc0a5829a4dd82840e501c6140b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:13:14 +0000 Subject: [PATCH 032/447] Remove RunCompiler It has become nothing other than a wrapper around run_compiler. --- examples/rustc-driver-example.rs | 4 ++-- examples/rustc-driver-interacting-with-the-ast.rs | 4 ++-- src/rustc-driver/intro.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/rustc-driver-example.rs b/examples/rustc-driver-example.rs index b77172841..8983915d7 100644 --- a/examples/rustc-driver-example.rs +++ b/examples/rustc-driver-example.rs @@ -18,7 +18,7 @@ use std::path::Path; use rustc_ast_pretty::pprust::item_to_string; use rustc_data_structures::sync::Lrc; -use rustc_driver::{Compilation, RunCompiler}; +use rustc_driver::{Compilation, run_compiler}; use rustc_interface::interface::{Compiler, Config}; use rustc_middle::ty::TyCtxt; @@ -87,5 +87,5 @@ impl rustc_driver::Callbacks for MyCallbacks { } fn main() { - RunCompiler::new(&["main.rs".to_string()], &mut MyCallbacks).run(); + run_compiler(&["main.rs".to_string()], &mut MyCallbacks); } diff --git a/examples/rustc-driver-interacting-with-the-ast.rs b/examples/rustc-driver-interacting-with-the-ast.rs index 6c06bbed5..c894b6044 100644 --- a/examples/rustc-driver-interacting-with-the-ast.rs +++ b/examples/rustc-driver-interacting-with-the-ast.rs @@ -18,7 +18,7 @@ use std::path::Path; use rustc_ast_pretty::pprust::item_to_string; use rustc_data_structures::sync::Lrc; -use rustc_driver::{Compilation, RunCompiler}; +use rustc_driver::{Compilation, run_compiler}; use rustc_interface::interface::{Compiler, Config}; use rustc_middle::ty::TyCtxt; @@ -94,5 +94,5 @@ impl rustc_driver::Callbacks for MyCallbacks { } fn main() { - RunCompiler::new(&["main.rs".to_string()], &mut MyCallbacks).run(); + run_compiler(&["main.rs".to_string()], &mut MyCallbacks); } diff --git a/src/rustc-driver/intro.md b/src/rustc-driver/intro.md index a6234dc12..40500e6bc 100644 --- a/src/rustc-driver/intro.md +++ b/src/rustc-driver/intro.md @@ -6,7 +6,7 @@ The [`rustc_driver`] is essentially `rustc`'s `main` function. It acts as the glue for running the various phases of the compiler in the correct order, using the interface defined in the [`rustc_interface`] crate. Where possible, using [`rustc_driver`] rather than [`rustc_interface`] is recommended. -The main entry point of [`rustc_driver`] is [`rustc_driver::RunCompiler`][rd_rc]. +The main entry point of [`rustc_driver`] is [`rustc_driver::run_compiler`][rd_rc]. This builder accepts the same command-line args as rustc as well as an implementation of [`Callbacks`][cb] and a couple of other optional options. [`Callbacks`][cb] is a `trait` that allows for custom compiler configuration, as well as allowing custom code to run after different phases of the compilation. @@ -40,7 +40,7 @@ specifically [`rustc_driver_impl::run_compiler`][rdi_rc] [cb]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/trait.Callbacks.html [example]: https://github.com/rust-lang/rustc-dev-guide/blob/master/examples/rustc-interface-example.rs [i_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/fn.run_compiler.html -[rd_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/struct.RunCompiler.html +[rd_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/fn.run_compiler.html [rdi_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver_impl/fn.run_compiler.html [stupid-stats]: https://github.com/nrc/stupid-stats [`nightly-rustc`]: https://doc.rust-lang.org/nightly/nightly-rustc/ From 0f175948cdfe12d6ae4973eec25a791f058adf64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:39:04 +0800 Subject: [PATCH 033/447] rustc-dev-guide: document `needs-subprocess` directive --- src/tests/directives.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 426a6ff1d..7366e55d3 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -94,7 +94,7 @@ for more details. | Directive | Explanation | Supported test suites | Possible values | |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------|----------------------------------------------|-----------------------------------------------------------------------------------------| | `check-run-results` | Check run test binary `run-{pass,fail}` output snapshot | `ui`, `crashes`, `incremental` if `run-pass` | N/A | -| `error-pattern` | Check that output contains a specific string | `ui`, `crashes`, `incremental` if `run-pass` | String | +| `error-pattern` | Check that output contains a specific string | `ui`, `crashes`, `incremental` if `run-pass` | String | | `regex-error-pattern` | Check that output contains a regex pattern | `ui`, `crashes`, `incremental` if `run-pass` | Regex | | `check-stdout` | Check `stdout` against `error-pattern`s from running test binary[^check_stdout] | `ui`, `crashes`, `incremental` | N/A | | `normalize-stderr-32bit` | Normalize actual stderr (for 32-bit platforms) with a rule `"" -> ""` before comparing against snapshot | `ui`, `incremental` | `"" -> ""`, ``/`` is regex capture and replace syntax | @@ -176,6 +176,7 @@ settings: - `needs-rust-lld` — ignores if the rust lld support is not enabled (`rust.lld = true` in `config.toml`) - `needs-threads` — ignores if the target does not have threading support +- `needs-subprocess` — ignores if the target does not have subprocess support - `needs-symlink` — ignores if the target does not support symlinks. This can be the case on Windows if the developer did not enable privileged symlink permissions. From 80aac13e782ac3c0217ac792a4a188f9523ab7d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 23 Jan 2025 20:09:13 +0100 Subject: [PATCH 034/447] Document Python formatting and linting in the rustc-dev-guide --- src/conventions.md | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/conventions.md b/src/conventions.md index 37af8121c..4010e9082 100644 --- a/src/conventions.md +++ b/src/conventions.md @@ -1,4 +1,4 @@ -This file offers some tips on the coding conventions for rustc. This +This file offers some tips on the coding conventions for rustc. This chapter covers [formatting](#formatting), [coding for correctness](#cc), [using crates from crates.io](#cio), and some tips on [structuring your PR for easy review](#er). @@ -25,6 +25,7 @@ pass the `--edition=2021` argument yourself when c `rustfmt` directly. [fmt]: https://github.com/rust-dev-tools/fmt-rfcs + [`rustfmt`]:https://github.com/rust-lang/rustfmt ## Formatting C++ code @@ -40,6 +41,26 @@ When modifying that code, use this command to format it: This uses a pinned version of `clang-format`, to avoid relying on the local environment. +## Formatting and linting Python code + +The Rust repository contains quite a lof of Python code. We try to keep +it both linted and formatted by the [ruff][ruff] tool. + +When modifying Python code, use this command to format it: +```sh +./x test tidy --extra-checks=py:fmt --bless +``` + +and the following command to run lints: +```sh +./x test tidy --extra-checks=py:lint +``` + +This uses a pinned version of `ruff`, to avoid relying on the local +environment. + +[ruff]: https://github.com/astral-sh/ruff + @@ -84,7 +105,7 @@ Using `_` in a match is convenient, but it means that when new variants are added to the enum, they may not get handled correctly. Ask yourself: if a new variant were added to this enum, what's the chance that it would want to use the `_` code, versus having some -other treatment? Unless the answer is "low", then prefer an +other treatment? Unless the answer is "low", then prefer an exhaustive match. (The same advice applies to `if let` and `while let`, which are effectively tests for a single variant.) @@ -124,7 +145,7 @@ See the [crates.io dependencies][crates] section. # How to structure your PR How you prepare the commits in your PR can make a big difference for the -reviewer. Here are some tips. +reviewer. Here are some tips. **Isolate "pure refactorings" into their own commit.** For example, if you rename a method, then put that rename into its own commit, along @@ -165,4 +186,5 @@ to the compiler. crate-related, often the spelling is changed to `krate`. [tcx]: ./ty.md + [crates]: ./crates-io.md From d56358082cd5995f4532cd192ec05ce0fc8abc22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 24 Jan 2025 13:59:05 +0100 Subject: [PATCH 035/447] Revert "Add `@bors rollup=never` to rustc-push PR body" --- josh-sync/src/sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/josh-sync/src/sync.rs b/josh-sync/src/sync.rs index 7ff5e018d..eff80b109 100644 --- a/josh-sync/src/sync.rs +++ b/josh-sync/src/sync.rs @@ -180,7 +180,7 @@ impl GitSync { ); println!( // Open PR with `subtree update` title to silence the `no-merges` triagebot check - " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=Rustc+dev+guide+subtree+update&body=@bors+rollup=never%0Ar?+@ghost" + " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=Rustc+dev+guide+subtree+update&body=r?+@ghost" ); drop(josh); From 168456e7a30062684b418e7944f62d0ed6ba01fb Mon Sep 17 00:00:00 2001 From: Ada Alakbarova <58857108+ada4a@users.noreply.github.com> Date: Fri, 24 Jan 2025 14:12:17 +0100 Subject: [PATCH 036/447] fix(solve/significant-changes): typo --- src/solve/significant-changes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solve/significant-changes.md b/src/solve/significant-changes.md index c5bb8a01b..c82b5d468 100644 --- a/src/solve/significant-changes.md +++ b/src/solve/significant-changes.md @@ -42,7 +42,7 @@ old implementation structurally relates the aliases instead. This enables the new solver to stall equality until it is able to normalize the related aliases. The behavior of the old solver is incomplete and relies on eager normalization -which replaces ambiguous aliases with inference variables. As this is not +which replaces ambiguous aliases with inference variables. As this is not possible for aliases containing bound variables, the old implementation does not handle aliases inside of binders correctly, e.g. [#102048]. See the chapter on [normalization] for more details. From 2e060866f0199daf4485582c8b41b22bfd0111c1 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Fri, 24 Jan 2025 14:40:12 +0100 Subject: [PATCH 037/447] Cross-link documentation for adding a new target Both the target tier policy and the rustc-dev-guide has documentation on this, let's make sure people see both. --- src/building/new-target.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/building/new-target.md b/src/building/new-target.md index 1d9fa1b52..cd215277e 100644 --- a/src/building/new-target.md +++ b/src/building/new-target.md @@ -4,8 +4,13 @@ These are a set of steps to add support for a new target. There are numerous end states and paths to get there, so not all sections may be relevant to your desired goal. +See also the associated documentation in the +[target tier policy][target_tier_policy_add]. + +[target_tier_policy_add]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target + ## Specifying a new LLVM For very new targets, you may need to use a different fork of LLVM From adb70de1c4fa5417e961a536c9f2812122f2aff6 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Sat, 25 Jan 2025 18:21:58 +0100 Subject: [PATCH 038/447] CI: use key-restore for cache GH action It seems one can't overwrite a cache entry: ``` Failed to save: Unable to reserve cache with key linkcheck--0.8.1, another job may be creating this cache. More details: Cache already exists. Scope: refs/heads/master, Key: linkcheck--0.8.1, Version: 33f8fd511bed9c91c40778bc5c27cb58425caa894ab50f9c5705d83cb78660e0 Warning: Cache save failed. ``` A proper solution is to use `restore-keys`: https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache --- .github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 006bcce44..3f810e2fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,9 @@ jobs: uses: actions/cache/restore@v4 with: path: book/linkcheck/cache.json - key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }} + key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ github.run_id }} + restore-keys: | + linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }}-- - name: Install latest nightly Rust toolchain if: steps.mdbook-cache.outputs.cache-hit != 'true' @@ -66,7 +68,7 @@ jobs: uses: actions/cache/save@v4 with: path: book/linkcheck/cache.json - key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }} + key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ github.run_id }} - name: Deploy to gh-pages if: github.event_name == 'push' From 684424aeef127d6c107a7fb1d94596d02c95bfb8 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 25 Jan 2025 13:47:50 -0800 Subject: [PATCH 039/447] Update boring lines to sync with rustdoc --- src/early_late_parameters.md | 62 ++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/early_late_parameters.md b/src/early_late_parameters.md index 6d1365529..28026b0af 100644 --- a/src/early_late_parameters.md +++ b/src/early_late_parameters.md @@ -126,8 +126,8 @@ In this example we call `foo`'s function item type twice, each time with a borro If the lifetime parameter on `foo` was late bound this would be able to compile as each caller could provide a different lifetime argument for its borrow. See the following example which demonstrates this using the `bar` function defined above: ```rust -#fn foo<'a: 'a>(b: &'a String) -> &'a String { b } -#fn bar<'a>(b: &'a String) -> &'a String { b } +# fn foo<'a: 'a>(b: &'a String) -> &'a String { b } +# fn bar<'a>(b: &'a String) -> &'a String { b } // Early bound parameters are instantiated here, however as `'a` is // late bound it is not provided here. @@ -220,24 +220,24 @@ Then, for the first case, we can call each function with a single lifetime argum ```rust #![deny(late_bound_lifetime_arguments)] -#fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} # -#struct Foo; +# struct Foo; # -#trait Trait: Sized { -# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()); -# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()); -#} +# trait Trait: Sized { +# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()); +# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()); +# } # -#impl Trait for Foo { -# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} -# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} -#} +# impl Trait for Foo { +# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} +# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# } # -#impl Foo { -# fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} -# fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} -#} +# impl Foo { +# fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} +# fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# } # // Specifying as many arguments as there are early // bound parameters is always a future compat warning @@ -251,24 +251,24 @@ free_function::<'static>(&(), &()); For the second case we call each function with more lifetime arguments than there are lifetime parameters (be it early or late bound) and note that method calls result in a FCW as opposed to the free/associated functions which result in a hard error: ```rust -#fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} # -#struct Foo; +# struct Foo; # -#trait Trait: Sized { -# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()); -# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()); -#} +# trait Trait: Sized { +# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()); +# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()); +# } # -#impl Trait for Foo { -# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} -# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} -#} +# impl Trait for Foo { +# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} +# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# } # -#impl Foo { -# fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} -# fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} -#} +# impl Foo { +# fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} +# fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# } # // Specifying more arguments than there are early // bound parameters is a future compat warning when @@ -421,4 +421,4 @@ impl<'a> Fn<()> for FooFnItem<'a> { type Output = &'a String; /* fn call(...) -> ... { ... } */ } -``` \ No newline at end of file +``` From 3ffcf606a9985ad14b0119671a3a612836a3dda8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 26 Jan 2025 02:42:09 +0100 Subject: [PATCH 040/447] Remove accidental leading empty line in code block --- src/early_late_parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/early_late_parameters.md b/src/early_late_parameters.md index 28026b0af..3b2a5e8a1 100644 --- a/src/early_late_parameters.md +++ b/src/early_late_parameters.md @@ -128,7 +128,7 @@ If the lifetime parameter on `foo` was late bound this would be able to compile ```rust # fn foo<'a: 'a>(b: &'a String) -> &'a String { b } # fn bar<'a>(b: &'a String) -> &'a String { b } - +# // Early bound parameters are instantiated here, however as `'a` is // late bound it is not provided here. let b = bar; From a86a368f0f20b4ddb4ece70ad47387a7283ae62b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 25 Jan 2025 15:31:40 +0800 Subject: [PATCH 041/447] rustc-dev-guide: update bootstrap tracing docs --- .../bootstrapping/debugging-bootstrap.md | 90 +++++++++++------- .../tracing-output-example.png | Bin 140711 -> 0 bytes 2 files changed, 58 insertions(+), 32 deletions(-) delete mode 100644 src/building/bootstrapping/debugging-bootstrap/tracing-output-example.png diff --git a/src/building/bootstrapping/debugging-bootstrap.md b/src/building/bootstrapping/debugging-bootstrap.md index 972b4a8fb..3f907e85d 100644 --- a/src/building/bootstrapping/debugging-bootstrap.md +++ b/src/building/bootstrapping/debugging-bootstrap.md @@ -1,6 +1,6 @@ # Debugging bootstrap -> FIXME: this page could be expanded +> FIXME: this section should be expanded ## `tracing` in bootstrap @@ -10,21 +10,69 @@ Bootstrap has conditional [`tracing`][tracing] setup to provide structured loggi ### Enabling `tracing` output -Bootstrap will conditionally enable `tracing` output if the `BOOTSTRAP_TRACING` env var is set. +Bootstrap will conditionally build `tracing` support and enable `tracing` output if the `BOOTSTRAP_TRACING` env var is set. -Example usage: +#### Basic usage + +Example basic usage[^just-trace]: + +[^just-trace]: It is not recommend to use *just* `BOOTSTRAP_TRACING=TRACE` because that will dump *everything* at `TRACE` level, including logs intentionally gated behind custom targets as they are too verbose even for `TRACE` level by default. ```bash -$ BOOTSTRAP_TRACING=TRACE ./x build library --stage 1 +$ BOOTSTRAP_TRACING=bootstrap=TRACE ./x build library --stage 1 +``` + +Example output[^unstable]: + +``` +$ BOOTSTRAP_TRACING=bootstrap=TRACE ./x check src/bootstrap/ +Building bootstrap + Compiling bootstrap v0.0.0 (/home/joe/repos/rust/src/bootstrap) + Finished `dev` profile [unoptimized] target(s) in 2.74s + DEBUG bootstrap parsing flags + bootstrap::core::config::flags::Flags::parse args=["check", "src/bootstrap/"] + DEBUG bootstrap parsing config based on flags + DEBUG bootstrap creating new build based on config + bootstrap::Build::build + TRACE bootstrap setting up job management + TRACE bootstrap downloading rustfmt early + bootstrap::handling hardcoded subcommands (Format, Suggest, Perf) + DEBUG bootstrap not a hardcoded subcommand; returning to normal handling, cmd=Check { all_targets: false } + DEBUG bootstrap handling subcommand normally + bootstrap::executing real run + bootstrap::(1) executing dry-run sanity-check + bootstrap::(2) executing actual run +Checking stage0 library artifacts (x86_64-unknown-linux-gnu) + Finished `release` profile [optimized + debuginfo] target(s) in 0.04s +Checking stage0 compiler artifacts {rustc-main, rustc_abi, rustc_arena, rustc_ast, rustc_ast_ir, rustc_ast_lowering, rustc_ast_passes, rustc_ast_pretty, rustc_attr_data_structures, rustc_attr_parsing, rustc_baked_icu_data, rustc_borrowck, rustc_builtin_macros, rustc_codegen_llvm, rustc_codegen_ssa, rustc_const_eval, rustc_data_structures, rustc_driver, rustc_driver_impl, rustc_error_codes, rustc_error_messages, rustc_errors, rustc_expand, rustc_feature, rustc_fluent_macro, rustc_fs_util, rustc_graphviz, rustc_hir, rustc_hir_analysis, rustc_hir_pretty, rustc_hir_typeck, rustc_incremental, rustc_index, rustc_index_macros, rustc_infer, rustc_interface, rustc_lexer, rustc_lint, rustc_lint_defs, rustc_llvm, rustc_log, rustc_macros, rustc_metadata, rustc_middle, rustc_mir_build, rustc_mir_dataflow, rustc_mir_transform, rustc_monomorphize, rustc_next_trait_solver, rustc_parse, rustc_parse_format, rustc_passes, rustc_pattern_analysis, rustc_privacy, rustc_query_impl, rustc_query_system, rustc_resolve, rustc_sanitizers, rustc_serialize, rustc_session, rustc_smir, rustc_span, rustc_symbol_mangling, rustc_target, rustc_trait_selection, rustc_traits, rustc_transmute, rustc_ty_utils, rustc_type_ir, rustc_type_ir_macros, stable_mir} (x86_64-unknown-linux-gnu) + Finished `release` profile [optimized + debuginfo] target(s) in 0.23s +Checking stage0 bootstrap artifacts (x86_64-unknown-linux-gnu) + Checking bootstrap v0.0.0 (/home/joe/repos/rust/src/bootstrap) + Finished `release` profile [optimized + debuginfo] target(s) in 0.64s + DEBUG bootstrap checking for postponed test failures from `test --no-fail-fast` +Build completed successfully in 0:00:08 ``` -Example output[^experimental]: +#### Controlling log output + +The env var `BOOTSTRAP_TRACING` accepts a [`tracing` env-filter][tracing-env-filter]. + +There are two orthogonal ways to control which kind of logs you want: -![Example bootstrap tracing output](./debugging-bootstrap/tracing-output-example.png) +1. You can specify the log **level**, e.g. `DEBUG` or `TRACE`. +2. You can also control the log **target**, e.g. `bootstrap` or `bootstrap::core::config` vs custom targets like `CONFIG_HANDLING`. + - Custom targets are used to limit what is output when `BOOTSTRAP_TRACING=bootstrap=TRACE` is used, as they can be too verbose even for `TRACE` level by default. Currently used custom targets: + - `CONFIG_HANDLING` -[^experimental]: This shows what's *possible* with the infra in an experimental implementation. +The `TRACE` filter will enable *all* `trace` level or less verbose level tracing output. -The env var `BOOTSTRAP_TRACING` accepts a [`tracing` env-filter][tracing-env-filter]. The `TRACE` filter will enable *all* `trace` level or less verbose level tracing output. +You can of course combine them (custom target logs are typically gated behind `TRACE` log level additionally): + +```bash +$ BOOTSTRAP_TRACING=CONFIG_HANDLING=TRACE ./x build library --stage 1 +``` + +[^unstable]: This output is always subject to further changes. [tracing-env-filter]: https://docs.rs/tracing-subscriber/0.3.19/tracing_subscriber/filter/struct.EnvFilter.html @@ -73,28 +121,6 @@ For `#[instrument]`, it's recommended to: - Explicitly pick an instrumentation name via `name = ".."` to distinguish between e.g. `run` of different steps. - Take care to not cause diverging behavior via tracing, e.g. building extra things only when tracing infra is enabled. -### Enabling `tracing` bootstrap feature in rust-analyzer +### rust-analyzer integration? -You can adjust your `settings.json`'s `rust-analyzer.check.overrideCommand` and `rust-analyzer.cargo.buildScripts.overrideCommand` if you want to also enable `logging` cargo feature by default in your editor. This is mostly useful if you want proper r-a completions and such when working on bootstrap itself. - -```json -"rust-analyzer.check.overrideCommand": [ - "BOOTSTRAP_TRACING=1", // <- BOOTSTRAP_TRACING=1 won't enable tracing filter, but it will activate bootstrap's `tracing` feature - "python3", - "x.py", - "check", - "--json-output", - "--build-dir=build-rust-analyzer" -], -``` - -```json -"rust-analyzer.cargo.buildScripts.overrideCommand": [ - "BOOTSTRAP_TRACING=1", // <- note this - "python3", - "x.py", - "check", - "--json-output", - "--build-dir=build-rust-analyzer" -], -``` +Unfortunately, because bootstrap is a `rust-analyzer.linkedProjects`, you can't ask r-a to check/build bootstrap itself with `tracing` feature enabled to get relevant completions, due to lack of support as described in . diff --git a/src/building/bootstrapping/debugging-bootstrap/tracing-output-example.png b/src/building/bootstrapping/debugging-bootstrap/tracing-output-example.png deleted file mode 100644 index 745aec50d4a36563fa2701a3647506b29576518a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140711 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

(^WK44=cvB_&R#yN?@avo_z#Y8bN?d# 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𝔴D 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

z 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 From ae3a58a13a7fad816bf57b037ca698585f36cc68 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 26 Jan 2025 12:08:48 -0800 Subject: [PATCH 042/447] Correct information on dylib compression Compression of dylibs was removed in https://github.com/rust-lang/rust/pull/113695 (and decompression removed in https://github.com/rust-lang/rust/pull/132402). --- src/backend/libs-and-metadata.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/libs-and-metadata.md b/src/backend/libs-and-metadata.md index b0823b9a5..556b3fdf8 100644 --- a/src/backend/libs-and-metadata.md +++ b/src/backend/libs-and-metadata.md @@ -42,7 +42,7 @@ format is specific to `rustc`, and may change over time. This file contains: ### dylib A `dylib` is a platform-specific shared library. It includes the `rustc` -[metadata] in a special link section called `.rustc` in a compressed format. +[metadata] in a special link section called `.rustc`. ### rmeta From a0f5d80dfe8d77b4b17b344c40a4fef0965661dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 27 Jan 2025 23:34:36 +0100 Subject: [PATCH 043/447] Fix rustc-pull CI's bash commands --- .github/workflows/rustc-pull.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index 87a3ee2e7..615927d55 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -50,10 +50,10 @@ jobs: RESULT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | length' --json title` if [[ "$RESULT" -eq 0 ]]; then echo "Creating new pull request" - PR_URL=gh pr create -B master --title 'Rustc pull update' --body 'Latest update from rustc.' + PR_URL=`gh pr create -B master --title 'Rustc pull update' --body 'Latest update from rustc.'` echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT else - PR_URL=gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title + PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title` echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT fi env: From 636c5b1a4d07e2747e58df04d8218507a65dd178 Mon Sep 17 00:00:00 2001 From: Joren-vanGoethem <55790052+Joren-vanGoethem@users.noreply.github.com> Date: Tue, 28 Jan 2025 07:43:16 +0100 Subject: [PATCH 044/447] Update about-this-guide.md --- src/about-this-guide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/about-this-guide.md b/src/about-this-guide.md index 793bfa9e6..781a5c51b 100644 --- a/src/about-this-guide.md +++ b/src/about-this-guide.md @@ -72,7 +72,6 @@ You might also find the following sites useful: - The [Rust reference][rr], even though it doesn't specifically talk about Rust's internals, is a great resource nonetheless - Although out of date, [Tom Lee's great blog article][tlgba] is very helpful -- [rustaceans.org][ro] is helpful, but mostly dedicated to IRC - The [Rust Compiler Testing Docs][rctd] - For [@bors], [this cheat sheet][cheatsheet] is helpful - Google is always helpful when programming. From b06461f7df95b0dd517f32f8b244ef61f9f466df Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 28 Jan 2025 11:57:04 +0000 Subject: [PATCH 045/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 9693bfd63..183d26b29 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -ecda83b30f0f68cf5692855dddc0bc38ee8863fc +66d6064f9eb888018775e08f84747ee6f39ba28e From bc8f00367ef549fc1b80ce209afbf5308813d37d Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 28 Jan 2025 11:04:26 -0700 Subject: [PATCH 046/447] Add some extra pointers for rustdoc frontend devs --- src/rustdoc.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/rustdoc.md b/src/rustdoc.md index 3867d2489..2a0e212f9 100644 --- a/src/rustdoc.md +++ b/src/rustdoc.md @@ -58,10 +58,13 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) * If you want to copy those docs to a webserver, copy all of `build/host/doc`, since that's where the CSS, JS, fonts, and landing page are. + * For frontend debugging, disable the `rust.docs-minification` option in [`config.toml`]. * Use `./x test tests/rustdoc*` to run the tests using a stage1 rustdoc. * See [Rustdoc internals] for more information about tests. +[`config.toml`]: ./building/how-to-build-and-run.md + ## Code structure * All paths in this section are relative to `src/librustdoc` in the rust-lang/rust repository. @@ -77,6 +80,7 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) * The tests on the structure of rustdoc HTML output are located in `tests/rustdoc`, where they're handled by the test runner of bootstrap and the supplementary script `src/etc/htmldocck.py`. +* Frontend CSS and JavaScript are stored in `html/static/`. ## Tests @@ -91,6 +95,11 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) browser-UI-test](https://github.com/GuillaumeGomez/browser-UI-test/) that uses puppeteer to run tests in a headless browser and check rendering and interactivity. +* Additionally, JavaScript type annotations are written using [TypeScript-flavored JSDoc] + comments and an external d.ts file. The code itself is plain, valid JavaScript; we only + use tsc as a linter. + +[TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html ## Constraints From cd9a8cc9c3179bce896fc482ca66d542e89a52d9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 25 Jan 2025 04:26:32 +0000 Subject: [PATCH 047/447] Move outlives env computation into methods --- src/traits/implied-bounds.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/traits/implied-bounds.md b/src/traits/implied-bounds.md index 63b09a43f..05693dcd5 100644 --- a/src/traits/implied-bounds.md +++ b/src/traits/implied-bounds.md @@ -40,7 +40,7 @@ requirements of impls and functions as explicit predicates. ### using implicit implied bounds as assumptions These bounds are not added to the `ParamEnv` of the affected item itself. For lexical -region resolution they are added using [`fn OutlivesEnvironment::with_bounds`]. +region resolution they are added using [`fn OutlivesEnvironment::new`]. Similarly, during MIR borrowck we add them using [`fn UniversalRegionRelationsBuilder::add_implied_bounds`]. @@ -55,7 +55,7 @@ The assumed outlives constraints for implicit bounds are computed using the MIR borrowck adds the outlives constraints for both the normalized and unnormalized types, lexical region resolution [only uses the unnormalized types][notnorm]. -[`fn OutlivesEnvironment::with_bounds`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_infer/src/infer/outlives/env.rs#L90-L97 +[`fn OutlivesEnvironment::new`]: TODO [`fn UniversalRegionRelationsBuilder::add_implied_bounds`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L316 [mir]: https://github.com/rust-lang/rust/blob/91cae1dcdcf1a31bd8a92e4a63793d65cfe289bb/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L258-L332 [`fn assumed_wf_types`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_ty_utils/src/implied_bounds.rs#L21 From 936683c1c9dd51da17126b75412f008db328bd29 Mon Sep 17 00:00:00 2001 From: Mohammad Omidvar Date: Tue, 28 Jan 2025 19:45:20 +0000 Subject: [PATCH 048/447] Make crate AST mutation accessible for driver callback --- examples/rustc-driver-example.rs | 2 +- examples/rustc-driver-interacting-with-the-ast.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/rustc-driver-example.rs b/examples/rustc-driver-example.rs index 8983915d7..b0f9af1b8 100644 --- a/examples/rustc-driver-example.rs +++ b/examples/rustc-driver-example.rs @@ -58,7 +58,7 @@ impl rustc_driver::Callbacks for MyCallbacks { fn after_crate_root_parsing( &mut self, _compiler: &Compiler, - krate: &rustc_ast::Crate, + krate: &mut rustc_ast::Crate, ) -> Compilation { for item in &krate.items { println!("{}", item_to_string(&item)); diff --git a/examples/rustc-driver-interacting-with-the-ast.rs b/examples/rustc-driver-interacting-with-the-ast.rs index c894b6044..8766a8173 100644 --- a/examples/rustc-driver-interacting-with-the-ast.rs +++ b/examples/rustc-driver-interacting-with-the-ast.rs @@ -58,7 +58,7 @@ impl rustc_driver::Callbacks for MyCallbacks { fn after_crate_root_parsing( &mut self, _compiler: &Compiler, - krate: &rustc_ast::Crate, + krate: &mut rustc_ast::Crate, ) -> Compilation { for item in &krate.items { println!("{}", item_to_string(&item)); From 930c6a61e34633d6c53919fe0ccbf1fea979553f Mon Sep 17 00:00:00 2001 From: yegeunyang Date: Tue, 28 Jan 2025 20:42:26 -0600 Subject: [PATCH 049/447] Add "Writing tests" section --- src/getting-started.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/getting-started.md b/src/getting-started.md index 03d2811e8..d7797d2e4 100644 --- a/src/getting-started.md +++ b/src/getting-started.md @@ -137,6 +137,10 @@ pull request, continuing the work on the feature. [abandoned-prs]: https://github.com/rust-lang/rust/pulls?q=is%3Apr+label%3AS-inactive+is%3Aclosed +### Writing tests + +Issues that have been resolved but do not have a regression test are marked with the `E-needs-test` label. Writing unit tests is a low-risk, lower-priority task that offers new contributors a great opportunity to familiarize themselves with the codebase. + ### Contributing to std (standard library) See [std-dev-guide](https://std-dev-guide.rust-lang.org/). From 7e74e43eaa0297a076237cb986ba2a6b1ecde011 Mon Sep 17 00:00:00 2001 From: yegeunyang Date: Tue, 28 Jan 2025 21:05:12 -0600 Subject: [PATCH 050/447] Add link to declare_lint! macro --- src/diagnostics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics.md b/src/diagnostics.md index 709e9d4f8..8f389640d 100644 --- a/src/diagnostics.md +++ b/src/diagnostics.md @@ -602,7 +602,7 @@ as the linter walks the AST. You can then choose to emit lints in a very similar way to compile errors. You also declare the metadata of a particular lint via the `declare_lint!` -macro. This includes the name, the default level, a short description, and some +macro. [This macro](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html) includes the name, the default level, a short description, and some more details. Note that the lint and the lint pass must be registered with the compiler. From 2332c8e11493390c01016a8f19c772ed8ec3ca66 Mon Sep 17 00:00:00 2001 From: yegeunyang Date: Tue, 28 Jan 2025 22:56:52 -0600 Subject: [PATCH 051/447] Touch up a sentence --- src/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/getting-started.md b/src/getting-started.md index d7797d2e4..4cb1d0b31 100644 --- a/src/getting-started.md +++ b/src/getting-started.md @@ -139,7 +139,7 @@ pull request, continuing the work on the feature. ### Writing tests -Issues that have been resolved but do not have a regression test are marked with the `E-needs-test` label. Writing unit tests is a low-risk, lower-priority task that offers new contributors a great opportunity to familiarize themselves with the codebase. +Issues that have been resolved but do not have a regression test are marked with the `E-needs-test` label. Writing unit tests is a low-risk, lower-priority task that offers new contributors a great opportunity to familiarize themselves with the testing infrastructure and contribution workflow. ### Contributing to std (standard library) From a14bbfbea9fdf4ab11685bf32e527c0b14beb456 Mon Sep 17 00:00:00 2001 From: chiichen Date: Thu, 30 Jan 2025 17:38:46 +0800 Subject: [PATCH 052/447] chore: discard padding white space --- src/building/suggested.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/building/suggested.md b/src/building/suggested.md index bf5ffbc00..f498875ce 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -135,24 +135,24 @@ and follow the same instructions as above. ### Emacs Emacs provides support for rust-analyzer with project-local configuration -through [Eglot](https://www.gnu.org/software/emacs/manual/html_node/eglot/). +through [Eglot](https://www.gnu.org/software/emacs/manual/html_node/eglot/). Steps for setting up Eglot with rust-analyzer can be [found -here](https://rust-analyzer.github.io/manual.html#eglot). +here](https://rust-analyzer.github.io/manual.html#eglot). Having set up Emacs & Eglot for Rust development in general, you can run `./x setup editor` and select `emacs`, which will prompt you to create `.dir-locals.el` with the recommended configuration for Eglot. -The recommended settings live at [`src/etc/rust_analyzer_eglot.el`]. +The recommended settings live at [`src/etc/rust_analyzer_eglot.el`]. For more information on project-specific Eglot configuration, consult [the manual](https://www.gnu.org/software/emacs/manual/html_node/eglot/Project_002dspecific-configuration.html). ### Helix -Helix comes with built-in LSP and rust-analyzer support. +Helix comes with built-in LSP and rust-analyzer support. It can be configured through `languages.toml`, as described -[here](https://docs.helix-editor.com/languages.html). +[here](https://docs.helix-editor.com/languages.html). You can run `./x setup editor` and select `helix`, which will prompt you to create `languages.toml` with the recommended configuration for Helix. The -recommended settings live at [`src/etc/rust_analyzer_helix.toml`]. +recommended settings live at [`src/etc/rust_analyzer_helix.toml`]. ## Check, check, and check again @@ -181,7 +181,7 @@ example, running `tidy` and `linkchecker` is useful when editing Markdown files, whereas UI tests are much less likely to be helpful. While `x suggest` is a useful tool, it does not guarantee perfect coverage (just as PR CI isn't a substitute for bors). See the [dedicated chapter](../tests/suggest-tests.md) for -more information and contribution instructions. +more information and contribution instructions. Please note that `x suggest` is in a beta state currently and the tests that it will suggest are limited. From 72ceb939b3bce2df35cce96857493a2bfdae49a4 Mon Sep 17 00:00:00 2001 From: chiichen Date: Thu, 30 Jan 2025 17:56:31 +0800 Subject: [PATCH 053/447] feat: modify developing with nix section --- src/building/suggested.md | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/building/suggested.md b/src/building/suggested.md index f498875ce..2c6c3fe1d 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -332,29 +332,22 @@ git worktree add -b my-feature ../rust2 master You can then use that rust2 folder as a separate workspace for modifying and building `rustc`! -## Using nix-shell +## Working with nix -If you're using nix, you can use the following nix-shell to work on Rust: +Several nix configurations are defined in `src/tools/nix-dev-shell`. -```nix -{ pkgs ? import {} }: -pkgs.mkShell { - name = "rustc"; - nativeBuildInputs = with pkgs; [ - binutils cmake ninja pkg-config python3 git curl cacert patchelf nix - ]; - buildInputs = with pkgs; [ - openssl glibc.out glibc.static - ]; - # Avoid creating text files for ICEs. - RUSTC_ICE = "0"; - # Provide `libstdc++.so.6` for the self-contained lld. - LD_LIBRARY_PATH = "${with pkgs; lib.makeLibraryPath [ - stdenv.cc.cc.lib - ]}"; -} +If you're using direnv, you can create a symbol link to `src/tools/nix-dev-shell/envrc-flake` or `src/tools/nix-dev-shell/envrc-shell` + +```bash +ln -s ./src/tools/nix-dev-shell/envrc-flake ./.envrc # Use flake +``` +or +```bash +ln -s ./src/tools/nix-dev-shell/envrc-shell ./.envrc # Use nix-shell ``` +### Note + Note that when using nix on a not-NixOS distribution, it may be necessary to set **`patch-binaries-for-nix = true` in `config.toml`**. Bootstrap tries to detect whether it's running in nix and enable patching automatically, but this From 0cd4069ee42e80dec6ce74ba1a0b22b3d63b638a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 10 Jan 2025 20:09:10 +0000 Subject: [PATCH 054/447] Rework rustc_dump_vtable --- src/compiler-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler-debugging.md b/src/compiler-debugging.md index a2a6c8085..e2097b26e 100644 --- a/src/compiler-debugging.md +++ b/src/compiler-debugging.md @@ -275,7 +275,7 @@ Here are some notable ones: | `rustc_dump_def_parents` | Dumps the chain of `DefId` parents of certain definitions. | | `rustc_dump_item_bounds` | Dumps the [`item_bounds`] of an item. | | `rustc_dump_predicates` | Dumps the [`predicates_of`] an item. | -| `rustc_dump_vtable` | | +| `rustc_dump_vtable` | Dumps the vtable layout of an impl, or a type alias of a dyn type. | | `rustc_hidden_type_of_opaques` | Dumps the [hidden type of each opaque types][opaq] in the crate. | | `rustc_layout` | [See this section](#debugging-type-layouts). | | `rustc_object_lifetime_default` | Dumps the [object lifetime defaults] of an item. | From 88197e4182d16a711a2b78051a20ab9e6951451d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 30 Jan 2025 16:24:39 +0100 Subject: [PATCH 055/447] Distinguish between "nothing to pull" and "pull error" in josh-sync --- josh-sync/src/main.rs | 15 +++++++++++++-- josh-sync/src/sync.rs | 24 +++++++++++++++++++----- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/josh-sync/src/main.rs b/josh-sync/src/main.rs index 84613ad86..175f016f7 100644 --- a/josh-sync/src/main.rs +++ b/josh-sync/src/main.rs @@ -1,5 +1,5 @@ use clap::Parser; -use crate::sync::GitSync; +use crate::sync::{GitSync, RustcPullError}; mod sync; @@ -22,7 +22,18 @@ fn main() -> anyhow::Result<()> { let sync = GitSync::from_current_dir()?; match args { Args::RustcPull => { - sync.rustc_pull(None)?; + if let Err(error) = sync.rustc_pull(None) { + match error { + RustcPullError::NothingToPull => { + eprintln!("Nothing to pull"); + std::process::exit(2); + } + RustcPullError::PullFailed(error) => { + eprintln!("Pull failure: {error:?}"); + std::process::exit(1); + } + } + } } Args::RustcPush { github_username, branch } => { sync.rustc_push(github_username, branch)?; diff --git a/josh-sync/src/sync.rs b/josh-sync/src/sync.rs index eff80b109..cd64be636 100644 --- a/josh-sync/src/sync.rs +++ b/josh-sync/src/sync.rs @@ -11,6 +11,19 @@ const JOSH_FILTER: &str = ":/src/doc/rustc-dev-guide"; const JOSH_PORT: u16 = 42042; const UPSTREAM_REPO: &str = "rust-lang/rust"; +pub enum RustcPullError { + /// No changes are available to be pulled. + NothingToPull, + /// A rustc-pull has failed, probably a git operation error has occurred. + PullFailed(anyhow::Error) +} + +impl From for RustcPullError where E: Into { + fn from(error: E) -> Self { + Self::PullFailed(error.into()) + } +} + pub struct GitSync { dir: PathBuf, } @@ -24,7 +37,7 @@ impl GitSync { }) } - pub fn rustc_pull(&self, commit: Option) -> anyhow::Result<()> { + pub fn rustc_pull(&self, commit: Option) -> Result<(), RustcPullError> { let sh = Shell::new()?; sh.change_dir(&self.dir); let commit = commit.map(Ok).unwrap_or_else(|| { @@ -38,7 +51,7 @@ impl GitSync { })?; // Make sure the repo is clean. if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() { - bail!("working directory must be clean before performing rustc pull"); + return Err(anyhow::anyhow!("working directory must be clean before performing rustc pull").into()); } // Make sure josh is running. let josh = Self::start_josh()?; @@ -47,7 +60,7 @@ impl GitSync { let previous_base_commit = sh.read_file("rust-version")?.trim().to_string(); if previous_base_commit == commit { - return Err(anyhow::anyhow!("No changes since last pull")); + return Err(RustcPullError::NothingToPull); } // Update rust-version file. As a separate commit, since making it part of @@ -94,12 +107,13 @@ impl GitSync { cmd!(sh, "git reset --hard HEAD^") .run() .expect("FAILED to clean up after creating the preparation commit"); - return Err(anyhow::anyhow!("No merge was performed, nothing to pull. Rolled back the preparation commit.")); + eprintln!("No merge was performed, no changes to pull were found. Rolled back the preparation commit."); + return Err(RustcPullError::NothingToPull); } // Check that the number of roots did not increase. if num_roots()? != num_roots_before { - bail!("Josh created a new root commit. This is probably not the history you want."); + return Err(anyhow::anyhow!("Josh created a new root commit. This is probably not the history you want.").into()); } drop(josh); From a0505b3e7d207d172e9aed37bbc4003428a574b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 30 Jan 2025 18:33:34 +0100 Subject: [PATCH 056/447] Rewrite section on executing Docker tests --- src/tests/docker.md | 65 ++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/src/tests/docker.md b/src/tests/docker.md index a0aa8bd3e..8327e5ce6 100644 --- a/src/tests/docker.md +++ b/src/tests/docker.md @@ -1,36 +1,44 @@ # Testing with Docker -The Rust tree includes [Docker] image definitions for the platforms used on -GitHub Actions in [`src/ci/docker`]. -The script [`src/ci/docker/run.sh`] is used to build the Docker image, run it, -build Rust within the image, and run the tests. - -You can run these images on your local development machine. This can be -helpful to test environments different from your local system. First you will +The [`src/ci/docker`] directory includes [Docker] image definitions for Linux-based jobs executed on GitHub Actions (non-Linux jobs run outside Docker). You can run these jobs on your local development machine, which can be +helpful to test environments different from your local system. You will 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). To enter interactive mode which will -start a bash shell in the container, run `src/ci/docker/run.sh --dev ` -where `` is one of the directory names in `src/ci/docker` (for example -`x86_64-gnu` is a fairly standard Ubuntu environment). - -The docker script will mount your local Rust source tree in read-only mode, -and an `obj` directory in read-write mode. All of the compiler artifacts will -be stored in the `obj` directory. The shell will start out in the `obj` -directory. From there, you can run `../src/ci/run.sh` which will run the build -as defined by the image. - -Alternatively, you can run individual commands to do specific tasks. For -example, you can run `../x test tests/ui` to just run UI tests. -Note that there is some configuration in the [`src/ci/run.sh`] script that you -may need to recreate. Particularly, set `submodules = false` in your -`config.toml` so that it doesn't attempt to modify the read-only directory. +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: + +```bash +python3 src/ci/github-actions/ci.py run-local +# For example: +python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux-alt +``` -Some additional notes about using the Docker images: +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. +## The `run.sh` script +The [`src/ci/docker/run.sh`] script is used to build a specific Docker image, run it, +build Rust within the image, and either run tests or prepare a set of archives designed for distribution. The script will mount your local Rust source tree in read-only mode, and an `obj` directory in read-write mode. All the compiler artifacts will be stored in the `obj` directory. The shell will start out in the `obj`directory. From there, it will execute `../src/ci/run.sh` which starts the build as defined by the Docker image. + +You can run `src/ci/docker/run.sh ` directly. A few important notes regarding the `run.sh` script: +- There is some configuration used on CI that you may need to recreate. In particular, set `submodules = false` in your `config.toml` so that it doesn't attempt to modify the read-only directory. +- `` corresponds to a single directory located in one of the `src/ci/docker/host-*` directories. Note that image name does not necessarily correspond to a job name, as some jobs execute the same image, but with different environment variables or Docker build arguments (this is a part of the complexity that makes it difficult to run CI jobs locally). +- If you are executing a "dist" job (job beginning with `dist-`), you should set the `DEPLOY=1` environment variable. +- If you are executing an "alternative dist" job (job beginning with `dist-` and ending with `-alt`), you should set the `DEPLOY_ALT=1` environment variable. - Some of the std tests require IPv6 support. Docker on Linux seems to have it disabled by default. Run the commands in [`enable-docker-ipv6.sh`] to enable IPv6 before creating the container. This only needs to be done once. + +### Interactive mode + +Sometimes, it can be useful to build a specific Docker image, and then run custom commands inside it, so that you can experiment with how the given system behaves. You can do that using an interactive mode, which will +start a bash shell in the container, using `src/ci/docker/run.sh --dev `. + +When inside the Docker container, you can run individual commands to do specific tasks. For +example, you can run `../x test tests/ui` to just run UI tests. + +Some additional notes about using the interactive mode: + - The container will be deleted automatically when you exit the shell, however the build artifacts persist in the `obj` directory. If you are switching between different Docker images, the artifacts from previous environments @@ -45,15 +53,6 @@ Some additional notes about using the Docker images: containers. With the container name, run `docker exec -it /bin/bash` where `` 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 -python3 src/ci/github-actions/ci.py run-local -# For example: -python3 src/ci/github-actions/ci.py 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 From c45e1e9a0e7874db1b530641462621d28184d3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 30 Jan 2025 17:29:01 +0100 Subject: [PATCH 057/447] Run rustc-pull CI every day, don't notify when there is nothing to update --- .github/workflows/rustc-pull.yml | 40 ++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index 615927d55..5d5b145c9 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -3,8 +3,8 @@ name: rustc-pull on: workflow_dispatch: schedule: - # Run at 04:00 UTC every Monday - - cron: '0 4 * * 1' + # Run at 04:00 UTC every day + - cron: '0 4 * * *' jobs: pull: @@ -34,8 +34,25 @@ jobs: git config --global user.name 'The rustc-dev-guide Cronjob Bot' git config --global user.email 'github-actions@github.com' - name: Perform rustc-pull - run: cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull + id: rustc-pull + # Turn off -e to disable early exit + shell: bash {0} + run: | + cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull + exitcode=$? + + # If no pull was performed, we want to mark this job as successful, + # but we do not want to perform the follow-up steps. + if [ $exitcode -eq 0 ]; then + echo "pull_result=pull-finished" >> $GITHUB_OUTPUT + elif [ $exitcode -eq 2 ]; then + echo "pull_result=skipped" >> $GITHUB_OUTPUT + exitcode=0 + fi + + exit ${exitcode} - name: Push changes to a branch + if: ${{ steps.rustc-pull.outputs.pull_result == 'pull-finished' }} run: | # Update a sticky branch that is used only for rustc pulls BRANCH="rustc-pull" @@ -43,6 +60,7 @@ jobs: git push -u origin $BRANCH --force - name: Create pull request id: update-pr + if: ${{ steps.rustc-pull.outputs.pull_result == 'pull-finished' }} run: | # Check if an open pull request for an rustc pull update already exists # If it does, the previous push has just updated it @@ -54,6 +72,7 @@ jobs: echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT else PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title` + echo "Updating pull request ${PR_URL}" echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT fi env: @@ -64,16 +83,23 @@ jobs: runs-on: ubuntu-latest steps: - name: Compute message - id: message + id: create-message run: | - if [ "${{ needs.pull.result }}" == "failure" ]; - then + if [ "${{ needs.pull.result }}" == "failure" ]; then WORKFLOW_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" echo "message=Rustc pull sync failed. Check out the [workflow URL]($WORKFLOW_URL)." >> $GITHUB_OUTPUT else - echo "message=Rustc pull sync succeeded. Check out the [PR](${{ needs.pull.outputs.pr_url }})." >> $GITHUB_OUTPUT + CREATED_AT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].createdAt' --json createdAt,title` + PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title` + week_ago=$(date +%F -d '7 days ago') + + # If there is an open PR that is at least a week old, post a message about it + if [[ -n $DATE_GH && $DATE_GH < $week_ago ]]; then + echo "message=A PR with a Rustc pull has been opened for more a week. Check out the [PR](${PR_URL})." >> $GITHUB_OUTPUT + fi fi - name: Send a Zulip message about updated PR + if: ${{ steps.create-message.outputs.message != '' }} uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 with: api-key: ${{ secrets.ZULIP_API_TOKEN }} From 55cd18d5cc255d8932e17be9369b61c93091a5d7 Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Fri, 31 Jan 2025 10:23:46 +1100 Subject: [PATCH 058/447] Fix a typo in conventions.md Introduced in #135950 --- src/conventions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conventions.md b/src/conventions.md index 4010e9082..0e624a456 100644 --- a/src/conventions.md +++ b/src/conventions.md @@ -43,7 +43,7 @@ environment. ## Formatting and linting Python code -The Rust repository contains quite a lof of Python code. We try to keep +The Rust repository contains quite a lot of Python code. We try to keep it both linted and formatted by the [ruff][ruff] tool. When modifying Python code, use this command to format it: From 4755a326eb6babd7ce3812ce764764b0a73ccc55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 31 Jan 2025 17:01:38 +0100 Subject: [PATCH 059/447] Pass `GITHUB_TOKEN` to Zulip CI step --- .github/workflows/rustc-pull.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index 5d5b145c9..2a9f56fd6 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -61,6 +61,8 @@ jobs: - name: Create pull request id: update-pr if: ${{ steps.rustc-pull.outputs.pull_result == 'pull-finished' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # Check if an open pull request for an rustc pull update already exists # If it does, the previous push has just updated it @@ -75,8 +77,6 @@ jobs: echo "Updating pull request ${PR_URL}" echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT fi - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} send-zulip-message: needs: [pull] if: ${{ !cancelled() }} @@ -84,6 +84,8 @@ jobs: steps: - name: Compute message id: create-message + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | if [ "${{ needs.pull.result }}" == "failure" ]; then WORKFLOW_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" From f5d66eb2df88b0b0981c7a639036f5f373ebcc44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 1 Feb 2025 15:50:00 +0100 Subject: [PATCH 060/447] Checkout repository sources in rustc-pull CI action This is needed for the `gh` command to work. --- .github/workflows/rustc-pull.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index 2a9f56fd6..5bfcf47d7 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -82,6 +82,7 @@ jobs: if: ${{ !cancelled() }} runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 - name: Compute message id: create-message env: From c1b96f0f88637a587677b12f9dc5846cdb78abf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 1 Feb 2025 16:42:28 +0100 Subject: [PATCH 061/447] Reword submodule handling --- src/tests/docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/docker.md b/src/tests/docker.md index 8327e5ce6..2ca08d421 100644 --- a/src/tests/docker.md +++ b/src/tests/docker.md @@ -21,7 +21,7 @@ The [`src/ci/docker/run.sh`] script is used to build a specific Docker image, ru build Rust within the image, and either run tests or prepare a set of archives designed for distribution. The script will mount your local Rust source tree in read-only mode, and an `obj` directory in read-write mode. All the compiler artifacts will be stored in the `obj` directory. The shell will start out in the `obj`directory. From there, it will execute `../src/ci/run.sh` which starts the build as defined by the Docker image. You can run `src/ci/docker/run.sh ` directly. A few important notes regarding the `run.sh` script: -- There is some configuration used on CI that you may need to recreate. In particular, set `submodules = false` in your `config.toml` so that it doesn't attempt to modify the read-only directory. +- When executed on CI, the script expects that all submodules are checked out. If some submodule that is accessed by the job is not available, the build will result in an error. You should thus make sure that you have all required submodules checked out locally. You can either do that manually through git, or set `submodules = true` in your `config.toml` and run a command such as `x build` to let bootstrap download the most important submodules (this might not be enough for the given CI job that you are trying to execute though). - `` corresponds to a single directory located in one of the `src/ci/docker/host-*` directories. Note that image name does not necessarily correspond to a job name, as some jobs execute the same image, but with different environment variables or Docker build arguments (this is a part of the complexity that makes it difficult to run CI jobs locally). - If you are executing a "dist" job (job beginning with `dist-`), you should set the `DEPLOY=1` environment variable. - If you are executing an "alternative dist" job (job beginning with `dist-` and ending with `-alt`), you should set the `DEPLOY_ALT=1` environment variable. From bc61b269a58c13181f99c8f4c6650bbcbe8e4f3a Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Sun, 2 Feb 2025 04:02:19 +0000 Subject: [PATCH 062/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 183d26b29..fa65931bd 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -66d6064f9eb888018775e08f84747ee6f39ba28e +8239a37f9c0951a037cfc51763ea52a20e71e6bd From 198de243e129a43eae66fbbfc52e4b71bea34ef9 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 2 Feb 2025 17:30:30 +0900 Subject: [PATCH 063/447] Apply suggestions from code review --- src/traits/implied-bounds.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/traits/implied-bounds.md b/src/traits/implied-bounds.md index 05693dcd5..cdcb90d3e 100644 --- a/src/traits/implied-bounds.md +++ b/src/traits/implied-bounds.md @@ -40,7 +40,7 @@ requirements of impls and functions as explicit predicates. ### using implicit implied bounds as assumptions These bounds are not added to the `ParamEnv` of the affected item itself. For lexical -region resolution they are added using [`fn OutlivesEnvironment::new`]. +region resolution they are added using [`fn OutlivesEnvironment::from_normalized_bounds`]. Similarly, during MIR borrowck we add them using [`fn UniversalRegionRelationsBuilder::add_implied_bounds`]. @@ -55,7 +55,7 @@ The assumed outlives constraints for implicit bounds are computed using the MIR borrowck adds the outlives constraints for both the normalized and unnormalized types, lexical region resolution [only uses the unnormalized types][notnorm]. -[`fn OutlivesEnvironment::new`]: TODO +[`fn OutlivesEnvironment::from_normalized_bounds`]: https://github.com/rust-lang/rust/blob/8239a37f9c0951a037cfc51763ea52a20e71e6bd/compiler/rustc_infer/src/infer/outlives/env.rs#L50-L55 [`fn UniversalRegionRelationsBuilder::add_implied_bounds`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L316 [mir]: https://github.com/rust-lang/rust/blob/91cae1dcdcf1a31bd8a92e4a63793d65cfe289bb/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L258-L332 [`fn assumed_wf_types`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_ty_utils/src/implied_bounds.rs#L21 From 65daf3b01a0450e6772abfed88b207654681038d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 2 Feb 2025 16:06:16 +0000 Subject: [PATCH 064/447] Replace ParseSess::set_dcx with DiagCtxt::set_emitter Replacing the error emitter doesn't accidentally clear the error count. --- examples/rustc-interface-getting-diagnostics.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/rustc-interface-getting-diagnostics.rs b/examples/rustc-interface-getting-diagnostics.rs index be37dd867..2355cb85a 100644 --- a/examples/rustc-interface-getting-diagnostics.rs +++ b/examples/rustc-interface-getting-diagnostics.rs @@ -10,6 +10,8 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; +use std::sync::{Arc, Mutex}; + use rustc_errors::emitter::Emitter; use rustc_errors::registry::{self, Registry}; use rustc_errors::translation::Translate; @@ -17,8 +19,6 @@ use rustc_errors::{DiagCtxt, DiagInner, FluentBundle}; use rustc_session::config; use rustc_span::source_map::SourceMap; -use std::sync::{Arc, Mutex}; - struct DebugEmitter { source_map: Arc, diagnostics: Arc>>, @@ -67,10 +67,10 @@ fn main() { locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES.to_owned(), lint_caps: rustc_hash::FxHashMap::default(), psess_created: Some(Box::new(|parse_sess| { - parse_sess.set_dcx(DiagCtxt::new(Box::new(DebugEmitter { + parse_sess.dcx().set_emitter(Box::new(DebugEmitter { source_map: parse_sess.clone_source_map(), diagnostics, - }))); + })); })), register_lints: None, override_queries: None, From 40ec7e6349454106869b060c171f69fe6bbae139 Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Mon, 3 Feb 2025 04:02:09 +0000 Subject: [PATCH 065/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index fa65931bd..b62959720 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -8239a37f9c0951a037cfc51763ea52a20e71e6bd +613bdd49978298648ed05ace086bd1ecad54b44a From 9f683c9070e802ce8c5b5636eb14cd5183a7ac36 Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Mon, 3 Feb 2025 06:44:41 +0300 Subject: [PATCH 066/447] tree-wide: parallel: Fully removed all `Lrc`, replaced with `Arc` --- examples/rustc-driver-example.rs | 4 ++-- examples/rustc-driver-interacting-with-the-ast.rs | 4 ++-- src/diagnostics/lintstore.md | 2 +- src/parallel-rustc.md | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/rustc-driver-example.rs b/examples/rustc-driver-example.rs index b0f9af1b8..14998965a 100644 --- a/examples/rustc-driver-example.rs +++ b/examples/rustc-driver-example.rs @@ -15,9 +15,9 @@ extern crate rustc_span; use std::io; use std::path::Path; +use std::sync::Arc; use rustc_ast_pretty::pprust::item_to_string; -use rustc_data_structures::sync::Lrc; use rustc_driver::{Compilation, run_compiler}; use rustc_interface::interface::{Compiler, Config}; use rustc_middle::ty::TyCtxt; @@ -43,7 +43,7 @@ fn main() { } } - fn read_binary_file(&self, _path: &Path) -> io::Result> { + fn read_binary_file(&self, _path: &Path) -> io::Result> { Err(io::Error::other("oops")) } } diff --git a/examples/rustc-driver-interacting-with-the-ast.rs b/examples/rustc-driver-interacting-with-the-ast.rs index 8766a8173..9fcb16b0f 100644 --- a/examples/rustc-driver-interacting-with-the-ast.rs +++ b/examples/rustc-driver-interacting-with-the-ast.rs @@ -15,9 +15,9 @@ extern crate rustc_span; use std::io; use std::path::Path; +use std::sync::Arc; use rustc_ast_pretty::pprust::item_to_string; -use rustc_data_structures::sync::Lrc; use rustc_driver::{Compilation, run_compiler}; use rustc_interface::interface::{Compiler, Config}; use rustc_middle::ty::TyCtxt; @@ -43,7 +43,7 @@ fn main() { } } - fn read_binary_file(&self, _path: &Path) -> io::Result> { + fn read_binary_file(&self, _path: &Path) -> io::Result> { Err(io::Error::other("oops")) } } diff --git a/src/diagnostics/lintstore.md b/src/diagnostics/lintstore.md index bd2b02529..7b98bc621 100644 --- a/src/diagnostics/lintstore.md +++ b/src/diagnostics/lintstore.md @@ -54,7 +54,7 @@ Lints are registered via the [`LintStore::register_lint`] function. This should happen just once for any lint, or an ICE will occur. Once the registration is complete, we "freeze" the lint store by placing it in -an `Lrc`. +an `Arc`. Lint passes are registered separately into one of the categories (pre-expansion, early, late, late module). Passes are registered as a closure diff --git a/src/parallel-rustc.md b/src/parallel-rustc.md index 2dae95a34..44c78a125 100644 --- a/src/parallel-rustc.md +++ b/src/parallel-rustc.md @@ -46,7 +46,6 @@ are implemented differently depending on whether `parallel-compiler` is true. | data structure | parallel | non-parallel | | -------------------------------- | --------------------------------------------------- | ------------ | -| Lrc | std::sync::Arc | std::rc::Rc | | Weak | std::sync::Weak | std::rc::Weak | | Atomic{Bool}/{Usize}/{U32}/{U64} | std::sync::atomic::Atomic{Bool}/{Usize}/{U32}/{U64} | (std::cell::Cell) | | OnceCell | std::sync::OnceLock | std::cell::OnceCell | From 2790e9aed6cd5d9fecae321ece53317ebeef4197 Mon Sep 17 00:00:00 2001 From: Rehmatpal Singh <91879372+DuskyElf@users.noreply.github.com> Date: Tue, 4 Feb 2025 01:26:15 +0530 Subject: [PATCH 067/447] Remove "Port run-make tests from Make to Rust" tracking issue from Recurring work --- src/getting-started.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/getting-started.md b/src/getting-started.md index 4cb1d0b31..8bf14bef2 100644 --- a/src/getting-started.md +++ b/src/getting-started.md @@ -101,7 +101,6 @@ it's easy to pick up work without a large time commitment: - [Rustdoc Askama Migration](https://github.com/rust-lang/rust/issues/108868) - [Diagnostic Translation](https://github.com/rust-lang/rust/issues/100717) - [Move UI tests to subdirectories](https://github.com/rust-lang/rust/issues/73494) -- [Port run-make tests from Make to Rust](https://github.com/rust-lang/rust/issues/121876) If you find more recurring work, please feel free to add it here! From b3c5e9c7343706912a1e3808bb8cfe9ce191d2fc Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 3 Feb 2025 22:07:10 +0200 Subject: [PATCH 068/447] overlong line --- src/diagnostics.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/diagnostics.md b/src/diagnostics.md index 8f389640d..972309b5c 100644 --- a/src/diagnostics.md +++ b/src/diagnostics.md @@ -601,8 +601,8 @@ The trait implementation allows you to check certain syntactic constructs as the linter walks the AST. You can then choose to emit lints in a very similar way to compile errors. -You also declare the metadata of a particular lint via the `declare_lint!` -macro. [This macro](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html) includes the name, the default level, a short description, and some +You also declare the metadata of a particular lint via the [`declare_lint!`] +macro. This macro includes the name, the default level, a short description, and some more details. Note that the lint and the lint pass must be registered with the compiler. @@ -671,6 +671,8 @@ example-use-loop = denote infinite loops with `loop {"{"} ... {"}"}` .suggestion = use `loop` ``` +[`declare_lint!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html + ### Edition-gated lints Sometimes we want to change the behavior of a lint in a new edition. To do this, From 6a5c177e4646948220fe3b846789d4430ee8c40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 3 Feb 2025 22:06:13 +0100 Subject: [PATCH 069/447] Make the rustc-pull workflow run less often --- .github/workflows/rustc-pull.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index 5bfcf47d7..dc5395a19 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -3,8 +3,8 @@ name: rustc-pull on: workflow_dispatch: schedule: - # Run at 04:00 UTC every day - - cron: '0 4 * * *' + # Run at 04:00 UTC every Monday and Thursday + - cron: '0 4 * * 1,4' jobs: pull: From 0238431e2011208621531a003abad5a614819869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 4 Feb 2025 11:10:14 +0100 Subject: [PATCH 070/447] Update rustc-dev-guide --- src/profiling/with_rustc_perf.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/profiling/with_rustc_perf.md b/src/profiling/with_rustc_perf.md index 87d205d9e..eda8c3a17 100644 --- a/src/profiling/with_rustc_perf.md +++ b/src/profiling/with_rustc_perf.md @@ -7,9 +7,7 @@ However, using the suite manually can be a bit cumbersome. To make this easier f the compiler build system (`bootstrap`) also provides built-in integration with the benchmarking suite, which will download and build the suite for you, build a local compiler toolchain and let you profile it using a simplified command-line interface. -You can use the `./x perf -- [options]` command to use this integration. - -> Note that you need to specify arguments after `--` in the `x perf` command! You will not be able to pass arguments without the double dashes. +You can use the `./x perf [options]` command to use this integration. You can use normal bootstrap flags for this command, such as `--stage 1` or `--stage 2`, for example to modify the stage of the created sysroot. It might also be useful to configure `config.toml` to better support profiling, e.g. set `rust.debuginfo-level = 1` to add source line information to the built compiler. From aba092fd08e820becdf4b2528b67895f7e577a3e Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 6 Feb 2025 09:12:42 +0100 Subject: [PATCH 071/447] Replace link with a https based one --- src/appendix/bibliography.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/appendix/bibliography.md b/src/appendix/bibliography.md index 8f6810cbc..93426b645 100644 --- a/src/appendix/bibliography.md +++ b/src/appendix/bibliography.md @@ -82,7 +82,7 @@ Rust, as well as publications about Rust. * [Ownership is Theft: Experiences Building an Embedded OS in Rust - Amit Levy, et. al.](https://amitlevy.com/papers/tock-plos2015.pdf) * [You can't spell trust without Rust](https://faultlore.com/blah/papers/thesis.pdf). Aria Beingessner's master's thesis. * [Rust-Bio: a fast and safe bioinformatics library](https://rust-bio.github.io/). Johannes Köster -* [Safe, Correct, and Fast Low-Level Networking](https://octarineparrot.com/assets/msci_paper.pdf). Robert Clipsham's master's thesis. +* [Safe, Correct, and Fast Low-Level Networking](https://csperkins.org/research/thesis-msci-clipsham.pdf). Robert Clipsham's master's thesis. * [Formalizing Rust traits](https://open.library.ubc.ca/cIRcle/collections/ubctheses/24/items/1.0220521). Jonatan Milewski's master's thesis. * [Rust as a Language for High Performance GC Implementation](https://dl.acm.org/doi/pdf/10.1145/3241624.2926707) * [Simple Verification of Rust Programs via Functional Purification](https://github.com/Kha/electrolysis). Sebastian Ullrich's master's thesis. From 8a6fd47a8558221a20ad4ee31f98ac40cb64194d Mon Sep 17 00:00:00 2001 From: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> Date: Thu, 6 Feb 2025 14:59:43 +0100 Subject: [PATCH 072/447] improve CI cache docs --- src/tests/ci.md | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/tests/ci.md b/src/tests/ci.md index 9dde40789..a4b22392f 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -322,7 +322,7 @@ Our CI workflow uses various caching mechanisms, mainly for two things: ### Docker images caching The Docker images we use to run most of the Linux-based builders take a *long* -time to fully build. To speed up the build, we cache it using [Docker registry +time to fully build. To speed up the build, we cache them using [Docker registry caching], with the intermediate artifacts being stored on [ghcr.io]. We also push the built Docker images to ghcr, so that they can be reused by other tools (rustup) or by developers running the Docker build locally (to speed up their @@ -334,6 +334,13 @@ override the cache for the others. Instead, we store the images under different tags, identifying them with a custom hash made from the contents of all the Dockerfiles and related scripts. +The CI calculates a hash key, so that the cache of a Docker image is +invalidated if one of the following changes: + +- Dockerfile +- Files copied into the Docker image in the Dockerfile +- The architecture of the GitHub runner (x86 or ARM) + [ghcr.io]: https://github.com/rust-lang-ci/rust/pkgs/container/rust-ci [Docker registry caching]: https://docs.docker.com/build/cache/backends/registry/ @@ -341,9 +348,18 @@ Dockerfiles and related scripts. We build some C/C++ stuff in various CI jobs, and we rely on [sccache] to cache the intermediate LLVM artifacts. Sccache is a distributed ccache developed by -Mozilla, which can use an object storage bucket as the storage backend. In our -case, the artefacts are uploaded to an S3 bucket that we control -(`rust-lang-ci-sccache2`). +Mozilla, which can use an object storage bucket as the storage backend. + +With sccache there's no need to calculate the hash key ourselves. Sccache +invalidates the cache automatically when it detects changes to relevant inputs, +such as the source code, the version of the compiler, and important environment +variables. +So we just pass the sccache wrapper on top of cargo and sccache does the rest. + +We store the persistent artifacts on the S3 bucket `rust-lang-ci-sccache2`. So +when the CI runs, if sccache sees that LLVM is being compiled with the same C/C++ +compiler and the LLVM source code is the same, sccache retrieves the individual +compiled translation units from S3. [sccache]: https://github.com/mozilla/sccache From 9143d8d6c810ad5d508abf0f334bdb43c6035d43 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 6 Feb 2025 08:29:10 -0700 Subject: [PATCH 073/447] Update links to type schemas What used to be in externs.js is now in rustdoc.d.ts. --- src/rustdoc-internals/search.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rustdoc-internals/search.md b/src/rustdoc-internals/search.md index ddf8ec405..350643111 100644 --- a/src/rustdoc-internals/search.md +++ b/src/rustdoc-internals/search.md @@ -46,8 +46,8 @@ For space savings, it's also written without newlines or spaces. ] ``` -[`src/librustdoc/html/static/js/externs.js`] -defines an actual schema in a Closure `@typedef`. +[`src/librustdoc/html/static/js/rustdoc.d.ts`] +defines an actual schema in a TypeScript `type`. | Key | Name | Description | | --- | -------------------- | ------------ | @@ -68,7 +68,7 @@ with a free function called `function_name` and a struct called `Data`, with the type signature `Data, i32 -> str`, and an alias, `get_name`, that equivalently refers to `function_name`. -[`src/librustdoc/html/static/js/externs.js`]: https://github.com/rust-lang/rust/blob/79b710c13968a1a48d94431d024d2b1677940866/src/librustdoc/html/static/js/externs.js#L204-L258 +[`src/librustdoc/html/static/js/rustdoc.d.ts`]: https://github.com/rust-lang/rust/blob/2f92f050e83bf3312ce4ba73c31fe843ad3cbc60/src/librustdoc/html/static/js/rustdoc.d.ts#L344-L390 The search index needs to fit the needs of the `rustdoc` compiler, the `search.js` frontend, @@ -469,7 +469,7 @@ want the libs team to be able to add new items without causing unrelated tests to fail, but standalone tests will use it more often. The `ResultsTable` and `ParsedQuery` types are specified in -[`externs.js`](https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/static/js/externs.js). +[`rustdoc.d.ts`](https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/static/js/rustdoc.d.ts). For example, imagine we needed to fix a bug where a function named `constructor` couldn't be found. To do this, write two files: From dc919f82961736bf69a805ffcb61488c6d68a484 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 7 Feb 2025 09:03:22 +0100 Subject: [PATCH 074/447] Remove reference to enum.Reveal --- src/param_env/param_env_acquisition.md | 3 +-- src/param_env/param_env_what_is_it.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/param_env/param_env_acquisition.md b/src/param_env/param_env_acquisition.md index 391e56291..f6cff2d6c 100644 --- a/src/param_env/param_env_acquisition.md +++ b/src/param_env/param_env_acquisition.md @@ -21,7 +21,7 @@ Creating an env from an arbitrary set of where clauses is usually unnecessary an Creating an empty environment via `ParamEnv::empty` is almost always wrong. There are very few places where we actually know that the environment should be empty. One of the only places where we do actually know this is after monomorphization, however the `ParamEnv` there should be constructed via `ParamEnv::reveal_all` instead as at this point we should be able to determine the hidden type of opaque types. Codegen/Post-mono is one of the only places that should be using `ParamEnv::reveal_all`. -An additional piece of complexity here is specifying the [`Reveal`][reveal] (see linked docs for explanation of what reveal does) used for the `ParamEnv`. When constructing a param env using the `param_env` query it will have `Reveal::UserFacing`, if `Reveal::All` is desired then the [`tcx.param_env_reveal_all_normalized`][env_reveal_all_normalized] query can be used instead. +An additional piece of complexity here is specifying the `Reveal` (see linked docs for explanation of what reveal does) used for the `ParamEnv`. When constructing a param env using the `param_env` query it will have `Reveal::UserFacing`, if `Reveal::All` is desired then the [`tcx.param_env_reveal_all_normalized`][env_reveal_all_normalized] query can be used instead. The `ParamEnv` type has a method [`ParamEnv::with_reveal_all_normalized`][with_reveal_all] which converts an existing `ParamEnv` into one with `Reveal::All` specified. Where possible the previously mentioned query should be preferred as it is more efficient. @@ -38,7 +38,6 @@ The `ParamEnv` type has a method [`ParamEnv::with_reveal_all_normalized`][with_r [with_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.with_reveal_all_normalized [env_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.reveal_all [env_empty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.empty -[reveal]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/traits/enum.Reveal.html [pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html [param_env_query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env [method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html diff --git a/src/param_env/param_env_what_is_it.md b/src/param_env/param_env_what_is_it.md index ca09518d9..5c2f4d594 100644 --- a/src/param_env/param_env_what_is_it.md +++ b/src/param_env/param_env_what_is_it.md @@ -3,7 +3,7 @@ The type system relies on information in the environment in order for it to function correctly. This information is stored in the [`ParamEnv`][pe] type and it is important to use the correct `ParamEnv` when interacting with the type system. -The information represented by `ParamEnv` is a list of in-scope where-clauses, and a [`Reveal`][reveal] (see linked docs for more information). A `ParamEnv` typically corresponds to a specific item's where clauses, some clauses are not explicitly written bounds and instead are implicitly added in [`predicates_of`][predicates_of] such as `ConstArgHasType` or some implied bounds. +The information represented by `ParamEnv` is a list of in-scope where-clauses, and a `Reveal` (see linked docs for more information). A `ParamEnv` typically corresponds to a specific item's where clauses, some clauses are not explicitly written bounds and instead are implicitly added in [`predicates_of`][predicates_of] such as `ConstArgHasType` or some implied bounds. A `ParamEnv` can also be created with arbitrary data that is not derived from a specific item such as in [`compare_method_predicate_entailment`][method_pred_entailment] which creates a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses. @@ -57,4 +57,3 @@ It's very important to use the correct `ParamEnv` when interacting with the type [method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html [pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html [query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env -[reveal]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/traits/enum.Reveal.html \ No newline at end of file From b72d90634f96d400b126d30b1dffd50c4057f7e8 Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Mon, 10 Feb 2025 04:02:33 +0000 Subject: [PATCH 075/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index b62959720..78e9ecdf1 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -613bdd49978298648ed05ace086bd1ecad54b44a +124cc92199ffa924f6b4c7cc819a85b65e0c3984 From 844a47ab9f6e059ffdcc5912d9eac57f9166d174 Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Tue, 11 Feb 2025 08:14:00 +0300 Subject: [PATCH 076/447] compiler/rustc_data_structures/src/sync.rs: delete MappedLockGuard It seems it is left-over after some refactoring --- src/parallel-rustc.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/parallel-rustc.md b/src/parallel-rustc.md index 44c78a125..49c52976c 100644 --- a/src/parallel-rustc.md +++ b/src/parallel-rustc.md @@ -58,7 +58,6 @@ are implemented differently depending on whether `parallel-compiler` is true. | WriteGuard | parking_lot::RwLockWriteGuard | std::cell::RefMut | | MappedWriteGuard | parking_lot::MappedRwLockWriteGuard | std::cell::RefMut | | LockGuard | parking_lot::MutexGuard | std::cell::RefMut | -| MappedLockGuard | parking_lot::MappedMutexGuard | std::cell::RefMut | - These thread-safe data structures are interspersed during compilation which can cause lock contention resulting in degraded performance as the number of From efa3dae1e187bc6511da4cab196fca2ed0142970 Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Tue, 11 Feb 2025 08:25:50 +0300 Subject: [PATCH 077/447] compiler/rustc_data_structures/src/sync.rs: delete Weak --- src/parallel-rustc.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/parallel-rustc.md b/src/parallel-rustc.md index 49c52976c..4fb91da68 100644 --- a/src/parallel-rustc.md +++ b/src/parallel-rustc.md @@ -46,7 +46,6 @@ are implemented differently depending on whether `parallel-compiler` is true. | data structure | parallel | non-parallel | | -------------------------------- | --------------------------------------------------- | ------------ | -| Weak | std::sync::Weak | std::rc::Weak | | Atomic{Bool}/{Usize}/{U32}/{U64} | std::sync::atomic::Atomic{Bool}/{Usize}/{U32}/{U64} | (std::cell::Cell) | | OnceCell | std::sync::OnceLock | std::cell::OnceCell | | Lock\ | (parking_lot::Mutex\) | (std::cell::RefCell) | From f0bcb7376097fc03f24fb1ae16cea190f8f3a224 Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Tue, 11 Feb 2025 08:57:36 +0300 Subject: [PATCH 078/447] compiler/rustc_data_structures/src/sync.rs: remove atomics, but not AtomicU64! --- src/parallel-rustc.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/parallel-rustc.md b/src/parallel-rustc.md index 4fb91da68..deddf77e3 100644 --- a/src/parallel-rustc.md +++ b/src/parallel-rustc.md @@ -46,7 +46,6 @@ are implemented differently depending on whether `parallel-compiler` is true. | data structure | parallel | non-parallel | | -------------------------------- | --------------------------------------------------- | ------------ | -| Atomic{Bool}/{Usize}/{U32}/{U64} | std::sync::atomic::Atomic{Bool}/{Usize}/{U32}/{U64} | (std::cell::Cell) | | OnceCell | std::sync::OnceLock | std::cell::OnceCell | | Lock\ | (parking_lot::Mutex\) | (std::cell::RefCell) | | RwLock\ | (parking_lot::RwLock\) | (std::cell::RefCell) | From eeec2f4b40dff17ec92902cdd7752c6c7ffe4412 Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Tue, 11 Feb 2025 09:23:54 +0300 Subject: [PATCH 079/447] src/doc/rustc-dev-guide/src/parallel-rustc.md: remove Arc and Rc (it seems they are left-over after my PR) --- src/parallel-rustc.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/parallel-rustc.md b/src/parallel-rustc.md index deddf77e3..c5b70706a 100644 --- a/src/parallel-rustc.md +++ b/src/parallel-rustc.md @@ -170,12 +170,10 @@ Here are some resources that can be used to learn more: - [This list of interior mutability in the compiler by nikomatsakis][imlist] [`rayon`]: https://crates.io/crates/rayon -[Arc]: https://doc.rust-lang.org/std/sync/struct.Arc.html [imlist]: https://github.com/nikomatsakis/rustc-parallelization/blob/master/interior-mutability-list.md [irlo0]: https://internals.rust-lang.org/t/parallelizing-rustc-using-rayon/6606 [irlo1]: https://internals.rust-lang.org/t/help-test-parallel-rustc/11503 [monomorphization]: backend/monomorph.md [parallel-rustdoc]: https://github.com/rust-lang/rust/issues/82741 -[Rc]: https://doc.rust-lang.org/std/rc/struct.Rc.html [rustc-rayon]: https://github.com/rust-lang/rustc-rayon [tracking]: https://github.com/rust-lang/rust/issues/48685 From 66e5b92c319b15b4a1e093b7c28cc5f269493268 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 11 Feb 2025 15:47:29 +0100 Subject: [PATCH 080/447] dev-guide: Link to t-lang procedures for new features --- src/implementing_new_features.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/implementing_new_features.md b/src/implementing_new_features.md index d87afeaed..5b67ccd7f 100644 --- a/src/implementing_new_features.md +++ b/src/implementing_new_features.md @@ -9,7 +9,11 @@ smoothly. **NOTE: this section is for *language* features, not *library* features, which use [a different process].** +See also [the Rust Language Design Team's procedures][lang-propose] for +proposing changes to the language. + [a different process]: ./stability.md +[lang-propose]: https://lang-team.rust-lang.org/how_to/propose.html ## The @rfcbot FCP process From 5cb9ff172f307bcaf5bdc3e8d2138fd089c51748 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 11 Feb 2025 21:21:04 +0200 Subject: [PATCH 081/447] document the directive --- src/tests/directives.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/directives.md b/src/tests/directives.md index 9e0f8f9c2..b6209bcb2 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -192,6 +192,8 @@ settings: specified atomic widths, e.g. the test with `//@ needs-target-has-atomic: 8, 16, ptr` will only run if it supports the comma-separated list of atomic widths. +- `needs-dynamic-linking` - ignores if target does not support dynamic linking + (which is orthogonal to it being unable to create `dylib` and `cdylib` crate types) The following directives will check LLVM support: From 5a9d7654d24d76cdd28e8355d9b9856b97be4694 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 6 Feb 2025 09:15:14 +0100 Subject: [PATCH 082/447] Run CI multiple times a day --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f810e2fb..7c414ce26 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,8 +6,8 @@ on: - master pull_request: schedule: - # Run at 18:00 UTC every day - - cron: '0 18 * * *' + # Run multiple times a day as the successfull cached links are not checked every time. + - cron: '0 */3 * * *' jobs: ci: From db57a5f454168b86820c26cb3c6ad73a4b331e1b Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 7 Feb 2025 19:33:58 +0100 Subject: [PATCH 083/447] intern valtrees --- src/mir/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mir/index.md b/src/mir/index.md index 778c58391..f355875aa 100644 --- a/src/mir/index.md +++ b/src/mir/index.md @@ -304,9 +304,9 @@ The most important rule for this representation is that every value must be uniquely represented. In other words: a specific value must only be representable in one specific way. For example: there is only one way to represent an array of two integers as a `ValTree`: -`ValTree::Branch(&[ValTree::Leaf(first_int), ValTree::Leaf(second_int)])`. +`Branch([Leaf(first_int), Leaf(second_int)])`. Even though theoretically a `[u32; 2]` could be encoded in a `u64` and thus just be a -`ValTree::Leaf(bits_of_two_u32)`, that is not a legal construction of `ValTree` +`Leaf(bits_of_two_u32)`, that is not a legal construction of `ValTree` (and is very complex to do, so it is unlikely anyone is tempted to do so). These rules also mean that some values are not representable. There can be no `union`s in type From 356e4816b20c2baa0a030ef6dbeef696670a7e22 Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 12 Feb 2025 21:03:34 -0500 Subject: [PATCH 084/447] document bootstrap logging --- .../bootstrapping/debugging-bootstrap.md | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/building/bootstrapping/debugging-bootstrap.md b/src/building/bootstrapping/debugging-bootstrap.md index 3f907e85d..75d789569 100644 --- a/src/building/bootstrapping/debugging-bootstrap.md +++ b/src/building/bootstrapping/debugging-bootstrap.md @@ -1,7 +1,46 @@ # Debugging bootstrap +There are two main ways to debug bootstrap itself. The first is through println logging, and the second is through the `tracing` feature. + > FIXME: this section should be expanded +## `println` logging + +Bootstrap has extensive unstructured logging. Most of it is gated behind the `--verbose` flag (pass `-vv` for even more detail). + +If you want to know which `Step` ran a command, you could invoke bootstrap like so: + +``` +$ ./x dist rustc --dry-run -vv +learning about cargo +running: RUSTC_BOOTSTRAP="1" "/home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "metadata" "--format-version" "1" "--no-deps" "--manifest-path" "/home/jyn/src/rust2/Cargo.toml" (failure_mode=Exit) (created at src/bootstrap/src/core/metadata.rs:81:25, executed at src/bootstrap/src/core/metadata.rs:92:50) +running: RUSTC_BOOTSTRAP="1" "/home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "metadata" "--format-version" "1" "--no-deps" "--manifest-path" "/home/jyn/src/rust2/library/Cargo.toml" (failure_mode=Exit) (created at src/bootstrap/src/core/metadata.rs:81:25, executed at src/bootstrap/src/core/metadata.rs:92:50) +> Assemble { target_compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu } } + > Libdir { compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu }, target: x86_64-unknown-linux-gnu } + > Sysroot { compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu }, force_recompile: false } +Removing sysroot /home/jyn/src/rust2/build/tmp-dry-run/x86_64-unknown-linux-gnu/stage1 to avoid caching bugs + < Sysroot { compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu }, force_recompile: false } + < Libdir { compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu }, target: x86_64-unknown-linux-gnu } +... +``` + +This will go through all the recursive dependency calculations, where `Step`s internally call `builder.ensure()`, without actually running cargo or the compiler. + +In some cases, even this may not be enough logging (if so, please add more!). In that case, you can omit `--dry-run`, which will show the normal output inline with the debug logging: + +``` + c Sysroot { compiler: Compiler { stage: 0, host: x86_64-unknown-linux-gnu }, force_recompile: false } +using sysroot /home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/stage0-sysroot +Building stage0 library artifacts (x86_64-unknown-linux-gnu) +running: cd "/home/jyn/src/rust2" && env ... RUSTC_VERBOSE="2" RUSTC_WRAPPER="/home/jyn/src/rust2/build/bootstrap/debug/rustc" "/home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "--target" "x86_64-unknown-linux-gnu" "-Zbinary-dep-depinfo" "-Zroot-dir=/home/jyn/src/rust2" "-v" "-v" "--manifest-path" "/home/jyn/src/rust2/library/sysroot/Cargo.toml" "--message-format" "json-render-diagnostics" + 0.293440230s INFO prepare_target{force=false package_id=sysroot v0.0.0 (/home/jyn/src/rust2/library/sysroot) target="sysroot"}: cargo::core::compiler::fingerprint: fingerprint error for sysroot v0.0.0 (/home/jyn/src/rust2/library/sysroot)/Build/TargetInner { name_inferred: true, ..: lib_target("sysroot", ["lib"], "/home/jyn/src/rust2/library/sysroot/src/lib.rs", Edition2021) } +... +``` + +In most cases this should not be necessary. + +TODO: we should convert all this to structured logging so it's easier to control precisely. + ## `tracing` in bootstrap Bootstrap has conditional [`tracing`][tracing] setup to provide structured logging. @@ -53,11 +92,11 @@ Checking stage0 bootstrap artifacts (x86_64-unknown-linux-gnu) Build completed successfully in 0:00:08 ``` -#### Controlling log output +#### Controlling tracing output The env var `BOOTSTRAP_TRACING` accepts a [`tracing` env-filter][tracing-env-filter]. -There are two orthogonal ways to control which kind of logs you want: +There are two orthogonal ways to control which kind of tracing logs you want: 1. You can specify the log **level**, e.g. `DEBUG` or `TRACE`. 2. You can also control the log **target**, e.g. `bootstrap` or `bootstrap::core::config` vs custom targets like `CONFIG_HANDLING`. From 470a207ef09aaa474cb61495b0f2b39477635bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 12 Feb 2025 13:48:48 +0100 Subject: [PATCH 085/447] Document bootstrap profiling --- src/building/bootstrapping/debugging-bootstrap.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/building/bootstrapping/debugging-bootstrap.md b/src/building/bootstrapping/debugging-bootstrap.md index 3f907e85d..04fa5b204 100644 --- a/src/building/bootstrapping/debugging-bootstrap.md +++ b/src/building/bootstrapping/debugging-bootstrap.md @@ -121,6 +121,14 @@ For `#[instrument]`, it's recommended to: - Explicitly pick an instrumentation name via `name = ".."` to distinguish between e.g. `run` of different steps. - Take care to not cause diverging behavior via tracing, e.g. building extra things only when tracing infra is enabled. +### Profiling bootstrap + +You can use the `COMMAND` tracing target to trace execution of most commands spawned by bootstrap. If you also use the `BOOTSTRAP_PROFILE=1` environment variable, bootstrap will generate a Chrome JSON trace file, which can be visualized in Chrome's `chrome://tracing` page or on https://ui.perfetto.dev. + +```bash +$ BOOTSTRAP_TRACING=COMMAND=trace BOOTSTRAP_PROFILE=1 ./x build library +``` + ### rust-analyzer integration? Unfortunately, because bootstrap is a `rust-analyzer.linkedProjects`, you can't ask r-a to check/build bootstrap itself with `tracing` feature enabled to get relevant completions, due to lack of support as described in . From b353b6e10aea35fced5ea59435d7523f8fceab70 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 14 Feb 2025 13:43:55 +0800 Subject: [PATCH 086/447] add notes for perf issue --- src/profiling/with_perf.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/profiling/with_perf.md b/src/profiling/with_perf.md index 6cd98f886..51a22d185 100644 --- a/src/profiling/with_perf.md +++ b/src/profiling/with_perf.md @@ -52,6 +52,13 @@ you made in the beginning. But there are some things to be aware of: - You probably don't want incremental messing about with your profile. So something like `CARGO_INCREMENTAL=0` can be helpful. +In case to avoid the issue of `addr2line xxx/elf: could not read first record` when reading +collected data from `cargo`, you may need use the latest version of `addr2line`: + +```bash +cargo install addr2line --features="bin" +``` + ### Gathering a perf profile from a `perf.rust-lang.org` test Often we want to analyze a specific test from `perf.rust-lang.org`. From 362246d1a807d2f7141e60db09e4e52d1a468878 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 14 Feb 2025 07:23:10 +0100 Subject: [PATCH 087/447] Fix borked link --- src/compiler-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler-debugging.md b/src/compiler-debugging.md index e2097b26e..c16b3ee7a 100644 --- a/src/compiler-debugging.md +++ b/src/compiler-debugging.md @@ -368,7 +368,7 @@ error: layout_of(&'a u32) = Layout { error: aborting due to previous error ``` -[`Layout`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/abi/struct.Layout.html +[`Layout`]: https://doc.rust-lang.org/nightly/nightly-rustc/stable_mir/abi/struct.Layout.html ## Configuring CodeLLDB for debugging `rustc` From e7e6e97524115210bef334b9f66e5343198f1a8b Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 14 Feb 2025 07:26:43 +0100 Subject: [PATCH 088/447] Start using latest release where -f checks all local links --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f810e2fb..2bae8fcbd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest env: MDBOOK_VERSION: 0.4.21 - MDBOOK_LINKCHECK2_VERSION: 0.8.1 + MDBOOK_LINKCHECK2_VERSION: 0.9.0 MDBOOK_MERMAID_VERSION: 0.12.6 MDBOOK_TOC_VERSION: 0.11.2 DEPLOY_DIR: book/html From f32fc55183701d1a75a7cbd6923ad8201f14a558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 15 Feb 2025 19:16:42 +0800 Subject: [PATCH 089/447] rustc-dev-guide: document `{ignore,only}-rustc_abi-x86-sse2` --- src/tests/directives.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/directives.md b/src/tests/directives.md index b6209bcb2..00bb2bc4d 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -154,6 +154,7 @@ Some examples of `X` in `ignore-X` or `only-X`: `ignore-coverage-map`, `ignore-coverage-run` - When testing a dist toolchain: `dist` - This needs to be enabled with `COMPILETEST_ENABLE_DIST_TESTS=1` +- The `rustc_abi` of the target: e.g. `rustc_abi-x86_64-sse2` The following directives will check rustc build settings and target settings: From 1979d851897c74a1c1431ab396d313a735d67530 Mon Sep 17 00:00:00 2001 From: Florian Brucker Date: Sat, 15 Feb 2025 19:44:32 +0100 Subject: [PATCH 090/447] Fix examples to work with nightly-2025-02-13 While there were comments indicating which nightly versions the examples were tested with, those versions did not work for me: neither did the examples compile, nor did they produce the expected output. This commit fixes the compilation issues, using nightly-2025-02-13 for all examples (previously the version differed between the examples) and, in the case of the `rustc_driver` examples, also fixes the argument passing: rustc ignores the first argument, so we need to pass the filename as the second (otherwise we only get the help text printed). Note that the `rustc-interface-getting-diagnostics.rs` example still does not produce any output, which I assume is not how it is intended. However, I don't know enough to fix it. To avoid inconsistencies between the documented version and the actually required version I've moved the version comment from the Markdown into the Rust code where it hopefully won't be forgotten as easily. Finally I've clarified in the examples' README that you also need to use the proper nightly version when compiling the examples, not just when running them. --- examples/README | 5 ++++- examples/rustc-driver-example.rs | 14 ++++++++++++-- .../rustc-driver-interacting-with-the-ast.rs | 16 +++++++++++++--- examples/rustc-interface-example.rs | 8 ++++---- examples/rustc-interface-getting-diagnostics.rs | 6 ++++-- src/rustc-driver/getting-diagnostics.md | 1 - src/rustc-driver/interacting-with-the-ast.md | 1 - 7 files changed, 37 insertions(+), 14 deletions(-) diff --git a/examples/README b/examples/README index ca49dd74d..05e446737 100644 --- a/examples/README +++ b/examples/README @@ -4,7 +4,10 @@ For each example to compile, you will need to first run the following: To create an executable: - rustc rustc-driver-example.rs + rustup run nightly rustc rustc-driver-example.rs + +You might need to be more specific about the exact nightly version. See the comments at the top of +the examples for the version they were written for. To run an executable: diff --git a/examples/rustc-driver-example.rs b/examples/rustc-driver-example.rs index 14998965a..984bd3e37 100644 --- a/examples/rustc-driver-example.rs +++ b/examples/rustc-driver-example.rs @@ -1,3 +1,5 @@ +// Tested with nightly-2025-02-13 + #![feature(rustc_private)] extern crate rustc_ast; @@ -73,7 +75,7 @@ impl rustc_driver::Callbacks for MyCallbacks { let hir = tcx.hir(); let item = hir.item(id); match item.kind { - rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn(_, _, _) => { + rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn { .. } => { let name = item.ident; let ty = tcx.type_of(item.hir_id().owner.def_id); println!("{name:?}:\t{ty:?}") @@ -87,5 +89,13 @@ impl rustc_driver::Callbacks for MyCallbacks { } fn main() { - run_compiler(&["main.rs".to_string()], &mut MyCallbacks); + run_compiler( + &[ + // The first argument, which in practice contains the name of the binary being executed + // (i.e. "rustc") is ignored by rustc. + "ignored".to_string(), + "main.rs".to_string(), + ], + &mut MyCallbacks, + ); } diff --git a/examples/rustc-driver-interacting-with-the-ast.rs b/examples/rustc-driver-interacting-with-the-ast.rs index 9fcb16b0f..98c6041d0 100644 --- a/examples/rustc-driver-interacting-with-the-ast.rs +++ b/examples/rustc-driver-interacting-with-the-ast.rs @@ -1,3 +1,5 @@ +// Tested with nightly-2025-02-13 + #![feature(rustc_private)] extern crate rustc_ast; @@ -74,8 +76,8 @@ impl rustc_driver::Callbacks for MyCallbacks { for id in hir_krate.items() { let item = hir_krate.item(id); // Use pattern-matching to find a specific node inside the main function. - if let rustc_hir::ItemKind::Fn(_, _, body_id) = item.kind { - let expr = &tcx.hir().body(body_id).value; + if let rustc_hir::ItemKind::Fn { body, .. } = item.kind { + let expr = &tcx.hir().body(body).value; if let rustc_hir::ExprKind::Block(block, _) = expr.kind { if let rustc_hir::StmtKind::Let(let_stmt) = block.stmts[0].kind { if let Some(expr) = let_stmt.init { @@ -94,5 +96,13 @@ impl rustc_driver::Callbacks for MyCallbacks { } fn main() { - run_compiler(&["main.rs".to_string()], &mut MyCallbacks); + run_compiler( + &[ + // The first argument, which in practice contains the name of the binary being executed + // (i.e. "rustc") is ignored by rustc. + "ignored".to_string(), + "main.rs".to_string(), + ], + &mut MyCallbacks, + ); } diff --git a/examples/rustc-interface-example.rs b/examples/rustc-interface-example.rs index 30f48ea52..70f27c2a8 100644 --- a/examples/rustc-interface-example.rs +++ b/examples/rustc-interface-example.rs @@ -1,3 +1,5 @@ +// Tested with nightly-2025-02-13 + #![feature(rustc_private)] extern crate rustc_driver; @@ -9,8 +11,6 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; -use std::sync::Arc; - use rustc_errors::registry; use rustc_hash::FxHashMap; use rustc_session::config; @@ -56,7 +56,7 @@ fn main() { expanded_args: Vec::new(), ice_file: None, hash_untracked_state: None, - using_internal_features: Arc::default(), + using_internal_features: &rustc_driver::USING_INTERNAL_FEATURES, }; rustc_interface::run_compiler(config, |compiler| { // Parse the program and print the syntax tree. @@ -68,7 +68,7 @@ fn main() { let hir = tcx.hir(); let item = hir.item(id); match item.kind { - rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn(_, _, _) => { + rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn { .. } => { let name = item.ident; let ty = tcx.type_of(item.hir_id().owner.def_id); println!("{name:?}:\t{ty:?}") diff --git a/examples/rustc-interface-getting-diagnostics.rs b/examples/rustc-interface-getting-diagnostics.rs index 2355cb85a..39b236e17 100644 --- a/examples/rustc-interface-getting-diagnostics.rs +++ b/examples/rustc-interface-getting-diagnostics.rs @@ -1,3 +1,5 @@ +// Tested with nightly-2025-02-13 + #![feature(rustc_private)] extern crate rustc_data_structures; @@ -15,7 +17,7 @@ use std::sync::{Arc, Mutex}; use rustc_errors::emitter::Emitter; use rustc_errors::registry::{self, Registry}; use rustc_errors::translation::Translate; -use rustc_errors::{DiagCtxt, DiagInner, FluentBundle}; +use rustc_errors::{DiagInner, FluentBundle}; use rustc_session::config; use rustc_span::source_map::SourceMap; @@ -79,7 +81,7 @@ fn main() { expanded_args: Vec::new(), ice_file: None, hash_untracked_state: None, - using_internal_features: Arc::default(), + using_internal_features: &rustc_driver::USING_INTERNAL_FEATURES, }; rustc_interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); diff --git a/src/rustc-driver/getting-diagnostics.md b/src/rustc-driver/getting-diagnostics.md index e3ca32305..1043df6ec 100644 --- a/src/rustc-driver/getting-diagnostics.md +++ b/src/rustc-driver/getting-diagnostics.md @@ -8,7 +8,6 @@ otherwise be printed to stderr. To get diagnostics from the compiler, configure [`rustc_interface::Config`] to output diagnostic to a buffer, and run [`TyCtxt.analysis`]. -The following was tested with `nightly-2024-09-16`: ```rust {{#include ../../examples/rustc-interface-getting-diagnostics.rs}} diff --git a/src/rustc-driver/interacting-with-the-ast.md b/src/rustc-driver/interacting-with-the-ast.md index 5eaa0c82c..f46418701 100644 --- a/src/rustc-driver/interacting-with-the-ast.md +++ b/src/rustc-driver/interacting-with-the-ast.md @@ -5,7 +5,6 @@ ## Getting the type of an expression To get the type of an expression, use the [`after_analysis`] callback to get a [`TyCtxt`]. -The following was tested with `nightly-2024-12-15`: ```rust {{#include ../../examples/rustc-driver-interacting-with-the-ast.rs}} From 2ceea672a09bbfdd1a730b1bc4165cf99bfa120d Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Sat, 15 Feb 2025 23:03:42 +0100 Subject: [PATCH 091/447] Fix CI schedule --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c414ce26..00c1c4092 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: pull_request: schedule: # Run multiple times a day as the successfull cached links are not checked every time. - - cron: '0 */3 * * *' + - cron: '0 */8 * * *' jobs: ci: From 141a8a1962ce8b698e6437be77e054523abae7af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 15 Feb 2025 22:59:01 +0800 Subject: [PATCH 092/447] rustc-dev-guide: document `COMPILER` and `COMPILER_FOR` tracing targets --- src/building/bootstrapping/debugging-bootstrap.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/building/bootstrapping/debugging-bootstrap.md b/src/building/bootstrapping/debugging-bootstrap.md index 04fa5b204..04d8e91dc 100644 --- a/src/building/bootstrapping/debugging-bootstrap.md +++ b/src/building/bootstrapping/debugging-bootstrap.md @@ -76,6 +76,14 @@ $ BOOTSTRAP_TRACING=CONFIG_HANDLING=TRACE ./x build library --stage 1 [tracing-env-filter]: https://docs.rs/tracing-subscriber/0.3.19/tracing_subscriber/filter/struct.EnvFilter.html +##### FIXME(#96176): specific tracing for `compiler()` vs `compiler_for()` + +The additional targets `COMPILER` and `COMPILER_FOR` are used to help trace what +`builder.compiler()` and `builder.compiler_for()` does. They should be removed +if [#96176][cleanup-compiler-for] is resolved. + +[cleanup-compiler-for]: https://github.com/rust-lang/rust/issues/96176 + ### Using `tracing` in bootstrap Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need to be gated behind `tracing` feature. Examples: From 59f65a3c240496a216649c3a346505ea4de048a1 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Sun, 16 Feb 2025 13:21:34 +0100 Subject: [PATCH 093/447] Bump mdbook-linkcheck2 dependency version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2796c1420..22a4fb190 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest env: MDBOOK_VERSION: 0.4.21 - MDBOOK_LINKCHECK2_VERSION: 0.9.0 + MDBOOK_LINKCHECK2_VERSION: 0.9.1 MDBOOK_MERMAID_VERSION: 0.12.6 MDBOOK_TOC_VERSION: 0.11.2 DEPLOY_DIR: book/html From 35c8087bff2281dc0c87ec17ca654d2fe362a388 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 3 Feb 2025 10:45:49 +1100 Subject: [PATCH 094/447] Move some `Map` methods onto `TyCtxt`. The end goal is to eliminate `Map` altogether. I added a `hir_` prefix to all of them, that seemed simplest. The exceptions are `module_items` which became `hir_module_free_items` because there was already a `hir_module_items`, and `items` which became `hir_free_items` for consistency with `hir_module_free_items`. --- examples/rustc-driver-interacting-with-the-ast.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rustc-driver-interacting-with-the-ast.rs b/examples/rustc-driver-interacting-with-the-ast.rs index 9fcb16b0f..dc63e1aa5 100644 --- a/examples/rustc-driver-interacting-with-the-ast.rs +++ b/examples/rustc-driver-interacting-with-the-ast.rs @@ -75,7 +75,7 @@ impl rustc_driver::Callbacks for MyCallbacks { let item = hir_krate.item(id); // Use pattern-matching to find a specific node inside the main function. if let rustc_hir::ItemKind::Fn(_, _, body_id) = item.kind { - let expr = &tcx.hir().body(body_id).value; + let expr = &tcx.hir_body(body_id).value; if let rustc_hir::ExprKind::Block(block, _) = expr.kind { if let rustc_hir::StmtKind::Let(let_stmt) = block.stmts[0].kind { if let Some(expr) = let_stmt.init { From 912575e174f41c19e56a9b34d0ec8a81e8775373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Feb 2025 13:21:40 +0100 Subject: [PATCH 095/447] Update documentation --- src/building/optimized-build.md | 2 +- src/tests/ci.md | 6 +++--- src/tests/docker.md | 9 +++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/building/optimized-build.md b/src/building/optimized-build.md index 8feda5982..f8ca1d0dc 100644 --- a/src/building/optimized-build.md +++ b/src/building/optimized-build.md @@ -126,4 +126,4 @@ Here is an example of how can `opt-dist` be used locally (outside of CI): [`Environment`]: https://github.com/rust-lang/rust/blob/ee451f8faccf3050c76cdcd82543c917b40c7962/src/tools/opt-dist/src/environment.rs#L5 > Note: if you want to run the actual CI pipeline, instead of running `opt-dist` locally, -> you can execute `python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux`. +> you can execute `cargo run --manifest-path src/ci/citool/Cargo.toml run-local dist-x86_64-linux`. diff --git a/src/tests/ci.md b/src/tests/ci.md index a4b22392f..ae6adb678 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -28,7 +28,7 @@ Our CI is primarily executed on [GitHub Actions], with a single workflow defined in [`.github/workflows/ci.yml`], which contains a bunch of steps that are unified for all CI jobs that we execute. When a commit is pushed to a corresponding branch or a PR, the workflow executes the -[`src/ci/github-actions/ci.py`] script, which dynamically generates the specific CI +[`src/ci/citool`] crate, which dynamically generates the specific CI jobs that should be executed. This script uses the [`jobs.yml`] file as an input, which contains a declarative configuration of all our CI jobs. @@ -299,7 +299,7 @@ platform’s custom [Docker container]. This has a lot of advantages for us: - We can avoid reinstalling tools (like QEMU or the Android emulator) every time thanks to Docker image caching. - Users can run the same tests in the same environment locally by just running - `python3 src/ci/github-actions/ci.py run-local `, which is awesome to debug failures. Note that there are only linux docker images available locally due to licensing and + `cargo run --manifest-path src/ci/citool/Cargo.toml run-local `, which is awesome to debug failures. Note that there are only linux docker images available locally due to licensing and other restrictions. The docker images prefixed with `dist-` are used for building artifacts while @@ -443,7 +443,7 @@ this: [GitHub Actions]: https://github.com/rust-lang/rust/actions [`jobs.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/jobs.yml [`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/master/.github/workflows/ci.yml -[`src/ci/github-actions/ci.py`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/ci.py +[`src/ci/citool`]: https://github.com/rust-lang/rust/blob/master/src/ci/citool [rust-lang-ci]: https://github.com/rust-lang-ci/rust/actions [bors]: https://github.com/bors [homu]: https://github.com/rust-lang/homu diff --git a/src/tests/docker.md b/src/tests/docker.md index 2ca08d421..a8a388ef9 100644 --- a/src/tests/docker.md +++ b/src/tests/docker.md @@ -53,6 +53,15 @@ Some additional notes about using the interactive mode: containers. With the container name, run `docker exec -it /bin/bash` where `` 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 +# 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 From 019264fc55b88135f4d3ca75adb16d71775d56b7 Mon Sep 17 00:00:00 2001 From: "Chai T. Rex" Date: Mon, 17 Feb 2025 23:48:39 -0500 Subject: [PATCH 096/447] Add Zed to dev guide suggested workflows page --- src/building/suggested.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/building/suggested.md b/src/building/suggested.md index 2c6c3fe1d..5c041d6cb 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -154,6 +154,16 @@ You can run `./x setup editor` and select `helix`, which will prompt you to create `languages.toml` with the recommended configuration for Helix. The recommended settings live at [`src/etc/rust_analyzer_helix.toml`]. +### Zed + +Zed comes with built-in LSP and rust-analyzer support. +It can be configured through `.zed/settings.json`, as described +[here](https://zed.dev/docs/configuring-languages). Selecting `zed` +in `./x setup editor` will prompt you to create a `.zed/settings.json` +file which will configure Zed with the recommended configuration. The +recommended `rust-analyzer` settings live +at [`src/etc/rust_analyzer_zed.json`]. + ## Check, check, and check again When doing simple refactoring, it can be useful to run `./x check` @@ -381,4 +391,5 @@ load this completion. [`src/etc/rust_analyzer_settings.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_settings.json [`src/etc/rust_analyzer_eglot.el`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_eglot.el [`src/etc/rust_analyzer_helix.toml`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_helix.toml +[`src/etc/rust_analyzer_zed.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_zed.json [`src/etc/pre-push.sh`]: https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh From 209dd46dad6a9ef6814b8d785a30ee4cc7304653 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 18 Feb 2025 10:28:36 -0600 Subject: [PATCH 097/447] docs(dev): Remove reference to features_untracked This was removed in #114723 --- src/implementing_new_features.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/implementing_new_features.md b/src/implementing_new_features.md index 5b67ccd7f..c77b872cf 100644 --- a/src/implementing_new_features.md +++ b/src/implementing_new_features.md @@ -167,9 +167,7 @@ a new unstable feature: 1. Prevent usage of the new feature unless the feature gate is set. You can check it in most places in the compiler using the - expression `tcx.features().$feature_name` (or - `sess.features_untracked().$feature_name` if the - tcx is unavailable) + expression `tcx.features().$feature_name` If the feature gate is not set, you should either maintain the pre-feature behavior or raise an error, depending on From 1520629844fc748359152008611f003e577971bd Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 18 Feb 2025 10:35:13 -0600 Subject: [PATCH 098/447] docs(dev): Access features as functions, not members This was changed in #132027 --- src/implementing_new_features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/implementing_new_features.md b/src/implementing_new_features.md index c77b872cf..fda38ef4f 100644 --- a/src/implementing_new_features.md +++ b/src/implementing_new_features.md @@ -167,7 +167,7 @@ a new unstable feature: 1. Prevent usage of the new feature unless the feature gate is set. You can check it in most places in the compiler using the - expression `tcx.features().$feature_name` + expression `tcx.features().$feature_name()` If the feature gate is not set, you should either maintain the pre-feature behavior or raise an error, depending on From 97b80c80d12ec1241a59f202c6546208b93c2ef5 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 19 Feb 2025 09:03:35 +0300 Subject: [PATCH 099/447] add rustc-dev doc about bootstrap tools Signed-off-by: onur-ozkan --- src/SUMMARY.md | 1 + .../writing-tools-in-bootstrap.md | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/building/bootstrapping/writing-tools-in-bootstrap.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 91c4aeacb..106db508e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -75,6 +75,7 @@ - [Prologue](./building/bootstrapping/intro.md) - [What Bootstrapping does](./building/bootstrapping/what-bootstrapping-does.md) - [How Bootstrap does it](./building/bootstrapping/how-bootstrap-does-it.md) +- [Writing tools in Bootstrap](./building/bootstrapping/writing-tools-in-bootstrap.md) - [Debugging bootstrap](./building/bootstrapping/debugging-bootstrap.md) # High-level Compiler Architecture diff --git a/src/building/bootstrapping/writing-tools-in-bootstrap.md b/src/building/bootstrapping/writing-tools-in-bootstrap.md new file mode 100644 index 000000000..6046d5b13 --- /dev/null +++ b/src/building/bootstrapping/writing-tools-in-bootstrap.md @@ -0,0 +1,23 @@ +# Writing tools in Bootstrap + +There are three types of tools you can write in bootstrap: + +- **`Mode::ToolBootstrap`** + Use this for tools that don’t need anything from the in-tree compiler and can run with the stage0 `rustc`. + The output is placed in the "stage0-bootstrap-tools" directory. This mode is for general-purpose tools built + entirely with the stage0 compiler, including target libraries and only works for stage 0. + +- **`Mode::ToolStd`** + Use this for tools that rely on the locally built std. The output goes into the "stageN-tools" directory. + This mode is rarely used, mainly for `compiletest` which requires `libtest`. + +- **`Mode::ToolRustc`** + Use this for tools that depend on both the locally built `rustc` and the target `std`. This is more complex than + the other modes because the tool must be built with the same compiler used for `rustc` and placed in the "stageN-tools" + directory. When you choose `Mode::ToolRustc`, `ToolBuild` implementation takes care of this automatically. + If you need to use the builder’s compiler for something specific, you can get it from `ToolBuildResult`, which is + returned by the tool's [`Step`]. + +Regardless of the tool type you must return `ToolBuildResult` from the tool’s [`Step`] implementation and use `ToolBuild` inside it. + +[`Step`]: https://doc.rust-lang.org/nightly/nightly-rustc/bootstrap/core/builder/trait.Step.html From 4f883945452097bc02969fdc728ed5806c9f8766 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 20 Feb 2025 21:39:45 +0800 Subject: [PATCH 100/447] Rewrite effects checking chapter --- src/SUMMARY.md | 2 +- src/effects.md | 196 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 131 insertions(+), 67 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 91c4aeacb..b1423acd3 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -177,7 +177,7 @@ - [Inference details](./opaque-types-impl-trait-inference.md) - [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md) - [Region inference restrictions][opaque-infer] -- [Effect checking](./effects.md) +- [Const condition checking](./effects.md) - [Pattern and Exhaustiveness Checking](./pat-exhaustive-checking.md) - [Unsafety Checking](./unsafety-checking.md) - [MIR dataflow](./mir/dataflow.md) diff --git a/src/effects.md b/src/effects.md index 1fda7bcbb..c30a521f4 100644 --- a/src/effects.md +++ b/src/effects.md @@ -1,66 +1,130 @@ -# Effects and effect checking - -Note: all of this describes the implementation of the unstable `effects` and -`const_trait_impl` features. None of this implementation is usable or visible from -stable Rust. - -The implementation of const traits and `~const` bounds is a limited effect system. -It is used to allow trait bounds on `const fn` to be used within the `const fn` for -method calls. Within the function, in order to know whether a method on a trait -bound is `const`, we need to know whether there is a `~const` bound for the trait. -In order to know whether we can instantiate a `~const` bound on a `const fn`, we -need to know whether there is a `const_trait` impl for the type and trait being -used (or whether the `const fn` is used at runtime, then any type implementing the -trait is ok, just like with other bounds). - -We perform these checks via a const generic boolean that gets attached to all -`const fn` and `const trait`. The following sections will explain the desugarings -and the way we perform the checks at call sites. - -The const generic boolean is inverted to the meaning of `const`. In the compiler -it is called `host`, because it enables "host APIs" like `static` items, network -access, disk access, random numbers and everything else that isn't available in -`const` contexts. So `false` means "const", `true` means "not const" and if it's -a generic parameter, it means "maybe const" (meaning we're in a const fn or const -trait). - -## `const fn` - -All `const fn` have a `#[rustc_host] const host: bool` generic parameter that is -hidden from users. Any `~const Trait` bounds in the generics list or `where` bounds -of a `const fn` get converted to `Trait + Trait` bounds. The `Trait` -exists so that associated types of the generic param can be used from projections -like `::Assoc`, because there are no `` projections for now. - -## `#[const_trait] trait`s - -The `#[const_trait]` attribute gives the marked trait a `#[rustc_host] const host: bool` -generic parameter. All functions of the trait "inherit" this generic parameter, just like -they have all the regular generic parameters of the trait. Any `~const Trait` super-trait -bounds get desugared to `Trait + Trait` in order to allow using associated -types and consts of the super traits in the trait declaration. This is necessary, because -`::Assoc` is always `>::Assoc` as there is -no `` syntax. - -## `typeck` performing method and function call checks. - -When generic parameters are instantiated for any items, the `host` generic parameter -is always instantiated as an inference variable. This is a special kind of inference var -that is not part of the type or const inference variables, similar to how we have -special inference variables for type variables that we know to be an integer, but not -yet which one. These separate inference variables fall back to `true` at -the end of typeck (in `fallback_effects`) to ensure that `let _ = some_fn_item_name;` -will keep compiling. - -All actually used (in function calls, casts, or anywhere else) function items, will -have the `enforce_context_effects` method invoked. -It trivially returns if the function being called has no `host` generic parameter. - -In order to error if a non-const function is called in a const context, we have not -yet disabled the const-check logic that happens on MIR, because -`enforce_context_effects` does not yet perform this check. - -The function call's `host` parameter is then equated to the context's `host` value, -which almost always trivially succeeds, as it was an inference var. If the inference -var has already been bound (since the function item is invoked twice), the second -invocation checks it against the first. +# Effects and const condition checking + +## The `HostEffect` predicate + +[`HostEffectPredicate`]s are a kind of predicate from `~const Tr` or `const Tr` +bounds. It has a trait reference, and a `constness` which could be `Maybe` or +`Const` depending on the bound. Because `~const Tr`, or rather `Maybe` bounds +apply differently based on whichever contexts they are in, they have different +behavior than normal bounds. Where normal trait bounds on a function such as +`T: Tr` are collected within the [`predicates_of`] query to be proven when a +function is called and to be assumed within the function, bounds such as +`T: ~const Tr` will behave as a normal trait bound and add `T: Tr` to the result +from `predicates_of`, but also adds a `HostEffectPredicate` to the +[`const_conditions`] query. + +On the other hand, `T: const Tr` bounds do not change meaning across contexts, +therefore they will result in `HostEffect(T: Tr, const)` being added to +`predicates_of`, and not `const_conditions`. + +[`HostEffectPredicate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/predicate/struct.HostEffectPredicate.html +[`predicates_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.predicates_of +[`const_conditions`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.const_conditions + +## The `const_conditions` query + +`predicates_of` represents a set of predicates that need to be proven to use an +item. For example, to use `foo` in the example below: + +```rust +fn foo() where T: Default {} +``` + +We must be able to prove that `T` implements `Default`. In a similar vein, +`const_conditions` represents a set of predicates that need to be proven to use +an item *in const contexts*. If we adjust the example above to use `const` trait +bounds: + +```rust +const fn foo() where T: ~const Default {} +``` + +Then `foo` would get a `HostEffect(T: Default, maybe)` in the `const_conditions` +query, suggesting that in order to call `foo` from const contexts, one must +prove that `T` has a const implementation of `Default`. + +## Enforcement of `const_conditions` + +`const_conditions` are currently checked in various places. + +Every call in HIR from a const context (which includes `const fn` and `const` +items) will check that `const_conditions` of the function we are calling hold. +This is done in [`FnCtxt::enforce_context_effects`]. Note that we don't check +if the function is only referred to but not called, as the following code needs +to compile: + +```rust +const fn hi() -> T { + T::default() +} +const X: fn() -> u32 = hi::; +``` + +For a trait `impl` to be well-formed, we must be able to prove the +`const_conditions` of the trait from the `impl`'s environment. This is checked +in [`wfcheck::check_impl`]. + +Here's an example: + +```rust +#[const_trait] +trait Bar {} +#[const_trait] +trait Foo: ~const Bar {} +// `const_conditions` contains `HostEffect(Self: Bar, maybe)` + +impl const Bar for () {} +impl const Foo for () {} +// ^ here we check `const_conditions` for the impl to be well-formed +``` + +Methods of trait impls must not have stricter bounds than the method of the +trait that they are implementing. To check that the methods are compatible, a +hybrid environment is constructed with the predicates of the `impl` plus the +predicates of the trait method, and we attempt to prove the predicates of the +impl method. We do the same for `const_conditions`: + +```rust +#[const_trait] +trait Foo { + fn hi(); +} + +impl Foo for Vec { + fn hi(); + // ^ we can't prove `T: ~const PartialEq` given `T: ~const Clone` and + // `T: ~const Default`, therefore we know that the method on the impl + // is stricter than the method on the trait. +} +``` + +These checks are done in [`compare_method_predicate_entailment`]. A similar +function that does the same check for associated types is called +[`compare_type_predicate_entailment`]. Both of these need to consider +`const_conditions` when in const contexts. + +In MIR, as part of const checking, `const_conditions` of items that are called +are revalidated again in [`Checker::revalidate_conditional_constness`]. + +[`compare_method_predicate_entailment`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html +[`compare_type_predicate_entailment`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_type_predicate_entailment.html +[`FnCtxt::enforce_context_effects`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#method.enforce_context_effects +[`wfcheck::check_impl`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/wfcheck/fn.check_impl.html +[`Checker::revalidate_conditional_constness`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/check_consts/check/struct.Checker.html#method.revalidate_conditional_constness + +## Proving `HostEffectPredicate`s + +`HostEffectPredicate`s are implemented both in the [old solver] and the [new +trait solver]. In general, we can prove a `HostEffect` predicate when either of +these conditions are met: + +* The predicate can be assumed from caller bounds; +* The type has a `const` `impl` for the trait, *and* that const conditions on +the impl holds; or +* The type has a built-in implementation for the trait in const contexts. For +example, `Fn` may be implemented by function items if their const conditions +are satisfied, or `Destruct` is implemented in const contexts if the type can +be dropped at compile time. + +[old solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_trait_selection/traits/effects.rs.html +[new trait solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_next_trait_solver/solve/effect_goals.rs.html From a55bd19ca71f72f660bb94c0ed53224bb35e2d41 Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 23 Feb 2025 22:07:09 -0500 Subject: [PATCH 101/447] document how to setup RA for nvim automatically --- src/building/suggested.md | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/building/suggested.md b/src/building/suggested.md index 2c6c3fe1d..77c9dc6e4 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -120,10 +120,35 @@ create a `.vim/coc-settings.json`. The settings can be edited with [`src/etc/rust_analyzer_settings.json`]. Another way is without a plugin, and creating your own logic in your -configuration. To do this you must translate the JSON to Lua yourself. The -translation is 1:1 and fairly straight-forward. It must be put in the -`["rust-analyzer"]` key of the setup table, which is [shown -here](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#rust_analyzer). +configuration. The following code will work for any checkout of rust-lang/rust (newer than Febuary 2025): + +```lua +lspconfig.rust_analyzer.setup { + root_dir = function() + default = lspconfig.rust_analyzer.config_def.default_config.root_dir() + -- the default root detection uses the cargo workspace root. + -- but for rust-lang/rust, the standard library is in its own workspace. + -- use the git root instead. + compiler_config = vim.fs.joinpath(default, "../src/bootstrap/defaults/config.compiler.toml") + if vim.fs.basename(default) == "library" and vim.uv.fs_stat(compiler_config) then + return vim.fs.dirname(default) + end + return default + end, + on_init = function(client) + local path = client.workspace_folders[1].name + config = vim.fs.joinpath(path, "src/etc/rust_analyzer_zed.json") + if vim.uv.fs_stat(config) then + -- load rust-lang/rust settings + file = io.open(config) + json = vim.json.decode(file:read("*a")) + client.config.settings["rust-analyzer"] = json.lsp["rust-analyzer"].initialization_options + client.notify("workspace/didChangeConfiguration", { settings = client.config.settings }) + end + return true + end +} +``` If you would like to use the build task that is described above, you may either make your own command in your config, or you can install a plugin such as From c5b75dc7bd0f5ee2b07590b7c1924eac3d0f9507 Mon Sep 17 00:00:00 2001 From: jyn Date: Mon, 24 Feb 2025 00:12:55 -0500 Subject: [PATCH 102/447] use lua locals Co-authored-by: DianQK --- src/building/suggested.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/building/suggested.md b/src/building/suggested.md index 77c9dc6e4..e2d50b31d 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -125,11 +125,11 @@ configuration. The following code will work for any checkout of rust-lang/rust ( ```lua lspconfig.rust_analyzer.setup { root_dir = function() - default = lspconfig.rust_analyzer.config_def.default_config.root_dir() + local default = lspconfig.rust_analyzer.config_def.default_config.root_dir() -- the default root detection uses the cargo workspace root. -- but for rust-lang/rust, the standard library is in its own workspace. -- use the git root instead. - compiler_config = vim.fs.joinpath(default, "../src/bootstrap/defaults/config.compiler.toml") + local compiler_config = vim.fs.joinpath(default, "../src/bootstrap/defaults/config.compiler.toml") if vim.fs.basename(default) == "library" and vim.uv.fs_stat(compiler_config) then return vim.fs.dirname(default) end @@ -137,11 +137,11 @@ lspconfig.rust_analyzer.setup { end, on_init = function(client) local path = client.workspace_folders[1].name - config = vim.fs.joinpath(path, "src/etc/rust_analyzer_zed.json") + local config = vim.fs.joinpath(path, "src/etc/rust_analyzer_zed.json") if vim.uv.fs_stat(config) then -- load rust-lang/rust settings - file = io.open(config) - json = vim.json.decode(file:read("*a")) + local file = io.open(config) + local json = vim.json.decode(file:read("*a")) client.config.settings["rust-analyzer"] = json.lsp["rust-analyzer"].initialization_options client.notify("workspace/didChangeConfiguration", { settings = client.config.settings }) end From 52f86c7219ae34d875c81ad3cb95b30b20684e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 25 Feb 2025 18:56:14 +0100 Subject: [PATCH 103/447] Fix posting message to Zulip --- .github/workflows/rustc-pull.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index dc5395a19..b19eccf9e 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -111,4 +111,4 @@ jobs: to: 196385 type: "stream" topic: "Subtree sync automation" - content: ${{ steps.message.outputs.message }} + content: ${{ steps.create-message.outputs.message }} From 5bda7ef853bcbca5568db450be56418a8973c640 Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 25 Feb 2025 21:22:45 +0000 Subject: [PATCH 104/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 78e9ecdf1..ce21bb8ef 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -124cc92199ffa924f6b4c7cc819a85b65e0c3984 +4ecd70ddd1039a3954056c1071e40278048476fa From 8044303cbfaca1ca145bb8002d478af970e0835a Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Sat, 18 Jan 2025 18:19:42 +0100 Subject: [PATCH 105/447] Support raw-dylib link kind on ELF raw-dylib is a link kind that allows rustc to link against a library without having any library files present. This currently only exists on Windows. rustc will take all the symbols from raw-dylib link blocks and put them in an import library, where they can then be resolved by the linker. While import libraries don't exist on ELF, it would still be convenient to have this same functionality. Not having the libraries present at build-time can be convenient for several reasons, especially cross-compilation. With raw-dylib, code linking against a library can be cross-compiled without needing to have these libraries available on the build machine. If the libc crate makes use of this, it would allow cross-compilation without having any libc available on the build machine. This is not yet possible with this implementation, at least against libc's like glibc that use symbol versioning. The raw-dylib kind could be extended with support for symbol versioning in the future. This implementation is very experimental and I have not tested it very well. I have tested it for a toy example and the lz4-sys crate, where it was able to successfully link a binary despite not having a corresponding library at build-time. --- src/tests/directives.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/directives.md b/src/tests/directives.md index 00bb2bc4d..af9cb85d2 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -142,6 +142,7 @@ Some examples of `X` in `ignore-X` or `only-X`: matches that target as well as the emscripten targets. - Pointer width: `32bit`, `64bit` - Endianness: `endian-big` +- Binary format: `elf` - Stage: `stage0`, `stage1`, `stage2` - Channel: `stable`, `beta` - When cross compiling: `cross-compile` From 6a61f6f721c0e1999a04ac0f7a3f37af5a47eb34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:40:57 +0800 Subject: [PATCH 106/447] rustc-dev-guide: remove mentions of legacy `Makefile` run-make infra And remove outdated requirements to run `run-make` tests on Windows. --- src/tests/compiletest.md | 30 +----------------------------- src/tests/directives.md | 7 +------ src/tests/running.md | 25 ------------------------- 3 files changed, 2 insertions(+), 60 deletions(-) diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index 459c08290..2905e470f 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -74,8 +74,7 @@ The following test suites are available, with links for more information: ### General purpose test suite -[`run-make`](#run-make-tests) are general purpose tests using Rust programs (or -Makefiles (legacy)). +[`run-make`](#run-make-tests) are general purpose tests using Rust programs. ### Rustdoc test suites @@ -396,14 +395,6 @@ your test, causing separate files to be generated for 32bit and 64bit systems. ### `run-make` tests -> **Note on phasing out `Makefile`s** -> -> We are planning to migrate all existing Makefile-based `run-make` tests -> to Rust programs. You should not be adding new Makefile-based `run-make` -> tests. -> -> See . - The tests in [`tests/run-make`] are general-purpose tests using Rust *recipes*, which are small programs (`rmake.rs`) allowing arbitrary Rust code such as `rustc` invocations, and is supported by a [`run_make_support`] library. Using @@ -424,11 +415,6 @@ Compiletest directives like `//@ only-` or `//@ ignore-` are supported in `rmake.rs`, like in UI tests. However, revisions or building auxiliary via directives are not currently supported. -Two `run-make` tests are ported over to Rust recipes as examples: - -- -- - #### Quickly check if `rmake.rs` tests can be compiled You can quickly check if `rmake.rs` tests can be compiled without having to @@ -481,20 +467,6 @@ Then add a corresponding entry to `"rust-analyzer.linkedProjects"` ], ``` -#### Using Makefiles (legacy) - -

- -Each test should be in a separate directory with a `Makefile` indicating the -commands to run. - -There is a [`tools.mk`] Makefile which you can include which provides a bunch of -utilities to make it easier to run commands and compare outputs. Take a look at -some of the other tests for some examples on how to get started. - -[`tools.mk`]: https://github.com/rust-lang/rust/blob/master/tests/run-make/tools.mk [`tests/run-make`]: https://github.com/rust-lang/rust/tree/master/tests/run-make [`run_make_support`]: https://github.com/rust-lang/rust/tree/master/src/tools/run-make-support diff --git a/src/tests/directives.md b/src/tests/directives.md index 00bb2bc4d..c72c7d7d8 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -6,10 +6,7 @@ FIXME(jieyouxu) completely revise this chapter. --> -Directives are special comments that tell compiletest how to build and interpret -a test. They must appear before the Rust source in the test. They may also -appear in `rmake.rs` or legacy Makefiles for [run-make -tests](compiletest.md#run-make-tests). +Directives are special comments that tell compiletest how to build and interpret a test. They must appear before the Rust source in the test. They may also appear in `rmake.rs` [run-make tests](compiletest.md#run-make-tests). They are normally put after the short comment that explains the point of this test. Compiletest test suites use `//@` to signal that a comment is a directive. @@ -221,8 +218,6 @@ The following directives will check LLVM support: [`aarch64-gnu-debug`]), which only runs a subset of `run-make` tests. Other tests with this directive will not run at all, which is usually not what you want. - - Notably, the [`aarch64-gnu-debug`] CI job *currently* only runs `run-make` - tests which additionally contain `clang` in their test name. See also [Debuginfo tests](compiletest.md#debuginfo-tests) for directives for ignoring debuggers. diff --git a/src/tests/running.md b/src/tests/running.md index 6ce650923..9ddf0afee 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -238,30 +238,6 @@ This is much faster, but doesn't always work. For example, some tests include directives that specify specific compiler flags, or which rely on other crates, and they may not run the same without those options. -## Running `run-make` tests - -### Windows - -Running the `run-make` test suite on Windows is a currently bit more involved. -There are numerous prerequisites and environmental requirements: - -- Install msys2: -- Specify `MSYS2_PATH_TYPE=inherit` in `msys2.ini` in the msys2 installation directory, run the - following with `MSYS2 MSYS`: - - `pacman -Syuu` - - `pacman -S make` - - `pacman -S diffutils` - - `pacman -S binutils` - - `./x test run-make` (`./x test tests/run-make` doesn't work) - -There is [on-going work][port-run-make] to not rely on `Makefile`s in the -run-make test suite. Once this work is completed, you can run the entire -`run-make` test suite on native Windows inside `cmd` or `PowerShell` without -needing to install and use MSYS2. As of Oct 2024, it is -already possible to run the vast majority of the `run-make` test suite outside -of MSYS2, but there will be failures for the tests that still use `Makefile`s -due to not finding `make`. - ## Running tests on a remote machine Tests may be run on a remote machine (e.g. to test builds for a different @@ -406,4 +382,3 @@ If you encounter bugs or problems, don't hesitate to open issues on the repository](https://github.com/rust-lang/rustc_codegen_gcc/). [`tests/ui`]: https://github.com/rust-lang/rust/tree/master/tests/ui -[port-run-make]: https://github.com/rust-lang/rust/issues/121876 From 4801165af51ba8fde444d0821002b6e99f3e4a9a Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 3 Mar 2025 20:17:26 +1100 Subject: [PATCH 107/447] Remove some unnecessary aliases from `rustc_data_structures::sync` With the removal of `cfg(parallel_compiler)`, these are always shared references and `std::sync::OnceLock`. --- src/parallel-rustc.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/parallel-rustc.md b/src/parallel-rustc.md index c5b70706a..690fb19c9 100644 --- a/src/parallel-rustc.md +++ b/src/parallel-rustc.md @@ -46,10 +46,8 @@ are implemented differently depending on whether `parallel-compiler` is true. | data structure | parallel | non-parallel | | -------------------------------- | --------------------------------------------------- | ------------ | -| OnceCell | std::sync::OnceLock | std::cell::OnceCell | | Lock\ | (parking_lot::Mutex\) | (std::cell::RefCell) | | RwLock\ | (parking_lot::RwLock\) | (std::cell::RefCell) | -| MTRef<'a, T> | &'a T | &'a mut T | | MTLock\ | (Lock\) | (T) | | ReadGuard | parking_lot::RwLockReadGuard | std::cell::Ref | | MappedReadGuard | parking_lot::MappedRwLockReadGuard | std::cell::Ref | From aab48065ca644fe6a780872514db7f819e51a4e7 Mon Sep 17 00:00:00 2001 From: moxian Date: Wed, 5 Mar 2025 15:28:06 -0800 Subject: [PATCH 108/447] Don't suggest explicitly `cfg`-gating `trace!` calls in bootstrap --- src/building/bootstrapping/debugging-bootstrap.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/building/bootstrapping/debugging-bootstrap.md b/src/building/bootstrapping/debugging-bootstrap.md index 24b9783dd..35d33ebdb 100644 --- a/src/building/bootstrapping/debugging-bootstrap.md +++ b/src/building/bootstrapping/debugging-bootstrap.md @@ -129,7 +129,7 @@ Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need ```rs #[cfg(feature = "tracing")] -use tracing::{instrument, trace}; +use tracing::instrument; struct Foo; @@ -138,7 +138,6 @@ impl Step for Foo { #[cfg_attr(feature = "tracing", instrument(level = "trace", name = "Foo::should_run", skip_all))] fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - #[cfg(feature = "tracing")] trace!(?run, "entered Foo::should_run"); todo!() @@ -154,7 +153,6 @@ impl Step for Foo { ), )] fn run(self, builder: &Builder<'_>) -> Self::Output { - #[cfg(feature = "tracing")] trace!(?run, "entered Foo::run"); todo!() From 93eca2b4945a7e03cf5833bb432882e12f8fe758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 24 Feb 2025 20:14:25 +0800 Subject: [PATCH 109/447] Document that `rmake.rs`/`run-make-support` may not use unstable features --- src/tests/compiletest.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index 2905e470f..a6996e398 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -415,6 +415,10 @@ Compiletest directives like `//@ only-` or `//@ ignore-` are supported in `rmake.rs`, like in UI tests. However, revisions or building auxiliary via directives are not currently supported. +`rmake.rs` and `run-make-support` may *not* use any nightly/unstable features, +as they must be compilable by a stage 0 rustc that may be a beta or even stable +rustc. + #### Quickly check if `rmake.rs` tests can be compiled You can quickly check if `rmake.rs` tests can be compiled without having to From 79e42cfb0bbc7eb6062149c657f6f0ed0ef18438 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 8 Mar 2025 16:38:44 +0800 Subject: [PATCH 110/447] consider `explicit_implied_const_bounds` --- src/effects.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/effects.md b/src/effects.md index c30a521f4..c7aa27146 100644 --- a/src/effects.md +++ b/src/effects.md @@ -112,6 +112,34 @@ are revalidated again in [`Checker::revalidate_conditional_constness`]. [`wfcheck::check_impl`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/wfcheck/fn.check_impl.html [`Checker::revalidate_conditional_constness`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/check_consts/check/struct.Checker.html#method.revalidate_conditional_constness +## `explicit_implied_const_bounds` on associated types and traits + +Bounds on associated types, opaque types, and supertraits such as +```rust +trait Foo: ~const PartialEq { + type X: ~const PartialEq; +} + +fn foo() -> impl ~const PartialEq { + // ^ unimplemented syntax +} +``` + +Have their bounds represented differently. Unlike `const_conditions` which need +to be proved for callers, and can be assumed inside the definition (e.g. trait +bounds on functions), these bounds need to be proved at definition (at the impl, +or when returning the opaque) but can be assumed for callers. The non-const +equivalent of these bounds are called [`explicit_item_bounds`]. + +These bounds are checked in [`compare_impl_item::check_type_bounds`] for HIR +typeck, [`evaluate_host_effect_from_item_bounds`] in the old solver and +[`consider_additional_alias_assumptions`] in the new solver. + +[`explicit_item_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.explicit_item_bounds +[`compare_impl_item::check_type_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.check_type_bounds.html +[`evaluate_host_effect_from_item_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/effects/fn.evaluate_host_effect_from_item_bounds.html +[`consider_additional_alias_assumptions`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/assembly/trait.GoalKind.html#tymethod.consider_additional_alias_assumptions + ## Proving `HostEffectPredicate`s `HostEffectPredicate`s are implemented both in the [old solver] and the [new @@ -120,7 +148,8 @@ these conditions are met: * The predicate can be assumed from caller bounds; * The type has a `const` `impl` for the trait, *and* that const conditions on -the impl holds; or +the impl holds, *and* that the `explicit_implied_const_bounds` on the trait +holds; or * The type has a built-in implementation for the trait in const contexts. For example, `Fn` may be implemented by function items if their const conditions are satisfied, or `Destruct` is implemented in const contexts if the type can From 723b887eff068e08cfdaececd8fb573a90b2a92e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 8 Mar 2025 20:33:05 +0200 Subject: [PATCH 111/447] numbers were not sequential, so stop trying --- src/backend/updating-llvm.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/backend/updating-llvm.md b/src/backend/updating-llvm.md index 92d4ce32f..bc8207bb4 100644 --- a/src/backend/updating-llvm.md +++ b/src/backend/updating-llvm.md @@ -116,14 +116,14 @@ so let's go through each in detail. at the time of the branch, and the remaining part is the current date. -2. Apply Rust-specific patches to the llvm-project repository. +1. Apply Rust-specific patches to the llvm-project repository. All features and bugfixes are upstream, but there's often some weird build-related patches that don't make sense to upstream. These patches are typically the latest patches in the rust-lang/llvm-project branch that rustc is currently using. -3. Build the new LLVM in the `rust` repository. +1. Build the new LLVM in the `rust` repository. To do this, you'll want to update the `src/llvm-project` repository to your branch, and the revision you've created. @@ -151,7 +151,7 @@ so let's go through each in detail. download-ci-llvm = false ``` -4. Test for regressions across other platforms. LLVM often has at least one bug +1. Test for regressions across other platforms. LLVM often has at least one bug for non-tier-1 architectures, so it's good to do some more testing before sending this to bors! If you're low on resources you can send the PR as-is now to bors, though, and it'll get tested anyway. @@ -170,7 +170,7 @@ so let's go through each in detail. * `./src/ci/docker/run.sh dist-various-2` * `./src/ci/docker/run.sh armhf-gnu` -5. Prepare a PR to `rust-lang/rust`. Work with maintainers of +1. Prepare a PR to `rust-lang/rust`. Work with maintainers of `rust-lang/llvm-project` to get your commit in a branch of that repository, and then you can send a PR to `rust-lang/rust`. You'll change at least `src/llvm-project` and will likely also change [`llvm-wrapper`] as well. @@ -194,7 +194,7 @@ so let's go through each in detail. others interested in trying out the new LLVM can benefit from work you've done to update the C++ bindings. -3. Over the next few months, +1. Over the next few months, LLVM will continually push commits to its `release/a.b` branch. We will often want to have those bug fixes as well. The merge process for that is to use `git merge` itself to merge LLVM's @@ -202,9 +202,9 @@ so let's go through each in detail. This is typically done multiple times when necessary while LLVM's release branch is baking. -4. LLVM then announces the release of version `a.b`. +1. LLVM then announces the release of version `a.b`. -5. After LLVM's official release, +1. After LLVM's official release, we follow the process of creating a new branch on the rust-lang/llvm-project repository again, this time with a new date. From fc6a11aeb4af722a78574783457393e6f0ed1e7b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 8 Mar 2025 20:35:42 +0200 Subject: [PATCH 112/447] only a few are needed as examples --- src/backend/updating-llvm.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/backend/updating-llvm.md b/src/backend/updating-llvm.md index bc8207bb4..be5fed9cf 100644 --- a/src/backend/updating-llvm.md +++ b/src/backend/updating-llvm.md @@ -177,12 +177,6 @@ so let's go through each in detail. > For prior art, here are some previous LLVM updates: - > - [LLVM 11](https://github.com/rust-lang/rust/pull/73526) - > - [LLVM 12](https://github.com/rust-lang/rust/pull/81451) - > - [LLVM 13](https://github.com/rust-lang/rust/pull/87570) - > - [LLVM 14](https://github.com/rust-lang/rust/pull/93577) - > - [LLVM 15](https://github.com/rust-lang/rust/pull/99464) - > - [LLVM 16](https://github.com/rust-lang/rust/pull/109474) > - [LLVM 17](https://github.com/rust-lang/rust/pull/115959) > - [LLVM 18](https://github.com/rust-lang/rust/pull/120055) > - [LLVM 19](https://github.com/rust-lang/rust/pull/127513) From ebead304f40a4bdc5e86e5d21c46ce7554db37f8 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 8 Mar 2025 20:40:44 +0200 Subject: [PATCH 113/447] link to latest major llvm update pr --- src/backend/updating-llvm.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/updating-llvm.md b/src/backend/updating-llvm.md index be5fed9cf..0b45956b1 100644 --- a/src/backend/updating-llvm.md +++ b/src/backend/updating-llvm.md @@ -175,11 +175,12 @@ so let's go through each in detail. and then you can send a PR to `rust-lang/rust`. You'll change at least `src/llvm-project` and will likely also change [`llvm-wrapper`] as well. - + > For prior art, here are some previous LLVM updates: > - [LLVM 17](https://github.com/rust-lang/rust/pull/115959) > - [LLVM 18](https://github.com/rust-lang/rust/pull/120055) > - [LLVM 19](https://github.com/rust-lang/rust/pull/127513) + > - [LLVM 20](https://github.com/rust-lang/rust/pull/135763) Note that sometimes it's easiest to land [`llvm-wrapper`] compatibility as a PR before actually updating `src/llvm-project`. From 28b1ec713082f5cc3cfaa3fe9f0f0336547d64b4 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 8 Mar 2025 22:58:09 +0200 Subject: [PATCH 114/447] fix text - There is more than just target and stage - There is only 3 stages, so don't mention them specially --- src/tests/directives.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 00bb2bc4d..934f79851 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -122,8 +122,7 @@ for more details. These directives are used to ignore the test in some situations, which means the test won't be compiled or run. -* `ignore-X` where `X` is a target detail or stage will ignore the test - accordingly (see below) +* `ignore-X` where `X` is a target detail or other criteria on which to ignore the test (see below) * `only-X` is like `ignore-X`, but will *only* run the test on that target or stage * `ignore-test` always ignores the test. This can be used to temporarily disable From efa11d0d5c58776351b739b2814910ea04c9c3dc Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 8 Mar 2025 23:51:17 +0200 Subject: [PATCH 115/447] ignore-stage0 and only-stage0 do not exist --- src/tests/directives.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 00bb2bc4d..078efc272 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -142,7 +142,7 @@ Some examples of `X` in `ignore-X` or `only-X`: matches that target as well as the emscripten targets. - Pointer width: `32bit`, `64bit` - Endianness: `endian-big` -- Stage: `stage0`, `stage1`, `stage2` +- Stage: `stage1`, `stage2` - Channel: `stable`, `beta` - When cross compiling: `cross-compile` - When [remote testing] is used: `remote` From 1d3b59fa4aedd6ab4b2df4ade0a2da9ca7d8a4ac Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 10 Mar 2025 10:29:30 +0200 Subject: [PATCH 116/447] use new terminology --- src/tests/running.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/running.md b/src/tests/running.md index 6ce650923..58564bc4f 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -24,8 +24,8 @@ collection. The test results are cached and previously successful tests are `ignored` during testing. The stdout/stderr contents as well as a timestamp file for every test -can be found under `build//test/` for the given -``. To force-rerun a test (e.g. in case the test runner fails to +can be found under `build//test/` for the given +``. To force-rerun a test (e.g. in case the test runner fails to notice a change) you can use the `--force-rerun` CLI option. > **Note on requirements of external dependencies** From 20b3dc1ee009a58c3a2c4fc485eadb7bc2e28b0e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 10 Mar 2025 10:35:40 +0200 Subject: [PATCH 117/447] already mentioned before showing code snippet --- src/tests/running.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/running.md b/src/tests/running.md index 6ce650923..16cf8dad3 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -49,7 +49,7 @@ test suite ([`tests/ui`]): ./x test tests/ui ``` -This will run the `ui` test suite. Of course, the choice of test suites is +Of course, the choice of test suites is somewhat arbitrary, and may not suit the task you are doing. For example, if you are hacking on debuginfo, you may be better off with the debuginfo test suite: From 916cd09d33dc7766566ff13d7c824b76a78796d4 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 10 Mar 2025 10:38:30 +0200 Subject: [PATCH 118/447] add a pause, for readability --- src/tests/running.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/running.md b/src/tests/running.md index 16cf8dad3..05a565791 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -112,8 +112,8 @@ crates, you have to specify those explicitly. ./x test --stage 1 library/std ``` -By listing which test suites you want to run you avoid having to run tests for -components you did not change at all. +By listing which test suites you want to run, +you avoid having to run tests for components you did not change at all.
Note that bors only runs the tests with the full stage 2 build; therefore, while From 12b836b37c3c181a9429984c05b14eea252d3740 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 10 Mar 2025 11:12:44 +0200 Subject: [PATCH 119/447] clean --bless text --- src/tests/running.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tests/running.md b/src/tests/running.md index 05a565791..eb763215a 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -172,16 +172,18 @@ additional arguments to the compiler when building the tests. ## Editing and updating the reference files If you have changed the compiler's output intentionally, or you are making a new -test, you can pass `--bless` to the test subcommand. E.g. if some tests in -`tests/ui` are failing, you can run +test, you can pass `--bless` to the test subcommand. + +As an example, +if some tests in `tests/ui` are failing, you can run this command: ```text ./x test tests/ui --bless ``` -to automatically adjust the `.stderr`, `.stdout` or `.fixed` files of -all tests. Of course you can also target just specific tests with the -`--test-args your_test_name` flag, just like when running the tests. +It automatically adjusts the `.stderr`, `.stdout`, or `.fixed` files of all `test/ui` tests. +Of course you can also target just specific tests with the `--test-args your_test_name` flag, +just like when running the tests without the `--bless` flag. ## Configuring test running From 53f8a2f1d6a626f28678a7edaebbf1c41f278285 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 10 Mar 2025 11:15:32 +0200 Subject: [PATCH 120/447] add missing punctuation --- src/tests/running.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/running.md b/src/tests/running.md index eb763215a..35deec4b4 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -192,7 +192,7 @@ There are a few options for running tests: * `config.toml` has the `rust.verbose-tests` option. If `false`, each test will print a single dot (the default). If `true`, the name of every test will be printed. This is equivalent to the `--quiet` option in the [Rust test - harness](https://doc.rust-lang.org/rustc/tests/) + harness](https://doc.rust-lang.org/rustc/tests/). * The environment variable `RUST_TEST_THREADS` can be set to the number of concurrent threads to use for testing. From 074e4787bdb0d8fd76398fb87dfc6f34746ab4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 10 Mar 2025 13:35:50 +0100 Subject: [PATCH 121/447] Modify try-job documentation --- src/tests/ci.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/tests/ci.md b/src/tests/ci.md index ae6adb678..7fd4c1697 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -134,15 +134,17 @@ There are several use-cases for try builds: the [dist-x86_64-linux] CI job. - Run a specific CI job (e.g. Windows tests) on a PR, to quickly test if it passes the test suite executed by that job. You can select which CI jobs will - be executed in the try build by adding up to 10 lines containing `try-job: - ` to the PR description. All such specified jobs will be executed + be executed in the try build by adding lines containing `try-job: + ` to the PR description. All such specified jobs will be executed in the try build once the `@bors try` command is used on the PR. If no try jobs are specified in this way, the jobs defined in the `try` section of - [`jobs.yml`] will be executed by default. + [`jobs.yml`] will be executed by default. Each pattern can either be an exact + name of a job or a glob pattern that matches multiple jobs, for example + `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. > **Using `try-job` PR description directives** > -> 1. Identify which set of try-jobs (max 10) you would like to exercise. You can +> 1. Identify which set of try-jobs you would like to exercise. You can > find the name of the CI jobs in [`jobs.yml`]. > > 2. Amend PR description to include (usually at the end of the PR description) @@ -153,9 +155,10 @@ There are several use-cases for try builds: > > try-job: x86_64-msvc > try-job: test-various +> try-job: *-alt > ``` > -> Each `try-job` directive must be on its own line. +> Each `try-job` pattern must be on its own line. > > 3. Run the prescribed try jobs with `@bors try`. As aforementioned, this > requires the user to either (1) have `try` permissions or (2) be delegated From dd0359476d06336734803e1c081b17a507147708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 10 Mar 2025 13:56:42 +0100 Subject: [PATCH 122/447] Handle backticks in try job patterns --- src/tests/ci.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/tests/ci.md b/src/tests/ci.md index 7fd4c1697..0c0f750a4 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -133,29 +133,34 @@ There are several use-cases for try builds: Again, a working compiler build is needed for this, which can be produced by the [dist-x86_64-linux] CI job. - Run a specific CI job (e.g. Windows tests) on a PR, to quickly test if it - passes the test suite executed by that job. You can select which CI jobs will - be executed in the try build by adding lines containing `try-job: - ` to the PR description. All such specified jobs will be executed - in the try build once the `@bors try` command is used on the PR. If no try - jobs are specified in this way, the jobs defined in the `try` section of - [`jobs.yml`] will be executed by default. Each pattern can either be an exact - name of a job or a glob pattern that matches multiple jobs, for example - `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. + passes the test suite executed by that job. + +You can select which CI jobs will +be executed in the try build by adding lines containing `try-job: +` to the PR description. All such specified jobs will be executed +in the try build once the `@bors try` command is used on the PR. If no try +jobs are specified in this way, the jobs defined in the `try` section of +[`jobs.yml`] will be executed by default. + +Each pattern can either be an exact name of a job or a glob pattern that matches multiple jobs, +for example `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. When using +glob patterns, you might want to wrap them in backticks (`` ` ``) to avoid GitHub rendering +the pattern as Markdown. > **Using `try-job` PR description directives** > > 1. Identify which set of try-jobs you would like to exercise. You can > find the name of the CI jobs in [`jobs.yml`]. > -> 2. Amend PR description to include (usually at the end of the PR description) -> e.g. +> 2. Amend PR description to include a set of patterns (usually at the end +> of the PR description), for example: > > ```text > This PR fixes #123456. > > try-job: x86_64-msvc > try-job: test-various -> try-job: *-alt +> try-job: `*-alt` > ``` > > Each `try-job` pattern must be on its own line. From 7f5b5c36f82be0ff0e270f648adc90f3042b5c2a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 21 Feb 2025 18:33:05 +1100 Subject: [PATCH 123/447] Move methods from `Map` to `TyCtxt`, part 4. Continuing the work from #137350. Removes the unused methods: `expect_variant`, `expect_field`, `expect_foreign_item`. Every method gains a `hir_` prefix. --- src/hir.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hir.md b/src/hir.md index 51893d537..75f5a9e20 100644 --- a/src/hir.md +++ b/src/hir.md @@ -139,12 +139,12 @@ defined in the map. By matching on this, you can find out what sort of node the `HirId` referred to and also get a pointer to the data itself. Often, you know what sort of node `n` is – e.g. if you know that `n` must be some HIR expression, you can do -[`tcx.hir().expect_expr(n)`][expect_expr], which will extract and return the +[`tcx.hir_expect_expr(n)`][expect_expr], which will extract and return the [`&hir::Expr`][Expr], panicking if `n` is not in fact an expression. [find]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.find [`Node`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html -[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.expect_expr +[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.expect_expr [Expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Expr.html Finally, you can use the HIR map to find the parents of nodes, via From bbcfc6902791892d0427b3d16871a08a521e04c3 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 13 Mar 2025 03:51:51 +0200 Subject: [PATCH 124/447] less text for same effect --- src/building/new-target.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/building/new-target.md b/src/building/new-target.md index cd215277e..14d10d4a5 100644 --- a/src/building/new-target.md +++ b/src/building/new-target.md @@ -4,12 +4,11 @@ These are a set of steps to add support for a new target. There are numerous end states and paths to get there, so not all sections may be relevant to your desired goal. -See also the associated documentation in the -[target tier policy][target_tier_policy_add]. +See also the associated documentation in the [target tier policy]. -[target_tier_policy_add]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target +[target tier policy]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target ## Specifying a new LLVM From 2aa579f75233f3e63e3ffa8ee51ab5a362e93f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Thu, 13 Mar 2025 15:19:22 +0800 Subject: [PATCH 125/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index ce21bb8ef..eb779d9ab 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -4ecd70ddd1039a3954056c1071e40278048476fa +8536f201ffdb2c24925d7f9e87996d7dca93428b From 589573c793a440c8830dfe54892e216430843130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Thu, 13 Mar 2025 15:14:59 +0800 Subject: [PATCH 126/447] Document `fetch.prunetags = true` gotcha during rustc-pull --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 2464ffbbc..6a25a91f5 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ cargo +stable install josh-proxy --git https://github.com/josh-project/josh --ta Older versions of `josh-proxy` may not round trip commits losslessly so it is important to install this exact version. ### Pull changes from `rust-lang/rust` into this repository + 1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide` 2) Run the pull command ``` @@ -95,3 +96,15 @@ Older versions of `josh-proxy` may not round trip commits losslessly so it is im $ cargo run --manifest-path josh-sync/Cargo.toml rustc-push ``` 2) Create a PR from `` into `rust-lang/rust` + +#### Minimal git config + +For simplicity (ease of implementation purposes), the josh-sync script simply calls out to system git. This means that the git invocation may be influenced by global (or local) git configuration. + +You may observe "Nothing to pull" even if you *know* rustc-pull has something to pull if your global git config sets `fetch.prunetags = true` (and possibly other configurations may cause unexpected outcomes). + +To minimize the likelihood of this happening, you may wish to keep a separate *minimal* git config that *only* has `[user]` entries from global git config, then repoint system git to use the minimal git config instead. E.g. + +``` +$ GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo +stable run --manifest-path josh-sync/Cargo.toml -- rustc-pull +``` From 46d4f952c7e3ca2a6b8a237d96d836588919fa04 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 13 Mar 2025 12:15:29 -0700 Subject: [PATCH 127/447] Remove the doc for `no-system-llvm` This compiletest directive was removed in rust-lang/rust#120265. --- src/tests/directives.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 7f50cd23a..bbebd5d91 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -197,7 +197,6 @@ settings: The following directives will check LLVM support: -- `no-system-llvm` — ignores if the system llvm is used - `exact-llvm-major-version: 19` — ignores if the llvm major version does not match the specified llvm major version. - `min-llvm-version: 13.0` — ignored if the LLVM version is less than the given From c20c046b0f346cd6f722e3d42fc6419660576852 Mon Sep 17 00:00:00 2001 From: KonaeAkira Date: Thu, 13 Mar 2025 23:56:04 +0100 Subject: [PATCH 128/447] Fix grammar and remove redundant info --- src/solve/trait-solving.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/solve/trait-solving.md b/src/solve/trait-solving.md index 345ee0b09..c1eb1a94b 100644 --- a/src/solve/trait-solving.md +++ b/src/solve/trait-solving.md @@ -2,8 +2,7 @@ This chapter describes how trait solving works with the new WIP solver located in [`rustc_trait_selection/solve`][solve]. Feel free to also look at the docs for -[the current solver](../traits/resolution.md) and [the chalk solver](../traits/chalk.md) -can be found separately. +[the current solver](../traits/resolution.md) and [the chalk solver](../traits/chalk.md). ## Core concepts From dad3718db833ee4fd2df3e5e21774045b1860c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 14 Mar 2025 15:18:58 +0100 Subject: [PATCH 129/447] Fix MCP links --- src/contributing.md | 2 +- src/implementing_new_features.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/contributing.md b/src/contributing.md index 9817326f0..09a7f912b 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -81,7 +81,7 @@ smaller user-facing changes. into a PR that ends up not getting merged!** [See this document][mcpinfo] for more info on MCPs. -[mcpinfo]: https://forge.rust-lang.org/compiler/mcp.html +[mcpinfo]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler ### Performance diff --git a/src/implementing_new_features.md b/src/implementing_new_features.md index fda38ef4f..d7561bbba 100644 --- a/src/implementing_new_features.md +++ b/src/implementing_new_features.md @@ -44,7 +44,7 @@ like this; for example, the compiler team recommends filing a Major Change Proposal ([MCP][mcp]) as a lightweight way to garner support and feedback without requiring full consensus. -[mcp]: https://forge.rust-lang.org/compiler/mcp.html#public-facing-changes-require-rfcbot-fcp +[mcp]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp You don't need to have the implementation fully ready for r+ to propose an FCP, but it is generally a good idea to have at least a proof From e068c546a3198d1940069b7268d0bddfafaa3a6d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 15 Mar 2025 11:11:43 +0200 Subject: [PATCH 130/447] those should not get shell highlighting --- src/tests/running.md | 48 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/tests/running.md b/src/tests/running.md index 03d4123cb..c7d924788 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -18,7 +18,7 @@ a subset of test collections, and merge queue CI will exercise all of the test collection.
-```bash +```text ./x test ``` @@ -45,7 +45,7 @@ tests. For example, a good "smoke test" that can be used after modifying rustc to see if things are generally working correctly would be to exercise the `ui` test suite ([`tests/ui`]): -```bash +```text ./x test tests/ui ``` @@ -53,14 +53,14 @@ Of course, the choice of test suites is somewhat arbitrary, and may not suit the task you are doing. For example, if you are hacking on debuginfo, you may be better off with the debuginfo test suite: -```bash +```text ./x test tests/debuginfo ``` If you only need to test a specific subdirectory of tests for any given test suite, you can pass that directory as a filter to `./x test`: -```bash +```text ./x test tests/ui/const-generics ``` @@ -73,7 +73,7 @@ suite, you can pass that directory as a filter to `./x test`: Likewise, you can test a single file by passing its path: -```bash +```text ./x test tests/ui/const-generics/const-test.rs ``` @@ -81,19 +81,19 @@ Likewise, you can test a single file by passing its path: have to use the `--test-args` argument as described [below](#running-an-individual-test). -```bash +```text ./x test src/tools/miri --test-args tests/fail/uninit/padding-enum.rs ``` ### Run only the tidy script -```bash +```text ./x test tidy ``` ### Run tests on the standard library -```bash +```text ./x test --stage 0 library/std ``` @@ -102,13 +102,13 @@ crates, you have to specify those explicitly. ### Run the tidy script and tests on the standard library -```bash +```text ./x test --stage 0 tidy library/std ``` ### Run tests on the standard library using a stage 1 compiler -```bash +```text ./x test --stage 1 library/std ``` @@ -122,7 +122,7 @@ the tests **usually** work fine with stage 1, there are some limitations. ### Run all tests using a stage 2 compiler -```bash +```text ./x test --stage 2 ``` @@ -134,13 +134,13 @@ You almost never need to do this; CI will run these tests for you. You may want to run unit tests on a specific file with following: -```bash +```text ./x test compiler/rustc_data_structures/src/thin_vec/tests.rs ``` But unfortunately, it's impossible. You should invoke the following instead: -```bash +```text ./x test compiler/rustc_data_structures/ --test-args thin_vec ``` @@ -151,7 +151,7 @@ often the test they are trying to fix. As mentioned earlier, you may pass the full file path to achieve this, or alternatively one may invoke `x` with the `--test-args` option: -```bash +```text ./x test tests/ui --test-args issue-1234 ``` @@ -203,7 +203,7 @@ When `--pass $mode` is passed, these tests will be forced to run under the given `$mode` unless the directive `//@ ignore-pass` exists in the test file. For example, you can run all the tests in `tests/ui` as `check-pass`: -```bash +```text ./x test tests/ui --pass check ``` @@ -219,7 +219,7 @@ first look for expected output in `foo.polonius.stderr`, falling back to the usual `foo.stderr` if not found. The following will run the UI test suite in Polonius mode: -```bash +```text ./x test tests/ui --compare-mode=polonius ``` @@ -232,7 +232,7 @@ just `.rs` files, so after [creating a rustup toolchain](../building/how-to-build-and-run.md#creating-a-rustup-toolchain), you can do something like: -```bash +```text rustc +stage1 tests/ui/issue-1234.rs ``` @@ -252,7 +252,7 @@ execution* so be careful where it is used. To do this, first build `remote-test-server` for the remote machine, e.g. for RISC-V -```sh +```text ./x build src/tools/remote-test-server --target riscv64gc-unknown-linux-gnu ``` @@ -264,7 +264,7 @@ On the remote machine, run the `remote-test-server` with the `--bind 0.0.0.0:12345` flag (and optionally `-v` for verbose output). Output should look like this: -```sh +```text $ ./remote-test-server -v --bind 0.0.0.0:12345 starting test server listening on 0.0.0.0:12345! @@ -278,7 +278,7 @@ restrictive IP address when binding. You can test if the `remote-test-server` is working by connecting to it and sending `ping\n`. It should reply `pong`: -```sh +```text $ nc $REMOTE_IP 12345 ping pong @@ -288,7 +288,7 @@ To run tests using the remote runner, set the `TEST_DEVICE_ADDR` environment variable then use `x` as usual. For example, to run `ui` tests for a RISC-V machine with the IP address `1.2.3.4` use -```sh +```text export TEST_DEVICE_ADDR="1.2.3.4:12345" ./x test tests/ui --target riscv64gc-unknown-linux-gnu ``` @@ -362,20 +362,20 @@ codegen-backends = ["llvm", "gcc"] Then you need to install libgccjit 12. For example with `apt`: -```bash +```text $ apt install libgccjit-12-dev ``` Now you can run the following command: -```bash +```text $ ./x test compiler/rustc_codegen_gcc/ ``` If it cannot find the `.so` library (if you installed it with `apt` for example), you need to pass the library file path with `LIBRARY_PATH`: -```bash +```text $ LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/ ./x test compiler/rustc_codegen_gcc/ ``` From 7d157cb36ea63d78de4b496f34e04b5501e532c8 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 15 Mar 2025 11:35:15 +0200 Subject: [PATCH 131/447] make 'mdbook test --chapter "Running tests"' pass --- src/tests/running.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/running.md b/src/tests/running.md index c7d924788..6fb49810a 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -296,7 +296,7 @@ export TEST_DEVICE_ADDR="1.2.3.4:12345" If `remote-test-server` was run with the verbose flag, output on the test machine may look something like -``` +```text [...] run "/tmp/work/test1007/a" run "/tmp/work/test1008/a" From b04865b8d2027cd262b794fc9d6b2dba895cb5e8 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 15 Mar 2025 11:17:03 +0200 Subject: [PATCH 132/447] add some copy-paste goodness --- src/tests/running.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/running.md b/src/tests/running.md index 6fb49810a..73f5603d5 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -363,20 +363,20 @@ codegen-backends = ["llvm", "gcc"] Then you need to install libgccjit 12. For example with `apt`: ```text -$ apt install libgccjit-12-dev +apt install libgccjit-12-dev ``` Now you can run the following command: ```text -$ ./x test compiler/rustc_codegen_gcc/ +./x test compiler/rustc_codegen_gcc/ ``` If it cannot find the `.so` library (if you installed it with `apt` for example), you need to pass the library file path with `LIBRARY_PATH`: ```text -$ LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/ ./x test compiler/rustc_codegen_gcc/ +LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/ ./x test compiler/rustc_codegen_gcc/ ``` If you encounter bugs or problems, don't hesitate to open issues on the From 971366b58bce4d3ec4f10b75a10d2a38485e61cd Mon Sep 17 00:00:00 2001 From: Yang Lin Date: Sun, 16 Mar 2025 23:27:10 +0800 Subject: [PATCH 133/447] Adapt to rust-lang/rust#136466: Start removing `rustc_middle::hir::map::Map` Following commit f86f7ad from pull request #136466 in the Rust project (https://github.com/rust-lang/rust), some methods in `Map` were moved to `TyCtxt`. This update reimplements `rustc-drive-example.rs`, `rustc-driver-interacting-with-the-ast.rs`, and `rustc-interface-example.rs` using the new versions of these methods, ensuring compatibility with the nightly-2025-03-08 toolchain. --- examples/rustc-driver-example.rs | 7 +++---- examples/rustc-driver-interacting-with-the-ast.rs | 8 +++----- examples/rustc-interface-example.rs | 7 +++---- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/examples/rustc-driver-example.rs b/examples/rustc-driver-example.rs index 984bd3e37..35dd07dd1 100644 --- a/examples/rustc-driver-example.rs +++ b/examples/rustc-driver-example.rs @@ -1,4 +1,4 @@ -// Tested with nightly-2025-02-13 +// Tested with nightly-2025-03-08 #![feature(rustc_private)] @@ -71,9 +71,8 @@ impl rustc_driver::Callbacks for MyCallbacks { fn after_analysis(&mut self, _compiler: &Compiler, tcx: TyCtxt<'_>) -> Compilation { // Analyze the program and inspect the types of definitions. - for id in tcx.hir().items() { - let hir = tcx.hir(); - let item = hir.item(id); + for id in tcx.hir_free_items(){ + let item = &tcx.hir_item(id); match item.kind { rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn { .. } => { let name = item.ident; diff --git a/examples/rustc-driver-interacting-with-the-ast.rs b/examples/rustc-driver-interacting-with-the-ast.rs index 3270c722e..2a43ba476 100644 --- a/examples/rustc-driver-interacting-with-the-ast.rs +++ b/examples/rustc-driver-interacting-with-the-ast.rs @@ -1,4 +1,4 @@ -// Tested with nightly-2025-02-13 +// Tested with nightly-2025-03-08 #![feature(rustc_private)] @@ -70,11 +70,9 @@ impl rustc_driver::Callbacks for MyCallbacks { } fn after_analysis(&mut self, _compiler: &Compiler, tcx: TyCtxt<'_>) -> Compilation { - // Every compilation contains a single crate. - let hir_krate = tcx.hir(); // Iterate over the top-level items in the crate, looking for the main function. - for id in hir_krate.items() { - let item = hir_krate.item(id); + for id in tcx.hir_free_items(){ + let item = &tcx.hir_item(id); // Use pattern-matching to find a specific node inside the main function. if let rustc_hir::ItemKind::Fn { body, .. } = item.kind { let expr = &tcx.hir_body(body).value; diff --git a/examples/rustc-interface-example.rs b/examples/rustc-interface-example.rs index 70f27c2a8..11125caec 100644 --- a/examples/rustc-interface-example.rs +++ b/examples/rustc-interface-example.rs @@ -1,4 +1,4 @@ -// Tested with nightly-2025-02-13 +// Tested with nightly-2025-03-08 #![feature(rustc_private)] @@ -64,9 +64,8 @@ fn main() { println!("{krate:?}"); // Analyze the program and inspect the types of definitions. rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { - for id in tcx.hir().items() { - let hir = tcx.hir(); - let item = hir.item(id); + for id in tcx.hir_free_items() { + let item = tcx.hir_item(id); match item.kind { rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn { .. } => { let name = item.ident; From 832299550ce82ff0b9360c8c4e328140c8b72260 Mon Sep 17 00:00:00 2001 From: Yang Lin Date: Sun, 16 Mar 2025 23:43:17 +0800 Subject: [PATCH 134/447] Following commit 401dd84 in the Rust project (https://github.com/rust-lang/rust), `ErrorGuaranteed` was replaced by fatal errors. As a result, `tcx.analysis()` now aborts directly instead of returning an error guard. To accommodate this change, this update replaces `tcx.analysis()` with `typeck()` to perform type checking in the example. --- examples/rustc-interface-getting-diagnostics.rs | 8 +++++--- src/rustc-driver/getting-diagnostics.md | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/rustc-interface-getting-diagnostics.rs b/examples/rustc-interface-getting-diagnostics.rs index 39b236e17..9bb93ab49 100644 --- a/examples/rustc-interface-getting-diagnostics.rs +++ b/examples/rustc-interface-getting-diagnostics.rs @@ -1,4 +1,4 @@ -// Tested with nightly-2025-02-13 +// Tested with nightly-2025-03-08 #![feature(rustc_private)] @@ -86,8 +86,10 @@ fn main() { rustc_interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { - // Run the analysis phase on the local crate to trigger the type error. - let _ = tcx.analysis(()); + // Iterate all the items defined and perform type checking. + tcx.par_hir_body_owners(|item_def_id| { + tcx.ensure_ok().typeck(item_def_id); + }); }); // If the compiler has encountered errors when this closure returns, it will abort (!) the program. // We avoid this by resetting the error count before returning diff --git a/src/rustc-driver/getting-diagnostics.md b/src/rustc-driver/getting-diagnostics.md index 1043df6ec..518cf4e82 100644 --- a/src/rustc-driver/getting-diagnostics.md +++ b/src/rustc-driver/getting-diagnostics.md @@ -7,7 +7,7 @@ otherwise be printed to stderr. To get diagnostics from the compiler, configure [`rustc_interface::Config`] to output diagnostic to a buffer, -and run [`TyCtxt.analysis`]. +and run [`rustc_hir_typeck::typeck`] for each item. ```rust {{#include ../../examples/rustc-interface-getting-diagnostics.rs}} @@ -16,3 +16,4 @@ and run [`TyCtxt.analysis`]. [`rustc_interface`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/index.html [`rustc_interface::Config`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Config.html [`TyCtxt.analysis`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/passes/fn.analysis.html +[`rustc_hir_typeck::typeck`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn.typeck.html From f6940a6e7c2b263f1144585e01008e93dfd0f6c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 16 Mar 2025 20:42:37 +0100 Subject: [PATCH 135/447] Add a note to rustc-dev-guide --- src/tests/ci.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/ci.md b/src/tests/ci.md index 0c0f750a4..2af09a605 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -180,6 +180,8 @@ their results can be seen [here](https://github.com/rust-lang-ci/rust/actions), although usually you will be notified of the result by a comment made by bors on the corresponding PR. +Note that if you start the default try job using `@bors try`, it will skip building several `dist` components and running post-optimization tests, to make the build duration shorter. If you want to execute the full build as it would happen before a merge, add an explicit `try-job` pattern with the name of the default try job (currently `dist-x86_64-linux`). + Multiple try builds can execute concurrently across different PRs.
From bfda715ef4d289ad6ab43277dbc783b050905743 Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 16 Mar 2025 21:06:18 -0400 Subject: [PATCH 136/447] expand ${workspaceFolder} in sample vim config --- src/building/suggested.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/building/suggested.md b/src/building/suggested.md index 249883814..772b0a778 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -123,6 +123,30 @@ Another way is without a plugin, and creating your own logic in your configuration. The following code will work for any checkout of rust-lang/rust (newer than Febuary 2025): ```lua +local function expand_config_variables(option) + local var_placeholders = { + ['${workspaceFolder}'] = function(_) + return vim.lsp.buf.list_workspace_folders()[1] + end, + } + + if type(option) == "table" then + local mt = getmetatable(option) + local result = {} + for k, v in pairs(option) do + result[expand_config_variables(k)] = expand_config_variables(v) + end + return setmetatable(result, mt) + end + if type(option) ~= "string" then + return option + end + local ret = option + for key, fn in pairs(var_placeholders) do + ret = ret:gsub(key, fn) + end + return ret +end lspconfig.rust_analyzer.setup { root_dir = function() local default = lspconfig.rust_analyzer.config_def.default_config.root_dir() @@ -142,7 +166,7 @@ lspconfig.rust_analyzer.setup { -- load rust-lang/rust settings local file = io.open(config) local json = vim.json.decode(file:read("*a")) - client.config.settings["rust-analyzer"] = json.lsp["rust-analyzer"].initialization_options + client.config.settings["rust-analyzer"] = expand_config_variables(json.lsp["rust-analyzer"].initialization_options) client.notify("workspace/didChangeConfiguration", { settings = client.config.settings }) end return true From e4ddc21c8ab4bee43c905b1d4621b4c657c5d0ef Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 15 Feb 2025 19:41:17 +0530 Subject: [PATCH 137/447] replace config.toml to bootstrap.toml in src:doc:rustc-dev-guide --- src/backend/debugging.md | 4 ++-- src/backend/updating-llvm.md | 2 +- src/building/compiler-documenting.md | 2 +- src/building/how-to-build-and-run.md | 14 +++++++------- src/building/new-target.md | 12 ++++++------ src/building/optimized-build.md | 8 ++++---- src/building/suggested.md | 10 +++++----- src/compiler-debugging.md | 10 +++++----- src/fuzzing.md | 2 +- src/llvm-coverage-instrumentation.md | 6 +++--- src/overview.md | 2 +- src/profile-guided-optimization.md | 2 +- src/profiling.md | 2 +- src/profiling/with_perf.md | 2 +- src/profiling/with_rustc_perf.md | 2 +- src/profiling/wpa_profiling.md | 2 +- src/rustdoc.md | 4 ++-- src/sanitizers.md | 4 ++-- src/tests/ci.md | 2 +- src/tests/compiletest.md | 4 ++-- src/tests/directives.md | 6 +++--- src/tests/docker.md | 2 +- src/tests/running.md | 4 ++-- src/tracing.md | 4 ++-- 24 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/backend/debugging.md b/src/backend/debugging.md index 805291017..4f8712dfa 100644 --- a/src/backend/debugging.md +++ b/src/backend/debugging.md @@ -38,7 +38,7 @@ which means that LLVM assertion failures can show up as compiler crashes (not ICEs but "real" crashes) and other sorts of weird behavior. If you are encountering these, it is a good idea to try using a compiler with LLVM assertions enabled - either an "alt" nightly or a compiler you build yourself -by setting `[llvm] assertions=true` in your config.toml - and see whether +by setting `[llvm] assertions=true` in your bootstrap.toml - and see whether anything turns up. The rustc build process builds the LLVM tools into @@ -160,7 +160,7 @@ from `./build//llvm/bin/` with the LLVM IR emitted by rustc. When investigating the implementation of LLVM itself, you should be aware of its [internal debug infrastructure][llvm-debug]. This is provided in LLVM Debug builds, which you enable for rustc -LLVM builds by changing this setting in the config.toml: +LLVM builds by changing this setting in the bootstrap.toml: ``` [llvm] # Indicates whether the LLVM assertions are enabled or not diff --git a/src/backend/updating-llvm.md b/src/backend/updating-llvm.md index 0b45956b1..18c822aad 100644 --- a/src/backend/updating-llvm.md +++ b/src/backend/updating-llvm.md @@ -144,7 +144,7 @@ so let's go through each in detail. Note that `profile = "compiler"` and other defaults set by `./x setup` download LLVM from CI instead of building it from source. You should disable this temporarily to make sure your changes are being used. - This is done by having the following setting in `config.toml`: + This is done by having the following setting in `bootstrap.toml`: ```toml [llvm] diff --git a/src/building/compiler-documenting.md b/src/building/compiler-documenting.md index 948571ce8..b031462ea 100644 --- a/src/building/compiler-documenting.md +++ b/src/building/compiler-documenting.md @@ -36,7 +36,7 @@ like the standard library (std) or the compiler (rustc). - Document internal rustc items Compiler documentation is not built by default. - To create it by default with `x doc`, modify `config.toml`: + To create it by default with `x doc`, modify `bootstrap.toml`: ```toml [build] diff --git a/src/building/how-to-build-and-run.md b/src/building/how-to-build-and-run.md index f9a089c23..067e28711 100644 --- a/src/building/how-to-build-and-run.md +++ b/src/building/how-to-build-and-run.md @@ -159,15 +159,15 @@ similar to the one declared in section [What is `x.py`](#what-is-xpy), but it works as an independent process to execute the `x.py` rather than calling the shell to run the platform related scripts. -## Create a `config.toml` +## Create a `bootstrap.toml` To start, run `./x setup` and select the `compiler` defaults. This will do some initialization -and create a `config.toml` for you with reasonable defaults. If you use a different default (which +and create a `bootstrap.toml` for you with reasonable defaults. If you use a different default (which you'll likely want to do if you want to contribute to an area of rust other than the compiler, such as rustdoc), make sure to read information about that default (located in `src/bootstrap/defaults`) as the build process may be different for other defaults. -Alternatively, you can write `config.toml` by hand. See `config.example.toml` for all the available +Alternatively, you can write `bootstrap.toml` by hand. See `bootstrap.example.toml` for all the available settings and explanations of them. See `src/bootstrap/defaults` for common settings to change. If you have already built `rustc` and you change settings related to LLVM, then you may have to @@ -206,7 +206,7 @@ See the chapters on Note that building will require a relatively large amount of storage space. You may want to have upwards of 10 or 15 gigabytes available to build the compiler. -Once you've created a `config.toml`, you are now ready to run +Once you've created a `bootstrap.toml`, you are now ready to run `x`. There are a lot of options here, but let's start with what is probably the best "go to" command for building a local compiler: @@ -326,7 +326,7 @@ involve proc macros or build scripts, you must be sure to explicitly build targe host platform (in this case, `x86_64-unknown-linux-gnu`). If you want to always build for other targets without needing to pass flags to `x build`, -you can configure this in the `[build]` section of your `config.toml` like so: +you can configure this in the `[build]` section of your `bootstrap.toml` like so: ```toml [build] @@ -336,8 +336,8 @@ target = ["x86_64-unknown-linux-gnu", "wasm32-wasip1"] Note that building for some targets requires having external dependencies installed (e.g. building musl targets requires a local copy of musl). Any target-specific configuration (e.g. the path to a local copy of musl) -will need to be provided by your `config.toml`. -Please see `config.example.toml` for information on target-specific configuration keys. +will need to be provided by your `bootstrap.toml`. +Please see `bootstrap.example.toml` for information on target-specific configuration keys. For examples of the complete configuration necessary to build a target, please visit [the rustc book](https://doc.rust-lang.org/rustc/platform-support.html), diff --git a/src/building/new-target.md b/src/building/new-target.md index 14d10d4a5..09ffbe8c8 100644 --- a/src/building/new-target.md +++ b/src/building/new-target.md @@ -37,7 +37,7 @@ able to configure Rust to treat your build as the system LLVM to avoid redundant builds. You can tell Rust to use a pre-built version of LLVM using the `target` section -of `config.toml`: +of `bootstrap.toml`: ```toml [target.x86_64-unknown-linux-gnu] @@ -55,8 +55,8 @@ for codegen tests. This tool is normally built with LLVM, but if you use your own preinstalled LLVM, you will need to provide `FileCheck` in some other way. On Debian-based systems, you can install the `llvm-N-tools` package (where `N` is the LLVM version number, e.g. `llvm-8-tools`). Alternately, you can specify -the path to `FileCheck` with the `llvm-filecheck` config item in `config.toml` -or you can disable codegen test with the `codegen-tests` item in `config.toml`. +the path to `FileCheck` with the `llvm-filecheck` config item in `bootstrap.toml` +or you can disable codegen test with the `codegen-tests` item in `bootstrap.toml`. ## Creating a target specification @@ -141,14 +141,14 @@ After this, run `cargo update -p libc` to update the lockfiles. Beware that if you patch to a local `path` dependency, this will enable warnings for that dependency. Some dependencies are not warning-free, and due -to the `deny-warnings` setting in `config.toml`, the build may suddenly start +to the `deny-warnings` setting in `bootstrap.toml`, the build may suddenly start to fail. To work around warnings, you may want to: - Modify the dependency to remove the warnings -- Or for local development purposes, suppress the warnings by setting deny-warnings = false in config.toml. +- Or for local development purposes, suppress the warnings by setting deny-warnings = false in bootstrap.toml. ```toml -# config.toml +# bootstrap.toml [rust] deny-warnings = false ``` diff --git a/src/building/optimized-build.md b/src/building/optimized-build.md index f8ca1d0dc..0849464ea 100644 --- a/src/building/optimized-build.md +++ b/src/building/optimized-build.md @@ -13,7 +13,7 @@ This page describes how you can use these approaches when building `rustc` yours Link-time optimization is a powerful compiler technique that can increase program performance. To enable (Thin-)LTO when building `rustc`, set the `rust.lto` config option to `"thin"` -in `config.toml`: +in `bootstrap.toml`: ```toml [rust] @@ -34,7 +34,7 @@ Enabling LTO on Linux has [produced] speed-ups by up to 10%. Using a different memory allocator for `rustc` can provide significant performance benefits. If you want to enable the `jemalloc` allocator, you can set the `rust.jemalloc` option to `true` -in `config.toml`: +in `bootstrap.toml`: ```toml [rust] @@ -46,7 +46,7 @@ jemalloc = true ## Codegen units Reducing the amount of codegen units per `rustc` crate can produce a faster build of the compiler. -You can modify the number of codegen units for `rustc` and `libstd` in `config.toml` with the +You can modify the number of codegen units for `rustc` and `libstd` in `bootstrap.toml` with the following options: ```toml @@ -67,7 +67,7 @@ RUSTFLAGS="-C target_cpu=x86-64-v3" ./x build ... ``` If you also want to compile LLVM for a specific instruction set, you can set `llvm` flags -in `config.toml`: +in `bootstrap.toml`: ```toml [llvm] diff --git a/src/building/suggested.md b/src/building/suggested.md index 249883814..506f41b16 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -305,7 +305,7 @@ subsequent rebuilds: ``` If you don't want to include the flag with every command, you can enable it in -the `config.toml`: +the `bootstrap.toml`: ```toml [rust] @@ -384,20 +384,20 @@ ln -s ./src/tools/nix-dev-shell/envrc-shell ./.envrc # Use nix-shell ### Note Note that when using nix on a not-NixOS distribution, it may be necessary to set -**`patch-binaries-for-nix = true` in `config.toml`**. Bootstrap tries to detect +**`patch-binaries-for-nix = true` in `bootstrap.toml`**. Bootstrap tries to detect whether it's running in nix and enable patching automatically, but this detection can have false negatives. -You can also use your nix shell to manage `config.toml`: +You can also use your nix shell to manage `bootstrap.toml`: ```nix let config = pkgs.writeText "rustc-config" '' - # Your config.toml content goes here + # Your bootstrap.toml content goes here '' pkgs.mkShell { /* ... */ - # This environment variable tells bootstrap where our config.toml is. + # This environment variable tells bootstrap where our bootstrap.toml is. RUST_BOOTSTRAP_CONFIG = config; } ``` diff --git a/src/compiler-debugging.md b/src/compiler-debugging.md index c16b3ee7a..47f397620 100644 --- a/src/compiler-debugging.md +++ b/src/compiler-debugging.md @@ -11,13 +11,13 @@ 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. +set `debug = true` in your bootstrap.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 simply set `debug = true`. -If you want to use GDB to debug rustc, please set `config.toml` with options: +If you want to use GDB to debug rustc, please set `bootstrap.toml` with options: ```toml [rust] @@ -35,14 +35,14 @@ debuginfo-level = 2 The default configuration will enable `symbol-mangling-version` v0. This requires at least GDB v10.2, -otherwise you need to disable new symbol-mangling-version in `config.toml`. +otherwise you need to disable new symbol-mangling-version in `bootstrap.toml`. ```toml [rust] new-symbol-mangling = false ``` -> See the comments in `config.example.toml` for more info. +> See the comments in `bootstrap.example.toml` for more info. You will need to rebuild the compiler after changing any configuration option. @@ -373,7 +373,7 @@ error: aborting due to previous error ## Configuring CodeLLDB for debugging `rustc` -If you are using VSCode, and have edited your `config.toml` to request debugging +If you are using VSCode, and have edited your `bootstrap.toml` to request debugging level 1 or 2 for the parts of the code you're interested in, then you should be able to use the [CodeLLDB] extension in VSCode to debug it. diff --git a/src/fuzzing.md b/src/fuzzing.md index 869fc2f71..b588ca104 100644 --- a/src/fuzzing.md +++ b/src/fuzzing.md @@ -123,7 +123,7 @@ what actually results in superior throughput. You may want to build rustc from source with debug assertions to find additional bugs, though this is a trade-off: it can slow down fuzzing by requiring extra work for every execution. To enable debug assertions, add this -to `config.toml` when compiling rustc: +to `bootstrap.toml` when compiling rustc: ```toml [rust] diff --git a/src/llvm-coverage-instrumentation.md b/src/llvm-coverage-instrumentation.md index 3078ae094..6bc21b6de 100644 --- a/src/llvm-coverage-instrumentation.md +++ b/src/llvm-coverage-instrumentation.md @@ -34,7 +34,7 @@ Detailed instructions and examples are documented in the [coverage map]: https://llvm.org/docs/CoverageMappingFormat.html [rustc-book-instrument-coverage]: https://doc.rust-lang.org/nightly/rustc/instrument-coverage.html -## Recommended `config.toml` settings +## Recommended `bootstrap.toml` settings When working on the coverage instrumentation code, it is usually necessary to **enable the profiler runtime** by setting `profiler = true` in `[build]`. @@ -83,7 +83,7 @@ statically links coverage-instrumented binaries with LLVM runtime code In the `rustc` source tree, `library/profiler_builtins` bundles the LLVM `compiler-rt` code into a Rust library crate. Note that when building `rustc`, -`profiler_builtins` is only included when `build.profiler = true` is set in `config.toml`. +`profiler_builtins` is only included when `build.profiler = true` is set in `bootstrap.toml`. When compiling with `-C instrument-coverage`, [`CrateLoader::postprocess()`][crate-loader-postprocess] dynamically loads @@ -115,7 +115,7 @@ human-readable coverage report. > Tests in `coverage-run` mode have an implicit `//@ needs-profiler-runtime` > directive, so they will be skipped if the profiler runtime has not been -> [enabled in `config.toml`](#recommended-configtoml-settings). +> [enabled in `bootstrap.toml`](#recommended-configtoml-settings). Finally, the [`tests/codegen/instrument-coverage/testprog.rs`] test compiles a simple Rust program with `-C instrument-coverage` and compares the compiled program's LLVM IR to diff --git a/src/overview.md b/src/overview.md index 21ab00406..92d0c7b0c 100644 --- a/src/overview.md +++ b/src/overview.md @@ -351,7 +351,7 @@ approach is to turn [`RefCell`]s into [`Mutex`]s -- that is, we switch to thread-safe internal mutability. However, there are ongoing challenges with lock contention, maintaining query-system invariants under concurrency, and the complexity of the code base. One can try out the current -work by enabling parallel compilation in `config.toml`. It's still early days, +work by enabling parallel compilation in `bootstrap.toml`. It's still early days, but there are already some promising performance improvements. [`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html diff --git a/src/profile-guided-optimization.md b/src/profile-guided-optimization.md index 995752b0b..39bc8b5e8 100644 --- a/src/profile-guided-optimization.md +++ b/src/profile-guided-optimization.md @@ -120,7 +120,7 @@ The `rustc` version of this can be found in `library/profiler_builtins` which basically packs the C code from `compiler-rt` into a Rust crate. In order for `profiler_builtins` to be built, `profiler = true` must be set -in `rustc`'s `config.toml`. +in `rustc`'s `bootstrap.toml`. [compiler-rt-profile]: https://github.com/llvm/llvm-project/tree/main/compiler-rt/lib/profile diff --git a/src/profiling.md b/src/profiling.md index df987e00a..de06bd7cd 100644 --- a/src/profiling.md +++ b/src/profiling.md @@ -87,7 +87,7 @@ Example output for the compiler: Since this doesn't seem to work with incremental compilation or `./x check`, you will be compiling rustc _a lot_. -I recommend changing a few settings in `config.toml` to make it bearable: +I recommend changing a few settings in `bootstrap.toml` to make it bearable: ``` [rust] # A debug build takes _a third_ as long on my machine, diff --git a/src/profiling/with_perf.md b/src/profiling/with_perf.md index 51a22d185..742ea1c41 100644 --- a/src/profiling/with_perf.md +++ b/src/profiling/with_perf.md @@ -6,7 +6,7 @@ This is a guide for how to profile rustc with [perf](https://perf.wiki.kernel.or - Get a clean checkout of rust-lang/master, or whatever it is you want to profile. -- Set the following settings in your `config.toml`: +- Set the following settings in your `bootstrap.toml`: - `debuginfo-level = 1` - enables line debuginfo - `jemalloc = false` - lets you do memory use profiling with valgrind - leave everything else the defaults diff --git a/src/profiling/with_rustc_perf.md b/src/profiling/with_rustc_perf.md index eda8c3a17..c47fed24e 100644 --- a/src/profiling/with_rustc_perf.md +++ b/src/profiling/with_rustc_perf.md @@ -9,7 +9,7 @@ which will download and build the suite for you, build a local compiler toolchai You can use the `./x perf [options]` command to use this integration. -You can use normal bootstrap flags for this command, such as `--stage 1` or `--stage 2`, for example to modify the stage of the created sysroot. It might also be useful to configure `config.toml` to better support profiling, e.g. set `rust.debuginfo-level = 1` to add source line information to the built compiler. +You can use normal bootstrap flags for this command, such as `--stage 1` or `--stage 2`, for example to modify the stage of the created sysroot. It might also be useful to configure `bootstrap.toml` to better support profiling, e.g. set `rust.debuginfo-level = 1` to add source line information to the built compiler. `x perf` currently supports the following commands: - `benchmark `: Benchmark the compiler and store the results under the passed `id`. diff --git a/src/profiling/wpa_profiling.md b/src/profiling/wpa_profiling.md index a800c5717..d2680d408 100644 --- a/src/profiling/wpa_profiling.md +++ b/src/profiling/wpa_profiling.md @@ -44,7 +44,7 @@ compiler we're using to build rustc will aid our analysis greatly by allowing WP symbols correctly. Unfortunately, the stage 0 compiler does not have symbols turned on which is why we'll need to build a stage 1 compiler and then a stage 2 compiler ourselves. -To do this, make sure you have set `debuginfo-level = 1` in your `config.toml` file. This tells +To do this, make sure you have set `debuginfo-level = 1` in your `bootstrap.toml` file. This tells rustc to generate debug information which includes stack frames when bootstrapping. Now you can build the stage 1 compiler: `x build --stage 1 -i library` or however diff --git a/src/rustdoc.md b/src/rustdoc.md index 2a0e212f9..356698148 100644 --- a/src/rustdoc.md +++ b/src/rustdoc.md @@ -58,12 +58,12 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) * If you want to copy those docs to a webserver, copy all of `build/host/doc`, since that's where the CSS, JS, fonts, and landing page are. - * For frontend debugging, disable the `rust.docs-minification` option in [`config.toml`]. + * For frontend debugging, disable the `rust.docs-minification` option in [`bootstrap.toml`]. * Use `./x test tests/rustdoc*` to run the tests using a stage1 rustdoc. * See [Rustdoc internals] for more information about tests. -[`config.toml`]: ./building/how-to-build-and-run.md +[`bootstrap.toml`]: ./building/how-to-build-and-run.md ## Code structure diff --git a/src/sanitizers.md b/src/sanitizers.md index 73e888eae..b1654b15e 100644 --- a/src/sanitizers.md +++ b/src/sanitizers.md @@ -32,7 +32,7 @@ implementation: * The sanitizer runtime libraries are part of the [compiler-rt] project, and [will be built][sanitizer-build] on [supported targets][sanitizer-targets] - when enabled in `config.toml`: + when enabled in `bootstrap.toml`: ```toml [build] @@ -80,7 +80,7 @@ Sanitizers are validated by code generation tests in [`tests/ui/sanitizer/`][test-ui] directory. Testing sanitizer functionality requires the sanitizer runtimes (built when -`sanitizer = true` in `config.toml`) and target providing support for particular +`sanitizer = true` in `bootstrap.toml`) and target providing support for particular sanitizer. When sanitizer is unsupported on given target, sanitizers tests will be ignored. This behaviour is controlled by compiletest `needs-sanitizer-*` directives. diff --git a/src/tests/ci.md b/src/tests/ci.md index 0c0f750a4..cded565d6 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -435,7 +435,7 @@ To learn more about the dashboard, see the [Datadog CI docs]. ## Determining the CI configuration -If you want to determine which `config.toml` settings are used in CI for a +If you want to determine which `bootstrap.toml` settings are used in CI for a particular job, it is probably easiest to just look at the build log. To do this: diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index a6996e398..2c35381ea 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -525,10 +525,10 @@ data into a human-readable code coverage report. Instrumented binaries need to be linked against the LLVM profiler runtime, so `coverage-run` tests are **automatically skipped** unless the profiler runtime -is enabled in `config.toml`: +is enabled in `bootstrap.toml`: ```toml -# config.toml +# bootstrap.toml [build] profiler = true ``` diff --git a/src/tests/directives.md b/src/tests/directives.md index d5b896a8e..81aa35f1a 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -160,9 +160,9 @@ settings: stable support for `asm!` - `needs-profiler-runtime` — ignores the test if the profiler runtime was not enabled for the target - (`build.profiler = true` in rustc's `config.toml`) + (`build.profiler = true` in rustc's `bootstrap.toml`) - `needs-sanitizer-support` — ignores if the sanitizer support was not enabled - for the target (`sanitizers = true` in rustc's `config.toml`) + for the target (`sanitizers = true` in rustc's `bootstrap.toml`) - `needs-sanitizer-{address,hwaddress,leak,memory,thread}` — ignores if the corresponding sanitizer is not enabled for the target (AddressSanitizer, hardware-assisted AddressSanitizer, LeakSanitizer, MemorySanitizer or @@ -172,7 +172,7 @@ settings: flag, or running on fuchsia. - `needs-unwind` — ignores if the target does not support unwinding - `needs-rust-lld` — ignores if the rust lld support is not enabled (`rust.lld = - true` in `config.toml`) + true` in `bootstrap.toml`) - `needs-threads` — ignores if the target does not have threading support - `needs-subprocess` — ignores if the target does not have subprocess support - `needs-symlink` — ignores if the target does not support symlinks. This can be diff --git a/src/tests/docker.md b/src/tests/docker.md index a8a388ef9..032da1ca1 100644 --- a/src/tests/docker.md +++ b/src/tests/docker.md @@ -21,7 +21,7 @@ The [`src/ci/docker/run.sh`] script is used to build a specific Docker image, ru build Rust within the image, and either run tests or prepare a set of archives designed for distribution. The script will mount your local Rust source tree in read-only mode, and an `obj` directory in read-write mode. All the compiler artifacts will be stored in the `obj` directory. The shell will start out in the `obj`directory. From there, it will execute `../src/ci/run.sh` which starts the build as defined by the Docker image. You can run `src/ci/docker/run.sh ` directly. A few important notes regarding the `run.sh` script: -- When executed on CI, the script expects that all submodules are checked out. If some submodule that is accessed by the job is not available, the build will result in an error. You should thus make sure that you have all required submodules checked out locally. You can either do that manually through git, or set `submodules = true` in your `config.toml` and run a command such as `x build` to let bootstrap download the most important submodules (this might not be enough for the given CI job that you are trying to execute though). +- When executed on CI, the script expects that all submodules are checked out. If some submodule that is accessed by the job is not available, the build will result in an error. You should thus make sure that you have all required submodules checked out locally. You can either do that manually through git, or set `submodules = true` in your `bootstrap.toml` and run a command such as `x build` to let bootstrap download the most important submodules (this might not be enough for the given CI job that you are trying to execute though). - `` corresponds to a single directory located in one of the `src/ci/docker/host-*` directories. Note that image name does not necessarily correspond to a job name, as some jobs execute the same image, but with different environment variables or Docker build arguments (this is a part of the complexity that makes it difficult to run CI jobs locally). - If you are executing a "dist" job (job beginning with `dist-`), you should set the `DEPLOY=1` environment variable. - If you are executing an "alternative dist" job (job beginning with `dist-` and ending with `-alt`), you should set the `DEPLOY_ALT=1` environment variable. diff --git a/src/tests/running.md b/src/tests/running.md index 03d4123cb..ab97fbf96 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -189,7 +189,7 @@ just like when running the tests without the `--bless` flag. There are a few options for running tests: -* `config.toml` has the `rust.verbose-tests` option. If `false`, each test will +* `bootstrap.toml` has the `rust.verbose-tests` option. If `false`, each test will print a single dot (the default). If `true`, the name of every test will be printed. This is equivalent to the `--quiet` option in the [Rust test harness](https://doc.rust-lang.org/rustc/tests/). @@ -353,7 +353,7 @@ coordinate running tests (see [src/bootstrap/src/core/build_steps/test.rs]). First thing to know is that it only supports linux x86_64 at the moment. We will extend its support later on. -You need to update `codegen-backends` value in your `config.toml` file in the +You need to update `codegen-backends` value in your `bootstrap.toml` file in the `[rust]` section and add "gcc" in the array: ```toml diff --git a/src/tracing.md b/src/tracing.md index af484ab5f..0cfdf306e 100644 --- a/src/tracing.md +++ b/src/tracing.md @@ -185,11 +185,11 @@ rustc. While calls to `error!`, `warn!` and `info!` are included in every build of the compiler, calls to `debug!` and `trace!` are only included in the program if -`debug-logging=true` is turned on in config.toml (it is +`debug-logging=true` is turned on in bootstrap.toml (it is turned off by default), so if you don't see `DEBUG` logs, especially if you run the compiler with `RUSTC_LOG=rustc rustc some.rs` and only see `INFO` logs, make sure that `debug-logging=true` is turned on in your -config.toml. +bootstrap.toml. ## Logging etiquette and conventions From bfe33b7ee060ebf712d85c5a0608e710b4ef05b4 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Tue, 18 Mar 2025 12:08:16 +0800 Subject: [PATCH 138/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index eb779d9ab..6baf43397 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -8536f201ffdb2c24925d7f9e87996d7dca93428b +493c38ba371929579fe136df26eccd9516347c7a From e0d97048419550941b8b1b5a8b2feb96768872c6 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Wed, 5 Mar 2025 13:18:17 +0800 Subject: [PATCH 139/447] Add chapter Remarks on perma-unstable features Signed-off-by: xizheyin --- src/SUMMARY.md | 1 + .../remarks-on-perma-unstable-features.md | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/rustc-driver/remarks-on-perma-unstable-features.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 106db508e..71b58f79d 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -124,6 +124,7 @@ - [rustc_driver and rustc_interface](./rustc-driver/intro.md) - [Example: Type checking](./rustc-driver/interacting-with-the-ast.md) - [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.md) + - [Remarks on perma-unstable features](./rustc-driver/remarks-on-perma-unstable-features.md) - [Errors and Lints](diagnostics.md) - [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md) - [Translation](./diagnostics/translation.md) diff --git a/src/rustc-driver/remarks-on-perma-unstable-features.md b/src/rustc-driver/remarks-on-perma-unstable-features.md new file mode 100644 index 000000000..c307adc00 --- /dev/null +++ b/src/rustc-driver/remarks-on-perma-unstable-features.md @@ -0,0 +1,55 @@ + +# Remarks on perma unstable features + +## `rustc_private` + +### Overview + +The `rustc_private` feature allows external crates to use compiler internals. + +### Using `rustc-private` with Official Toolchains + +When using the `rustc_private` feature with official Rust toolchains distributed via rustup, you need to install two additional components: + +1. **`rustc-dev`**: Provides compiler libraries +2. **`llvm-tools`**: Provides LLVM libraries required for linking + +#### Installation Steps + +Install both components using rustup: + +```bash +rustup component add rustc-dev llvm-tools +``` + +#### Common Error + +Without the `llvm-tools` component, you'll encounter linking errors like: + +``` +error: linking with `cc` failed: exit status: 1 + | + = note: rust-lld: error: unable to find library -lLLVM-{version} +``` + +### Using `rustc-private` with Custom Toolchains + +For custom-built toolchains or environments not using rustup, additional configuration is typically required: + +#### Requirements + +- LLVM libraries must be available in your system's library search paths +- The LLVM version must match the one used to build your Rust toolchain + +#### Troubleshooting Steps + +1. **Check LLVM installation**: Verify LLVM is installed and accessible +2. **Configure library paths**: You may need to set environment variables: + ```bash + export LD_LIBRARY_PATH=/path/to/llvm/lib:$LD_LIBRARY_PATH + ``` +3. **Check version compatibility**: Ensure your LLVM version is compatible with your Rust toolchain + +### Additional Resources + +- [GitHub Issue #137421](https://github.com/rust-lang/rust/issues/137421): Explains that `rustc_private` linker failures often occur because `llvm-tools` is not installed From db56758b57c00f545f05e4c3864dbf24752c9793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 18 Mar 2025 16:16:28 +0100 Subject: [PATCH 140/447] Add Fuchsia ping group notice --- src/tests/fuchsia.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tests/fuchsia.md b/src/tests/fuchsia.md index e96290b92..926803368 100644 --- a/src/tests/fuchsia.md +++ b/src/tests/fuchsia.md @@ -4,6 +4,14 @@ million lines of Rust code.[^loc] It has caught a large number of [regressions] in the past and was subsequently included in CI. +## What to do if the Fuchsia job breaks? + +Please contact the `fuchsia` ping group and ask them for help. + +```text +@rustbot ping fuchsia +``` + ## Building Fuchsia in CI Fuchsia builds as part of the suite of bors tests that run before a pull request From ba77a8030b2dfaf013f9e5b13184746ff2482c61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 18 Mar 2025 16:17:59 +0100 Subject: [PATCH 141/447] Reorder RfL tests page to move the "what if it breaks" section to the top --- src/tests/rust-for-linux.md | 40 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/tests/rust-for-linux.md b/src/tests/rust-for-linux.md index c674d1575..bdf32ffc3 100644 --- a/src/tests/rust-for-linux.md +++ b/src/tests/rust-for-linux.md @@ -3,26 +3,7 @@ [Rust for Linux](https://rust-for-linux.com/) (RfL) is an effort for adding support for the Rust programming language into the Linux kernel. -## Building Rust for Linux in CI - -Rust for Linux builds as part of the suite of bors tests that run before a pull -request is merged. - -The workflow builds a stage1 sysroot of the Rust compiler, downloads the Linux -kernel, and tries to compile several Rust for Linux drivers and examples using -this sysroot. RfL uses several unstable compiler/language features, therefore -this workflow notifies us if a given compiler change would break it. - -If you are worried that a pull request might break the Rust for Linux builder -and want to test it out before submitting it to the bors queue, simply add this -line to your PR description: - -> try-job: x86_64-rust-for-linux - -Then when you `@bors try` it will pick the job that builds the Rust for Linux -integration. - -## What to do in case of failure +## What to do if the Rust for Linux job breaks? If a PR breaks the Rust for Linux CI job, then: @@ -48,4 +29,23 @@ ping group to ask for help: @rustbot ping rfl ``` +## Building Rust for Linux in CI + +Rust for Linux builds as part of the suite of bors tests that run before a pull +request is merged. + +The workflow builds a stage1 sysroot of the Rust compiler, downloads the Linux +kernel, and tries to compile several Rust for Linux drivers and examples using +this sysroot. RfL uses several unstable compiler/language features, therefore +this workflow notifies us if a given compiler change would break it. + +If you are worried that a pull request might break the Rust for Linux builder +and want to test it out before submitting it to the bors queue, simply add this +line to your PR description: + +> try-job: x86_64-rust-for-linux + +Then when you `@bors try` it will pick the job that builds the Rust for Linux +integration. + [rfl-ping]: ../notification-groups/rust-for-linux.md From 1bcd02da969fa0ec166dba3c577a233283db2378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 18 Mar 2025 16:19:55 +0100 Subject: [PATCH 142/447] Add Fuchsia ping group page --- src/SUMMARY.md | 3 ++- src/notification-groups/fuchsia.md | 12 ++++++++++++ src/tests/fuchsia.md | 3 ++- 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 src/notification-groups/fuchsia.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index a090f96f3..9e2d0774a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -61,12 +61,13 @@ - [ARM](notification-groups/arm.md) - [Cleanup Crew](notification-groups/cleanup-crew.md) - [Emscripten](notification-groups/emscripten.md) + - [Fuchsia](notification-groups/fuchsia.md) - [LLVM](notification-groups/llvm.md) - [RISC-V](notification-groups/risc-v.md) + - [Rust for Linux](notification-groups/rust-for-linux.md) - [WASI](notification-groups/wasi.md) - [WebAssembly](notification-groups/wasm.md) - [Windows](notification-groups/windows.md) - - [Rust for Linux](notification-groups/rust-for-linux.md) - [Licenses](./licenses.md) - [Editions](guides/editions.md) diff --git a/src/notification-groups/fuchsia.md b/src/notification-groups/fuchsia.md new file mode 100644 index 000000000..a4658e0d8 --- /dev/null +++ b/src/notification-groups/fuchsia.md @@ -0,0 +1,12 @@ +# Fuchsia notification group + +**Github Label:** [O-fuchsia]
+**Ping command:** `@rustbot ping fuchsia` + +[O-fuchsia]: https://github.com/rust-lang/rust/labels/O-fuchsia + +This list will be used to notify [Fuchsia][fuchsia] maintainers +when the compiler or the standard library changes in a way that would +break the Fuchsia integration. + +[fuchsia]: ../tests/fuchsia.md diff --git a/src/tests/fuchsia.md b/src/tests/fuchsia.md index 926803368..2766c362c 100644 --- a/src/tests/fuchsia.md +++ b/src/tests/fuchsia.md @@ -6,7 +6,7 @@ in the past and was subsequently included in CI. ## What to do if the Fuchsia job breaks? -Please contact the `fuchsia` ping group and ask them for help. +Please contact the [fuchsia][fuchsia-ping] ping group and ask them for help. ```text @rustbot ping fuchsia @@ -170,6 +170,7 @@ rustc book][platform-support]. [`public_configs`]: https://gn.googlesource.com/gn/+/main/docs/reference.md#var_public_configs [`//build/config:compiler`]: https://cs.opensource.google/fuchsia/fuchsia/+/main:build/config/BUILD.gn;l=121;drc=c26c473bef93b33117ae417893118907a026fec7 [build system]: https://fuchsia.dev/fuchsia-src/development/build/build_system +[fuchsia-ping]: ../notification-groups/fuchsia.md [^loc]: As of June 2024, Fuchsia had about 2 million lines of first-party Rust code and a roughly equal amount of third-party code, as counted by tokei From f00643aa1cb4ee35f619406fbd7934d6a1093d50 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 18 Mar 2025 12:04:47 -0500 Subject: [PATCH 143/447] add new section on the `rustdoc` test suite --- src/rustdoc-internals/htmldocck.md | 101 +++++++++++++++++++++++++++++ src/rustdoc.md | 14 ++-- src/tests/compiletest.md | 2 +- 3 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 src/rustdoc-internals/htmldocck.md diff --git a/src/rustdoc-internals/htmldocck.md b/src/rustdoc-internals/htmldocck.md new file mode 100644 index 000000000..d69627f46 --- /dev/null +++ b/src/rustdoc-internals/htmldocck.md @@ -0,0 +1,101 @@ +# `rustdoc` tests + +This page is specifically about the `rustdoc` test suite, for other test suites used for testing rustdoc, see [Rustdoc § Tests](../rustdoc.md#tests). + +`htmldocck.py` is a custom checker script that uses [XPath] to verify the HTML output of rustdoc. + +[XPath]: https://en.wikipedia.org/wiki/XPath + +## Directives +Directives to htmldocck are similar to those given to `compiletest` in that they take the form of `//@` comments. + +All `PATH`s in directives are relative to the the rustdoc output directory (`build/TARGET/test/rustdoc/TESTNAME`), +so it is conventional to use a `#![crate_name = "foo"]` attribute to avoid writing paths. +To avoid repetion, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument. + +All arguments take the form of quoted strings, +with the exception of `COUNT` and the special `-` form of `PATH`. + +Directives are assertions that place constraints on the generated HTML. + +All directives (except `files`) can be negated by putting a `!` in front of their name. + +Similar to shell commands, +directives can extend across multiple lines if their last char is `\`. +In this case, the start of the next line should be `//`, with no `@`. + +For example, `//@ !has 'foo/struct.Bar.html'` checks that crate `foo` does not have a page for a struct named `Bar` in the crate root. + +### `has` + +Usage 1: `//@ has PATH` +Usage 2: `//@ has PATH XPATH PATTERN` + +In the first form, `has` checks that a given file exists. + +In the second form, `has` is an alias for `matches`, +except `PATTERN` is a whitespace-normalized[^1] string instead of a regex. + +### `matches` + +Usage: `//@ matches PATH XPATH PATTERN` + +Checks that the text of each element selected by `XPATH` in `PATH` matches the python-flavored regex `PATTERN`. + +### `matchesraw` + +Usage: `//@ matchesraw PATH PATTERN` + +Checks that the contents of the file `PATH` matches the regex `PATTERN`. + +### `hasraw` + +Usage: `//@ hasraw PATH PATTERN` + +Same as `matchesraw`, except `PATTERN` is a whitespace-normalized[^1] string instead of a regex. + +### `count` + +Usage: `//@ count PATH XPATH COUNT` + +Checks that there are exactly `COUNT` matches for `XPATH` within the file `PATH`. + +### `snapshot` + +Usage: `//@ snapshot NAME PATH XPATH` + +Creates a snapshot test named NAME. +A snapshot test captures a subtree of the DOM, at the location +determined by the XPath, and compares it to a pre-recorded value +in a file. The file's name is the test's name with the `.rs` extension +replaced with `.NAME.html`, where NAME is the snapshot's name. + +htmldocck supports the `--bless` option to accept the current subtree +as expected, saving it to the file determined by the snapshot's name. +compiletest's `--bless` flag is forwarded to htmldocck. + +### `has-dir` + +Usage: `//@ has-dir PATH` + +Checks for the existance of directory `PATH`. + +### `files` + +Usage: `//@ files PATH ENTRIES` + +Checks that the directory `PATH` contains exactly `ENTRIES`. +`ENTRIES` is a python list of strings inside a quoted string, +as if it were to be parsed by `eval`. +(note that the list is actually parsed by `shlex.split`, +so it cannot contain arbitrary python expressions). + +Example: `//@ files "foo/bar" '["index.html", "sidebar-items.js"]'` + +[^1]: Whitespace normalization means that all spans of consecutive whitespace are replaced with a single space. The files themselves are also whitespace-normalized. + +## Limitations +All `XPATH` arguments must start with `//` due to a flaw in the implemention. + +Only well-formed HTML can be parsed (hopefully rustdoc doesn't output mismatched tags). + diff --git a/src/rustdoc.md b/src/rustdoc.md index 356698148..5ac62aa2c 100644 --- a/src/rustdoc.md +++ b/src/rustdoc.md @@ -77,27 +77,27 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) `doctest.rs`. * The Markdown renderer is loaded up in `html/markdown.rs`, including functions for extracting doctests from a given block of Markdown. -* The tests on the structure of rustdoc HTML output are located in `tests/rustdoc`, where - they're handled by the test runner of bootstrap and the supplementary script - `src/etc/htmldocck.py`. * Frontend CSS and JavaScript are stored in `html/static/`. ## Tests -* All paths in this section are relative to `tests` in the rust-lang/rust repository. -* Tests on search engine and index are located in `rustdoc-js` and `rustdoc-js-std`. +* Tests on search engine and index are located in `tests/rustdoc-js` and `tests/rustdoc-js-std`. The format is specified [in the search guide](rustdoc-internals/search.md#testing-the-search-engine). * Tests on the "UI" of rustdoc (the terminal output it produces when run) are in - `rustdoc-ui` + `tests/rustdoc-ui` * Tests on the "GUI" of rustdoc (the HTML, JS, and CSS as rendered in a browser) - are in `rustdoc-gui`. These use a [NodeJS tool called + are in `tests/rustdoc-gui`. These use a [NodeJS tool called browser-UI-test](https://github.com/GuillaumeGomez/browser-UI-test/) that uses puppeteer to run tests in a headless browser and check rendering and interactivity. * Additionally, JavaScript type annotations are written using [TypeScript-flavored JSDoc] comments and an external d.ts file. The code itself is plain, valid JavaScript; we only use tsc as a linter. +* The tests on the structure of rustdoc HTML output are located in `tests/rustdoc`, + where they're handled by the test runner of bootstrap and + the supplementary script `src/etc/htmldocck.py`. + [These tests have several extra directives available to them](./rustdoc-internals/htmldocck.md). [TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index 2c35381ea..ee66b787b 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -78,7 +78,7 @@ The following test suites are available, with links for more information: ### Rustdoc test suites -See [Rustdoc tests](../rustdoc.md#tests) for more details. +See [Rustdoc § Tests](../rustdoc.md#tests) for more details. | Test suite | Purpose | |------------------|--------------------------------------------------------------------------| From 8b501562a8e0b21fb304394a3cb6df18c0f54cc3 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 18 Mar 2025 12:10:43 -0500 Subject: [PATCH 144/447] add htmldocck.md to SUMMARY.md --- src/SUMMARY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 9e2d0774a..fb4687774 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -95,7 +95,7 @@ - [Parallel Compilation](./parallel-rustc.md) - [Rustdoc internals](./rustdoc-internals.md) - [Search](./rustdoc-internals/search.md) - + - [`rustdoc` tests](./rustdoc-internals/htmldocck.md) # Source Code Representation - [Prologue](./part-3-intro.md) From f248d2f57cd99ae6f4962582b9ecc574b60ceb05 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 18 Mar 2025 13:10:26 -0500 Subject: [PATCH 145/447] htmldocck: expand limitations and mention compiletest directives --- src/rustdoc-internals/htmldocck.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/rustdoc-internals/htmldocck.md b/src/rustdoc-internals/htmldocck.md index d69627f46..b37c1ac3d 100644 --- a/src/rustdoc-internals/htmldocck.md +++ b/src/rustdoc-internals/htmldocck.md @@ -9,6 +9,10 @@ This page is specifically about the `rustdoc` test suite, for other test suites ## Directives Directives to htmldocck are similar to those given to `compiletest` in that they take the form of `//@` comments. +In addition to the directives listed here, +`rustdoc` tests also support most +[compiletest directives](../tests/directives.html). + All `PATH`s in directives are relative to the the rustdoc output directory (`build/TARGET/test/rustdoc/TESTNAME`), so it is conventional to use a `#![crate_name = "foo"]` attribute to avoid writing paths. To avoid repetion, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument. @@ -95,7 +99,9 @@ Example: `//@ files "foo/bar" '["index.html", "sidebar-items.js"]'` [^1]: Whitespace normalization means that all spans of consecutive whitespace are replaced with a single space. The files themselves are also whitespace-normalized. ## Limitations -All `XPATH` arguments must start with `//` due to a flaw in the implemention. - -Only well-formed HTML can be parsed (hopefully rustdoc doesn't output mismatched tags). +`htmldocck.py` uses the xpath implementation from the standard library. +This leads to several limitations: +* All `XPATH` arguments must start with `//` due to a flaw in the implemention. +* Many XPath features (functions, axies, etc.) are not supported. +* Only well-formed HTML can be parsed (hopefully rustdoc doesn't output mismatched tags). From 72aa06dff1dcfd3516aded79399336932c290976 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 18 Mar 2025 13:19:33 -0500 Subject: [PATCH 146/447] rustdoc test suite: clean up wording and intro --- src/rustdoc-internals/htmldocck.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/rustdoc-internals/htmldocck.md b/src/rustdoc-internals/htmldocck.md index b37c1ac3d..97c40c8a8 100644 --- a/src/rustdoc-internals/htmldocck.md +++ b/src/rustdoc-internals/htmldocck.md @@ -1,8 +1,10 @@ -# `rustdoc` tests +# the `rustdoc` test suite This page is specifically about the `rustdoc` test suite, for other test suites used for testing rustdoc, see [Rustdoc § Tests](../rustdoc.md#tests). -`htmldocck.py` is a custom checker script that uses [XPath] to verify the HTML output of rustdoc. +The `rustdoc` test suite is specifically used to test the HTML output of rustdoc. + +This is achived by means of `htmldocck.py`, a custom checker script that leverages [XPath]. [XPath]: https://en.wikipedia.org/wiki/XPath @@ -14,7 +16,8 @@ In addition to the directives listed here, [compiletest directives](../tests/directives.html). All `PATH`s in directives are relative to the the rustdoc output directory (`build/TARGET/test/rustdoc/TESTNAME`), -so it is conventional to use a `#![crate_name = "foo"]` attribute to avoid writing paths. +so it is conventional to use a `#![crate_name = "foo"]` attribute to avoid +having to write a long crate name multiple times. To avoid repetion, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument. All arguments take the form of quoted strings, From 174678da355231d76700710caca84b5439474c9c Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 18 Mar 2025 13:21:15 -0500 Subject: [PATCH 147/447] rename htmldocck.md -> rustdoc-test-suite.md --- src/SUMMARY.md | 2 +- src/rustdoc-internals/{htmldocck.md => rustdoc-test-suite.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/rustdoc-internals/{htmldocck.md => rustdoc-test-suite.md} (100%) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index fb4687774..8ea5e86cd 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -95,7 +95,7 @@ - [Parallel Compilation](./parallel-rustc.md) - [Rustdoc internals](./rustdoc-internals.md) - [Search](./rustdoc-internals/search.md) - - [`rustdoc` tests](./rustdoc-internals/htmldocck.md) + - [the `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md) # Source Code Representation - [Prologue](./part-3-intro.md) diff --git a/src/rustdoc-internals/htmldocck.md b/src/rustdoc-internals/rustdoc-test-suite.md similarity index 100% rename from src/rustdoc-internals/htmldocck.md rename to src/rustdoc-internals/rustdoc-test-suite.md From 2e1c4999c812e7c8f5af44a9f902d908c672dfe9 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 18 Mar 2025 13:23:37 -0500 Subject: [PATCH 148/447] clean up wording/grammar and mention double quotes --- src/SUMMARY.md | 2 +- src/rustdoc-internals/rustdoc-test-suite.md | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 8ea5e86cd..075d5af4c 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -95,7 +95,7 @@ - [Parallel Compilation](./parallel-rustc.md) - [Rustdoc internals](./rustdoc-internals.md) - [Search](./rustdoc-internals/search.md) - - [the `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md) + - [The `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md) # Source Code Representation - [Prologue](./part-3-intro.md) diff --git a/src/rustdoc-internals/rustdoc-test-suite.md b/src/rustdoc-internals/rustdoc-test-suite.md index 97c40c8a8..fb4be51c2 100644 --- a/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/rustdoc-internals/rustdoc-test-suite.md @@ -1,6 +1,6 @@ -# the `rustdoc` test suite +# The `rustdoc` test suite -This page is specifically about the `rustdoc` test suite, for other test suites used for testing rustdoc, see [Rustdoc § Tests](../rustdoc.md#tests). +This page is specifically about the test suite named `rustdoc`, for other test suites used for testing rustdoc, see [Rustdoc Tests](../rustdoc.md#tests). The `rustdoc` test suite is specifically used to test the HTML output of rustdoc. @@ -20,7 +20,8 @@ so it is conventional to use a `#![crate_name = "foo"]` attribute to avoid having to write a long crate name multiple times. To avoid repetion, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument. -All arguments take the form of quoted strings, +All arguments take the form of quoted strings +(both single and double quotes are supported), with the exception of `COUNT` and the special `-` form of `PATH`. Directives are assertions that place constraints on the generated HTML. From 871280d6dfb5c9b6d0962749d9c3c19b839b7872 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 18 Mar 2025 13:25:39 -0500 Subject: [PATCH 149/447] normalize link titles --- src/rustdoc-internals/rustdoc-test-suite.md | 2 +- src/tests/compiletest.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rustdoc-internals/rustdoc-test-suite.md b/src/rustdoc-internals/rustdoc-test-suite.md index fb4be51c2..c2a2e6495 100644 --- a/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/rustdoc-internals/rustdoc-test-suite.md @@ -1,6 +1,6 @@ # The `rustdoc` test suite -This page is specifically about the test suite named `rustdoc`, for other test suites used for testing rustdoc, see [Rustdoc Tests](../rustdoc.md#tests). +This page is specifically about the test suite named `rustdoc`, for other test suites used for testing rustdoc, see [Rustdoc tests](../rustdoc.md#tests). The `rustdoc` test suite is specifically used to test the HTML output of rustdoc. diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index ee66b787b..2c35381ea 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -78,7 +78,7 @@ The following test suites are available, with links for more information: ### Rustdoc test suites -See [Rustdoc § Tests](../rustdoc.md#tests) for more details. +See [Rustdoc tests](../rustdoc.md#tests) for more details. | Test suite | Purpose | |------------------|--------------------------------------------------------------------------| From 59f11cdfe58f0b42525e129320670bb725aaebc8 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 18 Mar 2025 13:29:14 -0500 Subject: [PATCH 150/447] update filename in link --- src/rustdoc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rustdoc.md b/src/rustdoc.md index 5ac62aa2c..320dc9d58 100644 --- a/src/rustdoc.md +++ b/src/rustdoc.md @@ -97,7 +97,7 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) * The tests on the structure of rustdoc HTML output are located in `tests/rustdoc`, where they're handled by the test runner of bootstrap and the supplementary script `src/etc/htmldocck.py`. - [These tests have several extra directives available to them](./rustdoc-internals/htmldocck.md). + [These tests have several extra directives available to them](./rustdoc-internals/rustdoc-test-suite.md). [TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html From 531e5f9d35cea141f8205fb137e4135b5fb87709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 19 Mar 2025 09:36:05 +0100 Subject: [PATCH 151/447] Set linkcheck in `ci.yml` --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22a4fb190..415d0dc39 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,7 @@ jobs: 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 }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 86aa63456e4e5747c9c57a70dc047e5bb5252dbd Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 19 Mar 2025 18:06:50 +0200 Subject: [PATCH 152/447] use correct code block markers This makes this command pass mdbook test --chapter "Remarks on perma-unstable features" --- src/rustc-driver/remarks-on-perma-unstable-features.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/rustc-driver/remarks-on-perma-unstable-features.md b/src/rustc-driver/remarks-on-perma-unstable-features.md index c307adc00..b434cfc9c 100644 --- a/src/rustc-driver/remarks-on-perma-unstable-features.md +++ b/src/rustc-driver/remarks-on-perma-unstable-features.md @@ -1,4 +1,3 @@ - # Remarks on perma unstable features ## `rustc_private` @@ -18,7 +17,7 @@ When using the `rustc_private` feature with official Rust toolchains distributed Install both components using rustup: -```bash +```text rustup component add rustc-dev llvm-tools ``` @@ -26,7 +25,7 @@ rustup component add rustc-dev llvm-tools Without the `llvm-tools` component, you'll encounter linking errors like: -``` +```text error: linking with `cc` failed: exit status: 1 | = note: rust-lld: error: unable to find library -lLLVM-{version} @@ -45,7 +44,7 @@ For custom-built toolchains or environments not using rustup, additional configu 1. **Check LLVM installation**: Verify LLVM is installed and accessible 2. **Configure library paths**: You may need to set environment variables: - ```bash + ```text export LD_LIBRARY_PATH=/path/to/llvm/lib:$LD_LIBRARY_PATH ``` 3. **Check version compatibility**: Ensure your LLVM version is compatible with your Rust toolchain From 0da80bbea1399badc98b2734201d50b7ddee418d Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 20 Mar 2025 12:40:51 +0800 Subject: [PATCH 153/447] Disambiguate between wg-llvm and icebreakers-llvm in rustc-dev-guide --- src/notification-groups/about.md | 4 ++-- src/notification-groups/llvm.md | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/notification-groups/about.md b/src/notification-groups/about.md index 74629aa08..af305f010 100644 --- a/src/notification-groups/about.md +++ b/src/notification-groups/about.md @@ -23,7 +23,7 @@ Here's the list of the notification groups: - [ARM](./arm.md) - [Cleanup Crew](./cleanup-crew.md) - [Emscripten](./emscripten.md) -- [LLVM](./llvm.md) +- [LLVM Icebreakers](./llvm.md) - [RISC-V](./risc-v.md) - [WASI](./wasi.md) - [WebAssembly](./wasm.md) @@ -83,7 +83,7 @@ group. For example: @rustbot ping arm @rustbot ping cleanup-crew @rustbot ping emscripten -@rustbot ping llvm +@rustbot ping icebreakers-llvm @rustbot ping risc-v @rustbot ping wasi @rustbot ping wasm diff --git a/src/notification-groups/llvm.md b/src/notification-groups/llvm.md index 2eff63713..9d0087285 100644 --- a/src/notification-groups/llvm.md +++ b/src/notification-groups/llvm.md @@ -1,13 +1,16 @@ -# LLVM Notification group +# LLVM Icebreakers Notification group **Github Label:** [A-LLVM]
-**Ping command:** `@rustbot ping llvm` +**Ping command:** `@rustbot ping icebreakers-llvm` [A-LLVM]: https://github.com/rust-lang/rust/labels/A-LLVM -The "LLVM Notification Group" are focused on bugs that center around LLVM. -These bugs often arise because of LLVM optimizations gone awry, or as -the result of an LLVM upgrade. The goal here is: +*Note*: this notification group is *not* the same as the LLVM working group +(WG-llvm). + +The "LLVM Icebreakers Notification Group" are focused on bugs that center around +LLVM. These bugs often arise because of LLVM optimizations gone awry, or as the +result of an LLVM upgrade. The goal here is: - to determine whether the bug is a result of us generating invalid LLVM IR, or LLVM misoptimizing; From b5522c1f58497500ccee7e40b9e945c1daf30fd2 Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 20 Mar 2025 17:30:18 +0000 Subject: [PATCH 154/447] Update `ParamEnv` section for `TypingEnv` changes --- src/SUMMARY.md | 5 +- src/appendix/code-index.md | 2 +- src/const-eval.md | 2 +- src/param_env/param_env_acquisition.md | 43 ---- .../param_env_construction_internals.md | 83 ------- src/param_env/param_env_summary.md | 18 -- src/param_env/param_env_what_is_it.md | 59 ----- src/traits/caching.md | 2 +- src/traits/resolution.md | 2 +- src/typing_parameter_envs.md | 206 ++++++++++++++++++ 10 files changed, 211 insertions(+), 211 deletions(-) delete mode 100644 src/param_env/param_env_acquisition.md delete mode 100644 src/param_env/param_env_construction_internals.md delete mode 100644 src/param_env/param_env_summary.md delete mode 100644 src/param_env/param_env_what_is_it.md create mode 100644 src/typing_parameter_envs.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 075d5af4c..c5d046015 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -146,10 +146,7 @@ - [ADTs and Generic Arguments](./ty_module/generic_arguments.md) - [Parameter types/consts/regions](./ty_module/param_ty_const_regions.md) - [`TypeFolder` and `TypeFoldable`](./ty-fold.md) -- [Parameter Environments](./param_env/param_env_summary.md) - - [What is it?](./param_env/param_env_what_is_it.md) - - [How are `ParamEnv`'s constructed internally](./param_env/param_env_construction_internals.md) - - [Which `ParamEnv` do I use?](./param_env/param_env_acquisition.md) +- [Typing/Param Envs](./typing_parameter_envs.md) - [Type inference](./type-inference.md) - [Trait solving](./traits/resolution.md) - [Higher-ranked trait bounds](./traits/hrtb.md) diff --git a/src/appendix/code-index.md b/src/appendix/code-index.md index b96ede68e..65fbf752d 100644 --- a/src/appendix/code-index.md +++ b/src/appendix/code-index.md @@ -40,5 +40,5 @@ Item | Kind | Short description | Chapter | [Emitting Diagnostics]: ../diagnostics.html [Macro expansion]: ../macro-expansion.html [Name resolution]: ../name-resolution.html -[Parameter Environment]: ../param_env/param_env_summary.html +[Parameter Environment]: ../typing_parameter_envs.html [Trait Solving: Goals and Clauses]: ../traits/goals-and-clauses.html#domain-goals diff --git a/src/const-eval.md b/src/const-eval.md index 69329a3e0..ca6a35a5e 100644 --- a/src/const-eval.md +++ b/src/const-eval.md @@ -35,7 +35,7 @@ They're the wrappers of the `const_eval` query. Statics are special; all other functions do not represent statics correctly and have thus assertions preventing their use on statics. -The `const_eval_*` functions use a [`ParamEnv`](./param_env/param_env_summary.html) of environment +The `const_eval_*` functions use a [`ParamEnv`](./typing_parameter_envs.html) of environment in which the constant is evaluated (e.g. the function within which the constant is used) and a [`GlobalId`]. The `GlobalId` is made up of an `Instance` referring to a constant or static or of an `Instance` of a function and an index into the function's `Promoted` table. diff --git a/src/param_env/param_env_acquisition.md b/src/param_env/param_env_acquisition.md deleted file mode 100644 index f6cff2d6c..000000000 --- a/src/param_env/param_env_acquisition.md +++ /dev/null @@ -1,43 +0,0 @@ - -# Which `ParamEnv` do I use? - -When needing a [`ParamEnv`][pe] in the compiler there are a few options for obtaining one: -- The correct env is already in scope simply use it (or pass it down the call stack to where you are). -- The [`tcx.param_env(def_id)` query][param_env_query] -- Use [`ParamEnv::new`][param_env_new] to construct an env with an arbitrary set of where clauses. Then call [`traits::normalize_param_env_or_error`][normalize_env_or_error] which will handle normalizing and elaborating all the where clauses in the env for you. -- Creating an empty environment via [`ParamEnv::reveal_all`][env_reveal_all] or [`ParamEnv::empty`][env_empty] - -In the large majority of cases a `ParamEnv` when required already exists somewhere in scope or above in the call stack and should be passed down. A non exhaustive list of places where you might find an existing `ParamEnv`: -- During typeck `FnCtxt` has a [`param_env` field][fnctxt_param_env] -- When writing late lints the `LateContext` has a [`param_env` field][latectxt_param_env] -- During well formedness checking the `WfCheckingCtxt` has a [`param_env` field][wfckctxt_param_env] -- The `TypeChecker` used by Mir Typeck has a [`param_env` field][mirtypeck_param_env] -- In the next-gen trait solver all `Goal`s have a [`param_env` field][goal_param_env] specifying what environment to prove the goal in -- When editing an existing [`TypeRelation`][typerelation] if it implements `PredicateEmittingRelation` then a [`param_env` method][typerelation_param_env] will be available. - -Using the `param_env` query to obtain an env is generally done at the start of some kind of analysis and then passed everywhere that a `ParamEnv` is required. For example the type checker will create a `ParamEnv` for the item it is type checking and then pass it around everywhere. - -Creating an env from an arbitrary set of where clauses is usually unnecessary and should only be done if the environment you need does not correspond to an actual item in the source code (i.e. [`compare_method_predicate_entailment`][method_pred_entailment] as mentioned earlier). - -Creating an empty environment via `ParamEnv::empty` is almost always wrong. There are very few places where we actually know that the environment should be empty. One of the only places where we do actually know this is after monomorphization, however the `ParamEnv` there should be constructed via `ParamEnv::reveal_all` instead as at this point we should be able to determine the hidden type of opaque types. Codegen/Post-mono is one of the only places that should be using `ParamEnv::reveal_all`. - -An additional piece of complexity here is specifying the `Reveal` (see linked docs for explanation of what reveal does) used for the `ParamEnv`. When constructing a param env using the `param_env` query it will have `Reveal::UserFacing`, if `Reveal::All` is desired then the [`tcx.param_env_reveal_all_normalized`][env_reveal_all_normalized] query can be used instead. - -The `ParamEnv` type has a method [`ParamEnv::with_reveal_all_normalized`][with_reveal_all] which converts an existing `ParamEnv` into one with `Reveal::All` specified. Where possible the previously mentioned query should be preferred as it is more efficient. - -[param_env_new]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.new -[normalize_env_or_error]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/fn.normalize_param_env_or_error.html -[fnctxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env -[latectxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html#structfield.param_env -[wfckctxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/wfcheck/struct.WfCheckingCtxt.html#structfield.param_env -[goal_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/canonical/ir/solve/struct.Goal.html#structfield.param_env -[typerelation_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/trait.PredicateEmittingRelation.html#tymethod.param_env -[typerelation]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/relate/trait.TypeRelation.html -[mirtypeck_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/type_check/struct.TypeChecker.html#structfield.param_env -[env_reveal_all_normalized]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env_reveal_all_normalized -[with_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.with_reveal_all_normalized -[env_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.reveal_all -[env_empty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.empty -[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html -[param_env_query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env -[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html diff --git a/src/param_env/param_env_construction_internals.md b/src/param_env/param_env_construction_internals.md deleted file mode 100644 index 69a262a17..000000000 --- a/src/param_env/param_env_construction_internals.md +++ /dev/null @@ -1,83 +0,0 @@ - -# How are `ParamEnv`'s constructed internally? - -Creating a [`ParamEnv`][pe] is more complicated than simply using the list of where clauses defined on an item as written by the user. We need to both elaborate supertraits into the env and fully normalize all aliases. This logic is handled by [`traits::normalize_param_env_or_error`][normalize_env_or_error] (even though it does not mention anything about elaboration). - -## Elaborating supertraits - -When we have a function such as `fn foo()` we would like to be able to prove `T: Clone` inside of the function as the `Copy` trait has a `Clone` supertrait. Constructing a `ParamEnv` looks at all of the trait bounds in the env and explicitly adds new where clauses to the `ParamEnv` for any supertraits found on the traits. - -A concrete example would be the following function: -```rust -trait Trait: SuperTrait {} -trait SuperTrait: SuperSuperTrait {} - -// `bar`'s unelaborated `ParamEnv` would be: -// `[T: Sized, T: Copy, T: Trait]` -fn bar(a: T) { - requires_impl(a); -} - -fn requires_impl(a: T) {} -``` - -If we did not elaborate the env then the `requires_impl` call would fail to typecheck as we would not be able to prove `T: Clone` or `T: SuperSuperTrait`. In practice we elaborate the env which means that `bar`'s `ParamEnv` is actually: -`[T: Sized, T: Copy, T: Clone, T: Trait, T: SuperTrait, T: SuperSuperTrait]` -This allows us to prove `T: Clone` and `T: SuperSuperTrait` when type checking `bar`. - -The `Clone` trait has a `Sized` supertrait however we do not end up with two `T: Sized` bounds in the env (one for the supertrait and one for the implicitly added `T: Sized` bound). This is because the elaboration process (implemented via [`util::elaborate`][elaborate]) deduplicates the where clauses to avoid this. - -As a side effect this also means that even if no actual elaboration of supertraits takes place, the existing where clauses in the env are _also_ deduplicated. See the following example: -```rust -trait Trait {} -// The unelaborated `ParamEnv` would be: -// `[T: Sized, T: Trait, T: Trait]` -// but after elaboration it would be: -// `[T: Sized, T: Trait]` -fn foo() {} -``` - -The [next-gen trait solver][next-gen-solver] also requires this elaboration to take place. - -[elaborate]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/traits/util/fn.elaborate.html -[next-gen-solver]: ../solve/trait-solving.md - -## Normalizing all bounds - -In the old trait solver the where clauses stored in `ParamEnv` are required to be fully normalized or else the trait solver will not function correctly. A concrete example of needing to normalize the `ParamEnv` is the following: -```rust -trait Trait { - type Assoc; -} - -trait Other { - type Bar; -} - -impl Other for T { - type Bar = u32; -} - -// `foo`'s unnormalized `ParamEnv` would be: -// `[T: Sized, U: Sized, U: Trait]` -fn foo(a: U) -where - U: Trait<::Bar>, -{ - requires_impl(a); -} - -fn requires_impl>(_: U) {} -``` - -As humans we can tell that `::Bar` is equal to `u32` so the trait bound on `U` is equivalent to `U: Trait`. In practice trying to prove `U: Trait` in the old solver in this environment would fail as it is unable to determine that `::Bar` is equal to `u32`. - -To work around this we normalize `ParamEnv`'s after constructing them so that `foo`'s `ParamEnv` is actually: `[T: Sized, U: Sized, U: Trait]` which means the trait solver is now able to use the `U: Trait` in the `ParamEnv` to determine that the trait bound `U: Trait` holds. - -This workaround does not work in all cases as normalizing associated types requires a `ParamEnv` which introduces a bootstrapping problem. We need a normalized `ParamEnv` in order for normalization to give correct results, but we need to normalize to get that `ParamEnv`. Currently we normalize the `ParamEnv` once using the unnormalized param env and it tends to give okay results in practice even though there are some examples where this breaks ([example]). - -In the next-gen trait solver the requirement for all where clauses in the `ParamEnv` to be fully normalized is not present and so we do not normalize when constructing `ParamEnv`s. - -[example]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e6933265ea3e84eaa47019465739992c -[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html -[normalize_env_or_error]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/fn.normalize_param_env_or_error.html diff --git a/src/param_env/param_env_summary.md b/src/param_env/param_env_summary.md deleted file mode 100644 index 0ff6d8fc3..000000000 --- a/src/param_env/param_env_summary.md +++ /dev/null @@ -1,18 +0,0 @@ -# The `ParamEnv` type - -## Summary - -The [`ParamEnv`][pe] is used to store information about the environment that we are interacting with the type system from. For example the set of in-scope where-clauses is stored in `ParamEnv` as it differs between each item whereas the list of user written impls is not stored in the `ParamEnv` as this does not change for each item. - -This chapter of the dev guide covers: -- A high level summary of what a `ParamEnv` is and what it is used for -- Technical details about what the process of constructing a `ParamEnv` involves -- Guidance about how to acquire a `ParamEnv` when one is required - -## Bundling - -A useful API on `ParamEnv` is the [`and`][and] method which allows bundling a value with the `ParamEnv`. The `and` method produces a [`ParamEnvAnd`][pea] making it clearer that using the inner value is intended to be done in that specific environment. - -[and]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.and -[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html -[pea]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnvAnd.html \ No newline at end of file diff --git a/src/param_env/param_env_what_is_it.md b/src/param_env/param_env_what_is_it.md deleted file mode 100644 index 5c2f4d594..000000000 --- a/src/param_env/param_env_what_is_it.md +++ /dev/null @@ -1,59 +0,0 @@ - -# What is a `ParamEnv`? - -The type system relies on information in the environment in order for it to function correctly. This information is stored in the [`ParamEnv`][pe] type and it is important to use the correct `ParamEnv` when interacting with the type system. - -The information represented by `ParamEnv` is a list of in-scope where-clauses, and a `Reveal` (see linked docs for more information). A `ParamEnv` typically corresponds to a specific item's where clauses, some clauses are not explicitly written bounds and instead are implicitly added in [`predicates_of`][predicates_of] such as `ConstArgHasType` or some implied bounds. - -A `ParamEnv` can also be created with arbitrary data that is not derived from a specific item such as in [`compare_method_predicate_entailment`][method_pred_entailment] which creates a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses. - -If we have a function such as: -```rust -// `foo` would have a `ParamEnv` of: -// `[T: Sized, T: Trait, ::Assoc: Clone]` -fn foo() -where - ::Assoc: Clone, -{} -``` -If we were conceptually inside of `foo` (for example, type-checking or linting it) we would use this `ParamEnv` everywhere that we interact with the type system. This would allow things such as normalization (TODO: write a chapter about normalization and link it), evaluating generic constants, and proving where clauses/goals, to rely on `T` being sized, implementing `Trait`, etc. - -A more concrete example: -```rust -// `foo` would have a `ParamEnv` of: -// `[T: Sized, T: Clone]` -fn foo(a: T) { - // when typechecking `foo` we require all the where clauses on `bar` - // to hold in order for it to be legal to call. This means we have to - // prove `T: Clone`. As we are type checking `foo` we use `foo`'s - // environment when trying to check that `T: Clone` holds. - // - // Trying to prove `T: Clone` with a `ParamEnv` of `[T: Sized, T: Clone]` - // will trivially succeed as bound we want to prove is in our environment. - requires_clone(a); -} -``` - -Or alternatively an example that would not compile: -```rust -// `foo2` would have a `ParamEnv` of: -// `[T: Sized]` -fn foo2(a: T) { - // When typechecking `foo2` we attempt to prove `T: Clone`. - // As we are type checking `foo2` we use `foo2`'s environment - // when trying to prove `T: Clone`. - // - // Trying to prove `T: Clone` with a `ParamEnv` of `[T: Sized]` will - // fail as there is nothing in the environment telling the trait solver - // that `T` implements `Clone` and there exists no user written impl - // that could apply. - requires_clone(a); -} -``` - -It's very important to use the correct `ParamEnv` when interacting with the type system as otherwise it can lead to ICEs or things compiling when they shouldn't (or vice versa). See [#82159](https://github.com/rust-lang/rust/pull/82159) and [#82067](https://github.com/rust-lang/rust/pull/82067) as examples of PRs that changed rustc to use the correct param env to avoid ICE. Determining how to acquire the correct `ParamEnv` is explained later in this chapter. - -[predicates_of]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/collect/predicates_of/fn.predicates_of.html -[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html -[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html -[query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env diff --git a/src/traits/caching.md b/src/traits/caching.md index a9f20969b..c44722a1d 100644 --- a/src/traits/caching.md +++ b/src/traits/caching.md @@ -61,7 +61,7 @@ to be pretty clearly safe and also still retains a very high hit rate **TODO**: it looks like `pick_candidate_cache` no longer exists. In general, is this section still accurate at all? -[`ParamEnv`]: ../param_env/param_env_summary.html +[`ParamEnv`]: ../typing_parameter_envs.html [`tcx`]: ../ty.html [#18290]: https://github.com/rust-lang/rust/issues/18290 [#22019]: https://github.com/rust-lang/rust/issues/22019 diff --git a/src/traits/resolution.md b/src/traits/resolution.md index 26eb72458..c62b05936 100644 --- a/src/traits/resolution.md +++ b/src/traits/resolution.md @@ -183,7 +183,7 @@ in that list. If so, it is considered satisfied. More precisely, we want to check whether there is a where-clause obligation that is for the same trait (or some subtrait) and which can match against the obligation. -[parameter environment]: ../param_env/param_env_summary.html +[parameter environment]: ../typing_parameter_envs.html Consider this simple example: diff --git a/src/typing_parameter_envs.md b/src/typing_parameter_envs.md new file mode 100644 index 000000000..757296d1f --- /dev/null +++ b/src/typing_parameter_envs.md @@ -0,0 +1,206 @@ +# Typing/Parameter Environments + + + +## Typing Environments + +When interacting with the type system there are a few variables to consider that can affect the results of trait solving. The 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). + +When an environment to perform type system operations in has not yet been created, the [`TypingEnv`][tenv] can be used to bundle all of the external context required into a single type. + +Once a context to perform type system operations in has been created (e.g. an [`ObligationCtxt`][ocx] or [`FnCtxt`][fnctxt]) a `TypingEnv` is typically not stored anywhere as only the `TypingMode` is a property of the whole environment, whereas different `ParamEnv`s can be used on a per-goal basis. + +[ocx]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/struct.ObligationCtxt.html +[fnctxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html + +## Parameter Environemnts + +### What is a `ParamEnv` + +The [`ParamEnv`][penv] is a list of in-scope where-clauses, it typically corresponds to a specific item's where clauses. Some clauses are not explicitly written but are instead are implicitly added in the [`predicates_of`][predicates_of] query, such as `ConstArgHasType` or (some) implied bounds. + +In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses. A `ParamEnv` can also be created with arbitrary sets of clauses that are not derived from a specific item, such as in [`compare_method_predicate_entailment`][method_pred_entailment] where we create a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. + +--- + +If we have a function such as: +```rust +// `foo` would have a `ParamEnv` of: +// `[T: Sized, T: Trait, ::Assoc: Clone]` +fn foo() +where + ::Assoc: Clone, +{} +``` +If we were conceptually inside of `foo` (for example, type-checking or linting it) we would use this `ParamEnv` everywhere that we interact with the type system. This would allow things such as normalization (TODO: write a chapter about normalization and link it), evaluating generic constants, and proving where clauses/goals, to rely on `T` being sized, implementing `Trait`, etc. + +A more concrete example: +```rust +// `foo` would have a `ParamEnv` of: +// `[T: Sized, T: Clone]` +fn foo(a: T) { + // when typechecking `foo` we require all the where clauses on `requires_clone` + // to hold in order for it to be legal to call. This means we have to + // prove `T: Clone`. As we are type checking `foo` we use `foo`'s + // environment when trying to check that `T: Clone` holds. + // + // Trying to prove `T: Clone` with a `ParamEnv` of `[T: Sized, T: Clone]` + // will trivially succeed as bound we want to prove is in our environment. + requires_clone(a); +} +``` + +Or alternatively an example that would not compile: +```rust +// `foo2` would have a `ParamEnv` of: +// `[T: Sized]` +fn foo2(a: T) { + // When typechecking `foo2` we attempt to prove `T: Clone`. + // As we are type checking `foo2` we use `foo2`'s environment + // when trying to prove `T: Clone`. + // + // Trying to prove `T: Clone` with a `ParamEnv` of `[T: Sized]` will + // fail as there is nothing in the environment telling the trait solver + // that `T` implements `Clone` and there exists no user written impl + // that could apply. + requires_clone(a); +} +``` + +[predicates_of]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/collect/predicates_of/fn.predicates_of.html +[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html +[query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env + +### Acquiring a `ParamEnv` + +Using the wrong [`ParamEnv`][penv] when interacting with the type system can lead to ICEs, illformed programs compiling, or erroing when we shouldn't. See [#82159](https://github.com/rust-lang/rust/pull/82159) and [#82067](https://github.com/rust-lang/rust/pull/82067) as examples of PRs that modified the compiler to use the correct param env and in the process fixed ICEs. + +In the large majority of cases, when a `ParamEnv` is required it either already exists somewhere in scope, or above in the call stack and should be passed down. A non exhaustive list of places where you might find an existing `ParamEnv`: +- During typeck `FnCtxt` has a [`param_env` field][fnctxt_param_env] +- When writing late lints the `LateContext` has a [`param_env` field][latectxt_param_env] +- During well formedness checking the `WfCheckingCtxt` has a [`param_env` field][wfckctxt_param_env] +- The `TypeChecker` used for MIR Typeck has a [`param_env` field][mirtypeck_param_env] +- In the next-gen trait solver all `Goal`s have a [`param_env` field][goal_param_env] specifying what environment to prove the goal in +- When editing an existing [`TypeRelation`][typerelation] if it implements [`PredicateEmittingRelation`][predicate_emitting_relation] then a [`param_env` method][typerelation_param_env] will be available. + +If you aren't sure if there's a `ParamEnv` in scope somewhere that can be used it can be worth opening a thread in the [`#t-compiler/help`][compiler_help] zulip stream where someone may be able to point out where a `ParamEnv` can be acquired from. + +Manually constructing a `ParamEnv` is typically only needed at the start of some kind of top level analysis (e.g. hir typeck or borrow checking). In such cases there are three ways it can be done: +- Calling the [`tcx.param_env(def_id)` query][param_env_query] which returns the environment associated with a given definition. +- Creating an empty environment with [`ParamEnv::empty`][env_empty]. +- Using [`ParamEnv::new`][param_env_new] to construct an env with an arbitrary set of where clauses. Then calling [`traits::normalize_param_env_or_error`][normalize_env_or_error] to handle normalizing and elaborating all the where clauses in the env. + +Using the `param_env` query is by far the most common way to construct a `ParamEnv` as most of the time the compiler is performing an analysis as part of some specific definition. + +Creating an empty environment with `ParamEnv::empty` is typically only done either in codegen (indirectly via [`TypingEnv::fully_monomorphized`][tenv_mono]), or as part of some analysis that do not expect to ever encounter generic parameters (e.g. various parts of coherence/orphan check). + +Creating an env from an arbitrary set of where clauses is usually unnecessary and should only be done if the environment you need does not correspond to an actual item in the source code (e.g. [`compare_method_predicate_entailment`][method_pred_entailment]). + +[param_env_new]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.new +[normalize_env_or_error]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/fn.normalize_param_env_or_error.html +[fnctxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env +[latectxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html#structfield.param_env +[wfckctxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/wfcheck/struct.WfCheckingCtxt.html#structfield.param_env +[goal_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/canonical/ir/solve/struct.Goal.html#structfield.param_env +[typerelation_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/trait.PredicateEmittingRelation.html#tymethod.param_env +[typerelation]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/relate/trait.TypeRelation.html +[mirtypeck_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/type_check/struct.TypeChecker.html#structfield.param_env +[env_empty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.empty +[param_env_query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env +[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html +[predicate_emitting_relation]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/relate/combine/trait.PredicateEmittingRelation.html +[tenv_mono]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypingEnv.html#method.fully_monomorphized +[compiler_help]: https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp + +### How are `ParamEnv`s constructed + +Creating a [`ParamEnv`][pe] is more complicated than simply using the list of where clauses defined on an item as written by the user. We need to both elaborate supertraits into the env and fully normalize all aliases. This logic is handled by [`traits::normalize_param_env_or_error`][normalize_env_or_error] (even though it does not mention anything about elaboration). + +#### Elaborating supertraits + +When we have a function such as `fn foo()` we would like to be able to prove `T: Clone` inside of the function as the `Copy` trait has a `Clone` supertrait. Constructing a `ParamEnv` looks at all of the trait bounds in the env and explicitly adds new where clauses to the `ParamEnv` for any supertraits found on the traits. + +A concrete example would be the following function: +```rust +trait Trait: SuperTrait {} +trait SuperTrait: SuperSuperTrait {} + +// `bar`'s unelaborated `ParamEnv` would be: +// `[T: Sized, T: Copy, T: Trait]` +fn bar(a: T) { + requires_impl(a); +} + +fn requires_impl(a: T) {} +``` + +If we did not elaborate the env then the `requires_impl` call would fail to typecheck as we would not be able to prove `T: Clone` or `T: SuperSuperTrait`. In practice we elaborate the env which means that `bar`'s `ParamEnv` is actually: +`[T: Sized, T: Copy, T: Clone, T: Trait, T: SuperTrait, T: SuperSuperTrait]` +This allows us to prove `T: Clone` and `T: SuperSuperTrait` when type checking `bar`. + +The `Clone` trait has a `Sized` supertrait however we do not end up with two `T: Sized` bounds in the env (one for the supertrait and one for the implicitly added `T: Sized` bound) as the elaboration process (implemented via [`util::elaborate`][elaborate]) deduplicates where clauses. + +A side effect of this is that even if no actual elaboration of supertraits takes place, the existing where clauses in the env are _also_ deduplicated. See the following example: +```rust +trait Trait {} +// The unelaborated `ParamEnv` would be: +// `[T: Sized, T: Trait, T: Trait]` +// but after elaboration it would be: +// `[T: Sized, T: Trait]` +fn foo() {} +``` + +The [next-gen trait solver][next-gen-solver] also requires this elaboration to take place. + +[elaborate]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/traits/util/fn.elaborate.html +[next-gen-solver]: ./solve/trait-solving.md + +#### Normalizing all bounds + +In the old trait solver the where clauses stored in `ParamEnv` are required to be fully normalized as otherwise the trait solver will not function correctly. A concrete example of needing to normalize the `ParamEnv` is the following: +```rust +trait Trait { + type Assoc; +} + +trait Other { + type Bar; +} + +impl Other for T { + type Bar = u32; +} + +// `foo`'s unnormalized `ParamEnv` would be: +// `[T: Sized, U: Sized, U: Trait]` +fn foo(a: U) +where + U: Trait<::Bar>, +{ + requires_impl(a); +} + +fn requires_impl>(_: U) {} +``` + +As humans we can tell that `::Bar` is equal to `u32` so the trait bound on `U` is equivalent to `U: Trait`. In practice trying to prove `U: Trait` in the old solver in this environment would fail as it is unable to determine that `::Bar` is equal to `u32`. + +To work around this we normalize `ParamEnv`'s after constructing them so that `foo`'s `ParamEnv` is actually: `[T: Sized, U: Sized, U: Trait]` which means the trait solver is now able to use the `U: Trait` in the `ParamEnv` to determine that the trait bound `U: Trait` holds. + +This workaround does not work in all cases as normalizing associated types requires a `ParamEnv` which introduces a bootstrapping problem. We need a normalized `ParamEnv` in order for normalization to give correct results, but we need to normalize to get that `ParamEnv`. Currently we normalize the `ParamEnv` once using the unnormalized param env and it tends to give okay results in practice even though there are some examples where this breaks ([example]). + +In the next-gen trait solver the requirement for all where clauses in the `ParamEnv` to be fully normalized is not present and so we do not normalize when constructing `ParamEnv`s. + +[example]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e6933265ea3e84eaa47019465739992c +[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html +[normalize_env_or_error]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/fn.normalize_param_env_or_error.html + +## Typing Modes + +Depending on what context we are performing type system operations in, different behaviour may be required. For example during coherence there are stronger requirements about when we can consider goals to not hold or when we can consider types to be unequal. + +Tracking which "phase" of the compiler type system operations are being performed in is done by the [`TypingMode`][tenv] enum. The documentation on the `TypingMode` enum is quite good so instead of repeating it here verbatim we would recommend reading the API documentation directly. + +[penv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html +[tenv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/infer_ctxt/enum.TypingMode.html +[tmode]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.TypingMode.html From 8c3302aa5f2bffecb6d983ea5afe652b38ab036b Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 21 Mar 2025 16:18:43 +0800 Subject: [PATCH 155/447] Move Fuchsia and RfL under `ecosystem-test-jobs/` folder Includes redirects to avoid breaking existing links. --- book.toml | 4 +++- src/SUMMARY.md | 4 ++-- src/notification-groups/fuchsia.md | 2 +- src/tests/{ => ecosystem-test-jobs}/fuchsia.md | 4 ++-- src/tests/{ => ecosystem-test-jobs}/rust-for-linux.md | 2 +- src/tests/ecosystem.md | 4 ++-- 6 files changed, 11 insertions(+), 9 deletions(-) rename src/tests/{ => ecosystem-test-jobs}/fuchsia.md (98%) rename src/tests/{ => ecosystem-test-jobs}/rust-for-linux.md (97%) diff --git a/book.toml b/book.toml index 67069d993..eb2f6806b 100644 --- a/book.toml +++ b/book.toml @@ -62,5 +62,7 @@ warning-policy = "error" "/diagnostics/sessiondiagnostic.html" = "diagnostic-structs.html" "/diagnostics/diagnostic-codes.html" = "error-codes.html" "/miri.html" = "const-eval/interpret.html" -"/tests/integration.html" = "ecosystem.html" +"/tests/fuchsia.html" = "ecosystem-test-jobs/fuchsia.html" "/tests/headers.html" = "directives.html" +"/tests/integration.html" = "ecosystem.html" +"/tests/rust-for-linux.html" = "ecosystem-test-jobs/rust-for-linux.html" diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 075d5af4c..8fc4fd33e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -28,8 +28,8 @@ - [Minicore](./tests/minicore.md) - [Ecosystem testing](./tests/ecosystem.md) - [Crater](./tests/crater.md) - - [Fuchsia](./tests/fuchsia.md) - - [Rust for Linux](./tests/rust-for-linux.md) + - [Fuchsia](./tests/ecosystem-test-jobs/fuchsia.md) + - [Rust for Linux](./tests/ecosystem-test-jobs/rust-for-linux.md) - [Performance testing](./tests/perf.md) - [Suggest tests tool](./tests/suggest-tests.md) - [Misc info](./tests/misc.md) diff --git a/src/notification-groups/fuchsia.md b/src/notification-groups/fuchsia.md index a4658e0d8..e3c1a7148 100644 --- a/src/notification-groups/fuchsia.md +++ b/src/notification-groups/fuchsia.md @@ -9,4 +9,4 @@ This list will be used to notify [Fuchsia][fuchsia] maintainers when the compiler or the standard library changes in a way that would break the Fuchsia integration. -[fuchsia]: ../tests/fuchsia.md +[fuchsia]: ../tests/ecosystem-test-jobs/fuchsia.md diff --git a/src/tests/fuchsia.md b/src/tests/ecosystem-test-jobs/fuchsia.md similarity index 98% rename from src/tests/fuchsia.md rename to src/tests/ecosystem-test-jobs/fuchsia.md index 2766c362c..b19d94d6f 100644 --- a/src/tests/fuchsia.md +++ b/src/tests/ecosystem-test-jobs/fuchsia.md @@ -40,7 +40,7 @@ using your local Rust toolchain. src/ci/docker/run.sh x86_64-fuchsia ``` -See the [Testing with Docker](docker.md) chapter for more details on how to run +See the [Testing with Docker](../docker.md) chapter for more details on how to run and debug jobs with Docker. Note that a Fuchsia checkout is *large* – as of this writing, a checkout and @@ -170,7 +170,7 @@ rustc book][platform-support]. [`public_configs`]: https://gn.googlesource.com/gn/+/main/docs/reference.md#var_public_configs [`//build/config:compiler`]: https://cs.opensource.google/fuchsia/fuchsia/+/main:build/config/BUILD.gn;l=121;drc=c26c473bef93b33117ae417893118907a026fec7 [build system]: https://fuchsia.dev/fuchsia-src/development/build/build_system -[fuchsia-ping]: ../notification-groups/fuchsia.md +[fuchsia-ping]: ../../notification-groups/fuchsia.md [^loc]: As of June 2024, Fuchsia had about 2 million lines of first-party Rust code and a roughly equal amount of third-party code, as counted by tokei diff --git a/src/tests/rust-for-linux.md b/src/tests/ecosystem-test-jobs/rust-for-linux.md similarity index 97% rename from src/tests/rust-for-linux.md rename to src/tests/ecosystem-test-jobs/rust-for-linux.md index bdf32ffc3..d549ec6fc 100644 --- a/src/tests/rust-for-linux.md +++ b/src/tests/ecosystem-test-jobs/rust-for-linux.md @@ -48,4 +48,4 @@ line to your PR description: Then when you `@bors try` it will pick the job that builds the Rust for Linux integration. -[rfl-ping]: ../notification-groups/rust-for-linux.md +[rfl-ping]: ../../notification-groups/rust-for-linux.md diff --git a/src/tests/ecosystem.md b/src/tests/ecosystem.md index 083601404..f4b93492e 100644 --- a/src/tests/ecosystem.md +++ b/src/tests/ecosystem.md @@ -24,5 +24,5 @@ there aren't any significant regressions. We have CI jobs that build large open-source Rust projects that are used as regression tests in CI. Our integration jobs build the following projects: -- [Fuchsia](fuchsia.md) -- [Rust for Linux](rust-for-linux.md) +- [Fuchsia](./ecosystem-test-jobs/fuchsia.md) +- [Rust for Linux](./ecosystem-test-jobs/rust-for-linux.md) From b7fc809e0bf0fd1942a8c59eab4f5a29950b62c7 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 21 Mar 2025 16:35:46 +0800 Subject: [PATCH 156/447] Stub out codegen backend test pages --- src/SUMMARY.md | 3 +++ src/tests/codegen-backend-tests/cg_clif.md | 3 +++ src/tests/codegen-backend-tests/cg_gcc.md | 3 +++ src/tests/codegen-backend-tests/intro.md | 13 +++++++++++++ src/tests/intro.md | 8 ++++++-- 5 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 src/tests/codegen-backend-tests/cg_clif.md create mode 100644 src/tests/codegen-backend-tests/cg_gcc.md create mode 100644 src/tests/codegen-backend-tests/intro.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 8fc4fd33e..29085a6e8 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -30,6 +30,9 @@ - [Crater](./tests/crater.md) - [Fuchsia](./tests/ecosystem-test-jobs/fuchsia.md) - [Rust for Linux](./tests/ecosystem-test-jobs/rust-for-linux.md) + - [Codegen backend testing](./tests/codegen-backend-tests/intro.md) + - [Cranelift codegen backend](./tests/codegen-backend-tests/cg_clif.md) + - [GCC codegen backend](./tests/codegen-backend-tests/cg_gcc.md) - [Performance testing](./tests/perf.md) - [Suggest tests tool](./tests/suggest-tests.md) - [Misc info](./tests/misc.md) diff --git a/src/tests/codegen-backend-tests/cg_clif.md b/src/tests/codegen-backend-tests/cg_clif.md new file mode 100644 index 000000000..030ddd7df --- /dev/null +++ b/src/tests/codegen-backend-tests/cg_clif.md @@ -0,0 +1,3 @@ +# Cranelift codegen backend tests + +TODO: please add some more information to this page. diff --git a/src/tests/codegen-backend-tests/cg_gcc.md b/src/tests/codegen-backend-tests/cg_gcc.md new file mode 100644 index 000000000..4caf4c0e0 --- /dev/null +++ b/src/tests/codegen-backend-tests/cg_gcc.md @@ -0,0 +1,3 @@ +# GCC codegen backend tests + +TODO: please add some more information to this page. diff --git a/src/tests/codegen-backend-tests/intro.md b/src/tests/codegen-backend-tests/intro.md new file mode 100644 index 000000000..c4bac26ab --- /dev/null +++ b/src/tests/codegen-backend-tests/intro.md @@ -0,0 +1,13 @@ +# Codegen backend testing + +See also the [Code generation](../../../src/backend/codegen.md) chapter. + +In addition to the primary LLVM codegen backend, the rust-lang/rust CI also runs tests of the [cranelift][cg_clif] and [GCC][cg_gcc] codegen backends in certain test jobs. + +For more details on the tests involved, see: + +- [Cranelift codegen backend tests](./cg_clif.md) +- [GCC codegen backend tests](./cg_gcc.md) + +[cg_clif]: https://github.com/rust-lang/rustc_codegen_cranelift +[cg_gcc]: https://github.com/rust-lang/rustc_codegen_gcc diff --git a/src/tests/intro.md b/src/tests/intro.md index ba44a969b..7bf30b106 100644 --- a/src/tests/intro.md +++ b/src/tests/intro.md @@ -38,7 +38,7 @@ directory, and `x` will essentially run `cargo test` on that package. Examples: | Command | Description | -| ----------------------------------------- | ------------------------------------- | +|-------------------------------------------|---------------------------------------| | `./x test library/std` | Runs tests on `std` only | | `./x test library/core` | Runs tests on `core` only | | `./x test compiler/rustc_data_structures` | Runs tests on `rustc_data_structures` | @@ -86,7 +86,7 @@ above. Examples: | Command | Description | -| ----------------------- | ------------------------------------------------------------------ | +|-------------------------|--------------------------------------------------------------------| | `./x fmt --check` | Checks formatting and exits with an error if formatting is needed. | | `./x fmt` | Runs rustfmt across the entire codebase. | | `./x test tidy --bless` | First runs rustfmt to format the codebase, then runs tidy checks. | @@ -155,6 +155,10 @@ chapter](ecosystem.md) for more details. A separate infrastructure is used for testing and tracking performance of the compiler. See the [Performance testing chapter](perf.md) for more details. +### Codegen backend testing + +See [Codegen backend testing](./codegen-backend-tests/intro.md). + ## Miscellaneous information There are some other useful testing-related info at [Misc info](misc.md). From 6f9680da7a529d63167be8876bd5f431912f7f32 Mon Sep 17 00:00:00 2001 From: Chiichen Date: Sun, 23 Mar 2025 12:34:41 +0800 Subject: [PATCH 157/447] doc: fix reference to #create-a-configtoml --- src/building/prerequisites.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/building/prerequisites.md b/src/building/prerequisites.md index f49f6bb05..6761cabac 100644 --- a/src/building/prerequisites.md +++ b/src/building/prerequisites.md @@ -38,4 +38,4 @@ incremental compilation ([see here][config]). This will make compilation take longer (especially after a rebase), but will save a ton of space from the incremental caches. -[config]: ./how-to-build-and-run.md#create-a-configtoml +[config]: ./how-to-build-and-run.md#create-a-bootstraptoml From 07e905fbe6e9eb4d5a9b6c6ea227a4f9cd87ffb3 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 24 Mar 2025 10:40:03 +0200 Subject: [PATCH 158/447] add needed break --- src/rustdoc-internals/rustdoc-test-suite.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rustdoc-internals/rustdoc-test-suite.md b/src/rustdoc-internals/rustdoc-test-suite.md index c2a2e6495..471dd29f7 100644 --- a/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/rustdoc-internals/rustdoc-test-suite.md @@ -1,6 +1,7 @@ # The `rustdoc` test suite -This page is specifically about the test suite named `rustdoc`, for other test suites used for testing rustdoc, see [Rustdoc tests](../rustdoc.md#tests). +This page is specifically about the test suite named `rustdoc`. +For other test suites used for testing rustdoc, see [Rustdoc tests](../rustdoc.md#tests). The `rustdoc` test suite is specifically used to test the HTML output of rustdoc. From 55e47b61f5bf197654074c81e166cb515dbfd90a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 24 Mar 2025 10:41:19 +0200 Subject: [PATCH 159/447] typo --- src/rustdoc-internals/rustdoc-test-suite.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rustdoc-internals/rustdoc-test-suite.md b/src/rustdoc-internals/rustdoc-test-suite.md index 471dd29f7..169b95a7e 100644 --- a/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/rustdoc-internals/rustdoc-test-suite.md @@ -5,7 +5,7 @@ For other test suites used for testing rustdoc, see [Rustdoc tests](../rustdoc.m The `rustdoc` test suite is specifically used to test the HTML output of rustdoc. -This is achived by means of `htmldocck.py`, a custom checker script that leverages [XPath]. +This is achieved by means of `htmldocck.py`, a custom checker script that leverages [XPath]. [XPath]: https://en.wikipedia.org/wiki/XPath From 2e81955d9cf6660585d9567792f79d9214c1d293 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 23 Mar 2025 15:50:51 +0300 Subject: [PATCH 160/447] compiletest: Support matching on diagnostics without a span --- src/tests/ui.md | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index c8536b004..98bb9dee7 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -202,6 +202,9 @@ several ways to match the message with the line (see the examples below): * `~|`: Associates the error level and message with the *same* line as the *previous comment*. This is more convenient than using multiple carets when there are multiple messages associated with the same line. +* `~?`: Used to match error levels and messages with errors not having line + information. These can be placed on any line in the test file, but are + conventionally placed at the end. Example: @@ -270,10 +273,23 @@ fn main() { //~| ERROR this pattern has 1 field, but the corresponding tuple struct has 3 fields [E0023] ``` +#### Error without line information + +Use `//~?` to match an error without line information. +`//~?` is precise and will not match errors if their line information is available. +It should be preferred to using `error-pattern`, which is imprecise and non-exhaustive. + +```rust,ignore +//@ compile-flags: --print yyyy + +//~? ERROR unknown print request: `yyyy` +``` + ### `error-pattern` -The `error-pattern` [directive](directives.md) can be used for messages that don't -have a specific span. +The `error-pattern` [directive](directives.md) can be used for runtime messages, which don't +have a specific span, or for compile time messages if imprecise matching is required due to +multi-line platform specific diagnostics. Let's think about this test: @@ -300,7 +316,9 @@ fn main() { } ``` -But for strict testing, try to use the `ERROR` annotation as much as possible. +But for strict testing, try to use the `ERROR` annotation as much as possible, +including `//~?` annotations for diagnostics without span. +For compile time diagnostics `error-pattern` should very rarely be necessary. ### Error levels @@ -353,7 +371,7 @@ would be a `.mir.stderr` and `.thir.stderr` file with the different outputs of the different revisions. > Note: cfg revisions also work inside the source code with `#[cfg]` attributes. -> +> > By convention, the `FALSE` cfg is used to have an always-false config. ## Controlling pass/fail expectations From 9745529523f09a7ad534b9524f9fd728f61c7fc9 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Thu, 27 Mar 2025 18:32:48 +0100 Subject: [PATCH 161/447] Delete from_method from rustc_on_unimplemented documentation --- src/diagnostics.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/diagnostics.md b/src/diagnostics.md index 972309b5c..6f72ea902 100644 --- a/src/diagnostics.md +++ b/src/diagnostics.md @@ -954,9 +954,6 @@ application of these fields based on a variety of attributes when using `Self="std::iter::Iterator"`. This is needed because `Self` is a keyword which cannot appear in attributes. - `direct`: user-specified rather than derived obligation. - - `from_method`: usable both as boolean (whether the flag is present, like - `crate_local`) or matching against a particular method. Currently used - for `try`. - `from_desugaring`: usable both as boolean (whether the flag is present) or matching against a particular desugaring. The desugaring is identified with its variant name in the `DesugaringKind` enum. From a480687c6c430a5249b6294ab99f35b6782352ac Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 28 Mar 2025 12:38:32 -0300 Subject: [PATCH 162/447] Fix code generation link --- src/tests/codegen-backend-tests/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/codegen-backend-tests/intro.md b/src/tests/codegen-backend-tests/intro.md index c4bac26ab..6bf46ddcd 100644 --- a/src/tests/codegen-backend-tests/intro.md +++ b/src/tests/codegen-backend-tests/intro.md @@ -1,6 +1,6 @@ # Codegen backend testing -See also the [Code generation](../../../src/backend/codegen.md) chapter. +See also the [Code generation](../../backend/codegen.md) chapter. In addition to the primary LLVM codegen backend, the rust-lang/rust CI also runs tests of the [cranelift][cg_clif] and [GCC][cg_gcc] codegen backends in certain test jobs. From f1a4e592db7edfe665ec66d5aec1c59d3cbd6d02 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Fri, 28 Mar 2025 20:10:31 +0100 Subject: [PATCH 163/447] Fix trivial typo of `BoundVariableKind` --- src/ty_module/binders.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ty_module/binders.md b/src/ty_module/binders.md index defb7cde5..71157eca9 100644 --- a/src/ty_module/binders.md +++ b/src/ty_module/binders.md @@ -40,7 +40,7 @@ We did not always explicitly track the set of bound vars introduced by each `Bin ``` Binder( fn(&'^1_0 &'^1 T/#0), - &[BoundVariarbleKind::Region(...)], + &[BoundVariableKind::Region(...)], ) ``` This would cause all kinds of issues as the region `'^1_0` refers to a binder at a higher level than the outermost binder i.e. it is an escaping bound var. The `'^1` region (also writeable as `'^0_1`) is also ill formed as the binder it refers to does not introduce a second parameter. Modern day rustc will ICE when constructing this binder due to both of those regions, in the past we would have simply allowed this to work and then ran into issues in other parts of the codebase. From 628eb7064d7aaea62521e11d6cc6b7306f51c248 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 29 Mar 2025 12:52:10 +0300 Subject: [PATCH 164/447] compiletest: Support matching diagnostics on lines below --- src/tests/ui.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tests/ui.md b/src/tests/ui.md index 98bb9dee7..1190c2646 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -202,6 +202,9 @@ several ways to match the message with the line (see the examples below): * `~|`: Associates the error level and message with the *same* line as the *previous comment*. This is more convenient than using multiple carets when there are multiple messages associated with the same line. +* `~v`: Associates the error level and message with the *next* error + annotation line. Each symbol (`v`) that you add adds a line to this, so `~vvv` + is three lines below the error annotation line. * `~?`: Used to match error levels and messages with errors not having line information. These can be placed on any line in the test file, but are conventionally placed at the end. @@ -273,6 +276,18 @@ fn main() { //~| ERROR this pattern has 1 field, but the corresponding tuple struct has 3 fields [E0023] ``` +#### Positioned above error line + +Use the `//~v` idiom with number of v's in the string to indicate the number +of lines below. This is typically used in lexer or parser tests matching on errors like unclosed +delimiter or unclosed literal happening at the end of file. + +```rust,ignore +// ignore-tidy-trailing-newlines +//~v ERROR this file contains an unclosed delimiter +fn main((ؼ +``` + #### Error without line information Use `//~?` to match an error without line information. From 6c1077e05d5409dd25cd01daa106da20667fc76c Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 29 Mar 2025 20:02:01 +0200 Subject: [PATCH 165/447] mention that know-bug test directive takes arguments --- src/tests/ui.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tests/ui.md b/src/tests/ui.md index c8536b004..728ea3de4 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -415,6 +415,14 @@ reasons, including: can alert the developer so they know that the associated issue has been fixed and can possibly be closed. +This directive takes comma-separated issue numbers as arguments, or `"unknown"`: + +- `//@ known-bug: #123, #456` (when the issues are on rust-lang/rust) +- `//@ known-bug: rust-lang/chalk#123456` + (allows arbitrary text before the `#`, which is useful when the issue is on another repo) +- `//@ known-bug: unknown` + (when there is no known issue yet; preferrably open one if it does not already exist) + Do not include [error annotations](#error-annotations) in a test with `known-bug`. The test should still include other normal directives and stdout/stderr files. From 550dc9b31b901539ed2a521669ced52b31508544 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 29 Mar 2025 23:52:57 +0200 Subject: [PATCH 166/447] update rustc-{driver,interface} examples --- examples/rustc-driver-example.rs | 11 +++++------ examples/rustc-driver-interacting-with-the-ast.rs | 4 ++-- examples/rustc-interface-example.rs | 8 ++++---- examples/rustc-interface-getting-diagnostics.rs | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/examples/rustc-driver-example.rs b/examples/rustc-driver-example.rs index 35dd07dd1..fb8b13ad1 100644 --- a/examples/rustc-driver-example.rs +++ b/examples/rustc-driver-example.rs @@ -1,4 +1,4 @@ -// Tested with nightly-2025-03-08 +// Tested with nightly-2025-03-28 #![feature(rustc_private)] @@ -20,7 +20,7 @@ use std::path::Path; use std::sync::Arc; use rustc_ast_pretty::pprust::item_to_string; -use rustc_driver::{Compilation, run_compiler}; +use rustc_driver::{run_compiler, Compilation}; use rustc_interface::interface::{Compiler, Config}; use rustc_middle::ty::TyCtxt; @@ -71,13 +71,12 @@ impl rustc_driver::Callbacks for MyCallbacks { fn after_analysis(&mut self, _compiler: &Compiler, tcx: TyCtxt<'_>) -> Compilation { // Analyze the program and inspect the types of definitions. - for id in tcx.hir_free_items(){ + for id in tcx.hir_free_items() { let item = &tcx.hir_item(id); match item.kind { - rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn { .. } => { - let name = item.ident; + rustc_hir::ItemKind::Static(ident, ..) | rustc_hir::ItemKind::Fn { ident, .. } => { let ty = tcx.type_of(item.hir_id().owner.def_id); - println!("{name:?}:\t{ty:?}") + println!("{ident:?}:\t{ty:?}") } _ => (), } diff --git a/examples/rustc-driver-interacting-with-the-ast.rs b/examples/rustc-driver-interacting-with-the-ast.rs index 2a43ba476..b0c62d5b4 100644 --- a/examples/rustc-driver-interacting-with-the-ast.rs +++ b/examples/rustc-driver-interacting-with-the-ast.rs @@ -1,4 +1,4 @@ -// Tested with nightly-2025-03-08 +// Tested with nightly-2025-03-28 #![feature(rustc_private)] @@ -71,7 +71,7 @@ impl rustc_driver::Callbacks for MyCallbacks { fn after_analysis(&mut self, _compiler: &Compiler, tcx: TyCtxt<'_>) -> Compilation { // Iterate over the top-level items in the crate, looking for the main function. - for id in tcx.hir_free_items(){ + for id in tcx.hir_free_items() { let item = &tcx.hir_item(id); // Use pattern-matching to find a specific node inside the main function. if let rustc_hir::ItemKind::Fn { body, .. } = item.kind { diff --git a/examples/rustc-interface-example.rs b/examples/rustc-interface-example.rs index 11125caec..360f70c8e 100644 --- a/examples/rustc-interface-example.rs +++ b/examples/rustc-interface-example.rs @@ -1,4 +1,4 @@ -// Tested with nightly-2025-03-08 +// Tested with nightly-2025-03-28 #![feature(rustc_private)] @@ -67,10 +67,10 @@ fn main() { for id in tcx.hir_free_items() { let item = tcx.hir_item(id); match item.kind { - rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn { .. } => { - let name = item.ident; + rustc_hir::ItemKind::Static(ident, ..) + | rustc_hir::ItemKind::Fn { ident, .. } => { let ty = tcx.type_of(item.hir_id().owner.def_id); - println!("{name:?}:\t{ty:?}") + println!("{ident:?}:\t{ty:?}") } _ => (), } diff --git a/examples/rustc-interface-getting-diagnostics.rs b/examples/rustc-interface-getting-diagnostics.rs index 9bb93ab49..2512ba3c3 100644 --- a/examples/rustc-interface-getting-diagnostics.rs +++ b/examples/rustc-interface-getting-diagnostics.rs @@ -1,4 +1,4 @@ -// Tested with nightly-2025-03-08 +// Tested with nightly-2025-03-28 #![feature(rustc_private)] From eb3d07befcfe964291baaf7cb3fee3cd040fcbc4 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sun, 30 Mar 2025 00:16:39 +0200 Subject: [PATCH 167/447] example assumes a static exists This was removed, likely by mistake, during a refactor. --- examples/rustc-driver-example.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/rustc-driver-example.rs b/examples/rustc-driver-example.rs index fb8b13ad1..0e3450086 100644 --- a/examples/rustc-driver-example.rs +++ b/examples/rustc-driver-example.rs @@ -34,9 +34,9 @@ impl rustc_span::source_map::FileLoader for MyFileLoader { fn read_file(&self, path: &Path) -> io::Result { if path == Path::new("main.rs") { Ok(r#" +static MESSAGE: &str = "Hello, World!"; fn main() { - let message = "Hello, World!"; - println!("{message}"); + println!("{MESSAGE}"); } "# .to_string()) From ed9122f5343f64a192c2baffb0655f2599e79f3e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sun, 30 Mar 2025 00:31:44 +0200 Subject: [PATCH 168/447] add rustfmt settings file --- ci/date-check/src/main.rs | 155 ++++-------------- examples/rustc-driver-example.rs | 2 +- .../rustc-driver-interacting-with-the-ast.rs | 2 +- rustfmt.toml | 7 + 4 files changed, 39 insertions(+), 127 deletions(-) create mode 100644 rustfmt.toml diff --git a/ci/date-check/src/main.rs b/ci/date-check/src/main.rs index 5ab3e6c8b..9af69dbbf 100644 --- a/ci/date-check/src/main.rs +++ b/ci/date-check/src/main.rs @@ -1,11 +1,8 @@ -use std::{ - collections::BTreeMap, - convert::TryInto as _, - env, fmt, fs, - path::{Path, PathBuf}, - process, - str::FromStr, -}; +use std::collections::BTreeMap; +use std::convert::TryInto as _; +use std::path::{Path, PathBuf}; +use std::str::FromStr; +use std::{env, fmt, fs, process}; use chrono::{Datelike as _, Month, TimeZone as _, Utc}; use glob::glob; @@ -19,19 +16,13 @@ struct Date { impl Date { fn months_since(self, other: Date) -> Option { - let self_chrono = Utc - .with_ymd_and_hms(self.year.try_into().unwrap(), self.month, 1, 0, 0, 0) - .unwrap(); - let other_chrono = Utc - .with_ymd_and_hms(other.year.try_into().unwrap(), other.month, 1, 0, 0, 0) - .unwrap(); + let self_chrono = + Utc.with_ymd_and_hms(self.year.try_into().unwrap(), self.month, 1, 0, 0, 0).unwrap(); + let other_chrono = + Utc.with_ymd_and_hms(other.year.try_into().unwrap(), other.month, 1, 0, 0, 0).unwrap(); let duration_since = self_chrono.signed_duration_since(other_chrono); let months_since = duration_since.num_days() / 30; - if months_since < 0 { - None - } else { - Some(months_since.try_into().unwrap()) - } + if months_since < 0 { None } else { Some(months_since.try_into().unwrap()) } } } @@ -66,26 +57,18 @@ fn collect_dates_from_file(date_regex: &Regex, text: &str) -> Vec<(usize, Date)> date_regex .captures_iter(text) .filter_map(|cap| { - if let (Some(month), Some(year), None, None) | (None, None, Some(month), Some(year)) = ( - cap.name("m1"), - cap.name("y1"), - cap.name("m2"), - cap.name("y2"), - ) { + if let (Some(month), Some(year), None, None) | (None, None, Some(month), Some(year)) = + (cap.name("m1"), cap.name("y1"), cap.name("m2"), cap.name("y2")) + { let year = year.as_str().parse().expect("year"); - let month = Month::from_str(month.as_str()) - .expect("month") - .number_from_month(); + let month = Month::from_str(month.as_str()).expect("month").number_from_month(); Some((cap.get(0).expect("all").range(), Date { year, month })) } else { None } }) .map(|(byte_range, date)| { - line += text[end_of_last_cap..byte_range.end] - .chars() - .filter(|c| *c == '\n') - .count(); + line += text[end_of_last_cap..byte_range.end].chars().filter(|c| *c == '\n').count(); end_of_last_cap = byte_range.end; (line, date) }) @@ -138,10 +121,7 @@ fn main() { let root_dir_path = Path::new(&root_dir); let glob_pat = format!("{}/**/*.md", root_dir); let today_chrono = Utc::now().date_naive(); - let current_month = Date { - year: today_chrono.year_ce().1, - month: today_chrono.month(), - }; + let current_month = Date { year: today_chrono.year_ce().1, month: today_chrono.month() }; let dates_by_file = collect_dates(glob(&glob_pat).unwrap().map(Result::unwrap)); let dates_by_file: BTreeMap<_, _> = @@ -173,10 +153,7 @@ fn main() { println!(); for (path, dates) in dates_by_file { - println!( - "- {}", - path.strip_prefix(&root_dir_path).unwrap_or(&path).display(), - ); + println!("- {}", path.strip_prefix(&root_dir_path).unwrap_or(&path).display(),); for (line, date) in dates { println!(" - [ ] line {}: {}", line, date); } @@ -191,14 +168,8 @@ mod tests { #[test] fn test_months_since() { - let date1 = Date { - year: 2020, - month: 3, - }; - let date2 = Date { - year: 2021, - month: 1, - }; + let date1 = Date { year: 2020, month: 3 }; + let date2 = Date { year: 2021, month: 1 }; assert_eq!(date2.months_since(date1), Some(10)); } @@ -273,83 +244,17 @@ Test8 assert_eq!( collect_dates_from_file(&make_date_regex(), text), vec![ - ( - 3, - Date { - year: 2021, - month: 1, - } - ), - ( - 6, - Date { - year: 2021, - month: 2, - } - ), - ( - 9, - Date { - year: 2021, - month: 3, - } - ), - ( - 11, - Date { - year: 2021, - month: 4, - } - ), - ( - 17, - Date { - year: 2021, - month: 5, - } - ), - ( - 20, - Date { - year: 2021, - month: 1, - } - ), - ( - 23, - Date { - year: 2021, - month: 2, - } - ), - ( - 26, - Date { - year: 2021, - month: 3, - } - ), - ( - 28, - Date { - year: 2021, - month: 4, - } - ), - ( - 34, - Date { - year: 2021, - month: 5, - } - ), - ( - 38, - Date { - year: 2021, - month: 6, - } - ), + (3, Date { year: 2021, month: 1 }), + (6, Date { year: 2021, month: 2 }), + (9, Date { year: 2021, month: 3 }), + (11, Date { year: 2021, month: 4 }), + (17, Date { year: 2021, month: 5 }), + (20, Date { year: 2021, month: 1 }), + (23, Date { year: 2021, month: 2 }), + (26, Date { year: 2021, month: 3 }), + (28, Date { year: 2021, month: 4 }), + (34, Date { year: 2021, month: 5 }), + (38, Date { year: 2021, month: 6 }), ], ); } diff --git a/examples/rustc-driver-example.rs b/examples/rustc-driver-example.rs index 0e3450086..db6ac1857 100644 --- a/examples/rustc-driver-example.rs +++ b/examples/rustc-driver-example.rs @@ -20,7 +20,7 @@ use std::path::Path; use std::sync::Arc; use rustc_ast_pretty::pprust::item_to_string; -use rustc_driver::{run_compiler, Compilation}; +use rustc_driver::{Compilation, run_compiler}; use rustc_interface::interface::{Compiler, Config}; use rustc_middle::ty::TyCtxt; diff --git a/examples/rustc-driver-interacting-with-the-ast.rs b/examples/rustc-driver-interacting-with-the-ast.rs index b0c62d5b4..c0d7f977d 100644 --- a/examples/rustc-driver-interacting-with-the-ast.rs +++ b/examples/rustc-driver-interacting-with-the-ast.rs @@ -20,7 +20,7 @@ use std::path::Path; use std::sync::Arc; use rustc_ast_pretty::pprust::item_to_string; -use rustc_driver::{run_compiler, Compilation}; +use rustc_driver::{Compilation, run_compiler}; use rustc_interface::interface::{Compiler, Config}; use rustc_middle::ty::TyCtxt; diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 000000000..b285329c7 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,7 @@ +# matches that of rust-lang/rust +style_edition = "2024" +use_small_heuristics = "Max" +merge_derives = false +group_imports = "StdExternalCrate" +imports_granularity = "Module" +use_field_init_shorthand = true From fcb637040666808d123c5e702015c9524b12920d Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sun, 30 Mar 2025 13:21:01 +0100 Subject: [PATCH 169/447] Fix partial clone link --- src/building/how-to-build-and-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/building/how-to-build-and-run.md b/src/building/how-to-build-and-run.md index 067e28711..c3c1c41e3 100644 --- a/src/building/how-to-build-and-run.md +++ b/src/building/how-to-build-and-run.md @@ -63,7 +63,7 @@ cd rust > **NOTE**: A shallow clone limits which `git` commands can be run. > If you intend to work on and contribute to the compiler, it is > generally recommended to fully clone the repository [as shown above](#get-the-source-code), -> or to perform a [partial clone](#shallow-clone-the-repository) instead. +> or to perform a [partial clone](#partial-clone-the-repository) instead. > > For example, `git bisect` and `git blame` require access to the commit history, > so they don't work if the repository was cloned with `--depth 1`. From b67b4357e49c0026578803d0f14f45e454ee70bf Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Wed, 2 Apr 2025 23:26:26 +0800 Subject: [PATCH 170/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 6baf43397..d7c20d8ce 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -493c38ba371929579fe136df26eccd9516347c7a +ae9173d7dd4a31806c950c90dcc331f1508b4d17 From a90cb7416c5755995f488c70e012068ea432e8b6 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 3 Apr 2025 02:04:49 +0200 Subject: [PATCH 171/447] test directive can appear anywhere in the file --- src/tests/directives.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 81aa35f1a..8e4a71017 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -6,7 +6,8 @@ FIXME(jieyouxu) completely revise this chapter. --> -Directives are special comments that tell compiletest how to build and interpret a test. They must appear before the Rust source in the test. They may also appear in `rmake.rs` [run-make tests](compiletest.md#run-make-tests). +Directives are special comments that tell compiletest how to build and interpret a test. +They may also appear in `rmake.rs` [run-make tests](compiletest.md#run-make-tests). They are normally put after the short comment that explains the point of this test. Compiletest test suites use `//@` to signal that a comment is a directive. From 8f4357e7a2575b3109521476768d72db5ac14203 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 29 Mar 2025 02:41:32 +0300 Subject: [PATCH 172/447] compiletest: Require `//~` annotations even if `error-pattern` is specified --- src/tests/ui.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/ui.md b/src/tests/ui.md index 1190c2646..6f412a7a6 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -335,6 +335,9 @@ But for strict testing, try to use the `ERROR` annotation as much as possible, including `//~?` annotations for diagnostics without span. For compile time diagnostics `error-pattern` should very rarely be necessary. +Per-line annotations (`//~`) are still checked in tests using `error-pattern`, +to opt out of these checks in exceptional cases use `//@ compile-flags: --error-format=human`. + ### Error levels The error levels that you can have are: From 7fda61b1166c4e9e835684915007c33dbe41d18f Mon Sep 17 00:00:00 2001 From: binarycat Date: Thu, 3 Apr 2025 15:04:32 -0500 Subject: [PATCH 173/447] add some links about the rustdoc-gui test suite --- src/rustdoc.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/rustdoc.md b/src/rustdoc.md index 320dc9d58..e36d6a388 100644 --- a/src/rustdoc.md +++ b/src/rustdoc.md @@ -90,7 +90,9 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) are in `tests/rustdoc-gui`. These use a [NodeJS tool called browser-UI-test](https://github.com/GuillaumeGomez/browser-UI-test/) that uses puppeteer to run tests in a headless browser and check rendering and - interactivity. + interactivity. For information on how to write this form of test, + see [`tests/rustdoc-gui/README.md`][rustdoc-gui-readme] + as well as [the description of the `.goml` format][goml-script] * Additionally, JavaScript type annotations are written using [TypeScript-flavored JSDoc] comments and an external d.ts file. The code itself is plain, valid JavaScript; we only use tsc as a linter. @@ -100,6 +102,8 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) [These tests have several extra directives available to them](./rustdoc-internals/rustdoc-test-suite.md). [TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html +[rustdoc-gui-readme]: https://github.com/rust-lang/rust/blob/master/tests/rustdoc-gui/README.md +[goml-script]: https://github.com/GuillaumeGomez/browser-UI-test/blob/master/goml-script.md ## Constraints From 02aa6b48523a61a673e1740b55266fb794f4d0ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Szab=C3=B3?= Date: Fri, 4 Apr 2025 08:34:08 +0300 Subject: [PATCH 174/447] Update book.toml fix the authors field See https://rust-lang.github.io/mdBook/format/configuration/general.html#general-metadata --- book.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book.toml b/book.toml index eb2f6806b..b84b1e754 100644 --- a/book.toml +++ b/book.toml @@ -1,6 +1,6 @@ [book] title = "Rust Compiler Development Guide" -author = "The Rust Project Developers" +authors = ["The Rust Project Developers"] description = "A guide to developing the Rust compiler (rustc)" [build] From 4188afe2e760410545db90696fe4ef7e1e52688e Mon Sep 17 00:00:00 2001 From: Levi Zim Date: Sun, 6 Apr 2025 20:05:03 +0800 Subject: [PATCH 175/447] Fix deadlink in libs-and-metadata.md --- src/backend/libs-and-metadata.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/libs-and-metadata.md b/src/backend/libs-and-metadata.md index 556b3fdf8..513df1650 100644 --- a/src/backend/libs-and-metadata.md +++ b/src/backend/libs-and-metadata.md @@ -110,7 +110,7 @@ See [`compute_hir_hash`] for where the hash is actually computed. [SVH]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/svh/struct.Svh.html [incremental compilation]: ../queries/incremental-compilation.md -[`compute_hir_hash`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/struct.LoweringContext.html#method.compute_hir_hash +[`compute_hir_hash`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/fn.compute_hir_hash.html ### Stable Crate Id From e6458031c06a0b7050d331d7110f16b4be9999d7 Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Mon, 7 Apr 2025 04:06:33 +0000 Subject: [PATCH 176/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index d7c20d8ce..a6f295108 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -ae9173d7dd4a31806c950c90dcc331f1508b4d17 +25a615bf829b9f6d6f22da537e3851043f92e5f2 From e76ab78d1dba25ccc1ab0583b29572f706deb2da Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 7 Apr 2025 06:42:37 +0200 Subject: [PATCH 177/447] improve flow --- src/tests/ui.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index 407862d48..e862a07ca 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -335,8 +335,9 @@ But for strict testing, try to use the `ERROR` annotation as much as possible, including `//~?` annotations for diagnostics without span. For compile time diagnostics `error-pattern` should very rarely be necessary. -Per-line annotations (`//~`) are still checked in tests using `error-pattern`, -to opt out of these checks in exceptional cases use `//@ compile-flags: --error-format=human`. +Per-line annotations (`//~`) are still checked in tests using `error-pattern`. +To opt out of these checks, use `//@ compile-flags: --error-format=human`. +Do that only in exceptional cases. ### Error levels From f34fa18b015a1d9b563ff72eb9605c87208d84e9 Mon Sep 17 00:00:00 2001 From: timesince Date: Wed, 9 Apr 2025 18:46:50 +0800 Subject: [PATCH 178/447] Remove redundant words --- src/solve/opaque-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solve/opaque-types.md b/src/solve/opaque-types.md index 672aab770..509c34a4d 100644 --- a/src/solve/opaque-types.md +++ b/src/solve/opaque-types.md @@ -33,7 +33,7 @@ For opaque types in the defining scope and in the implicit-negative coherence mo always done in two steps. Outside of the defining scope `normalizes-to` for opaques always returns `Err(NoSolution)`. -We start by trying to to assign the expected type as a hidden type. +We start by trying to assign the expected type as a hidden type. In the implicit-negative coherence mode, this currently always results in ambiguity without interacting with the opaque types storage. We could instead add allow 'defining' all opaque types, From 5fb6b8e48faffaf2570e39a5ae262d4ffcdbf7d9 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Mon, 7 Apr 2025 13:18:03 +0800 Subject: [PATCH 179/447] rustc-dev-guide: document `needs-crate-type` --- src/tests/directives.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 8e4a71017..7ed583c10 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -191,8 +191,13 @@ settings: specified atomic widths, e.g. the test with `//@ needs-target-has-atomic: 8, 16, ptr` will only run if it supports the comma-separated list of atomic widths. -- `needs-dynamic-linking` - ignores if target does not support dynamic linking +- `needs-dynamic-linking` — ignores if target does not support dynamic linking (which is orthogonal to it being unable to create `dylib` and `cdylib` crate types) +- `needs-crate-type` — ignores if target platform does not support one or more + of the comma-delimited list of specified crate types. For example, + `//@ needs-crate-type: cdylib, proc-macro` will cause the test to be ignored + on `wasm32-unknown-unknown` target because the target does not support the + `proc-macro` crate type. The following directives will check LLVM support: From d7631d20aa877d810c7026112c8a8c34a16a21f2 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 10 Apr 2025 12:34:57 +0200 Subject: [PATCH 180/447] mention --edition restrictions in rustc-dev-guide --- src/tests/directives.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 8e4a71017..f97f08e33 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -229,14 +229,14 @@ ignoring debuggers. ### Affecting how tests are built -| Directive | Explanation | Supported test suites | Possible values | -|---------------------|----------------------------------------------------------------------------------------------|---------------------------|------------------------------------------------------------------------------| -| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental`. | -| `edition` | Alias for `compile-flags: --edition=xxx` | All except for `run-make` | Any valid `--edition` value | -| `rustc-env` | Env var to set when running `rustc` | All except for `run-make` | `=` | -| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make` | Any env var name | -| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A | -| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A | +| Directive | Explanation | Supported test suites | Possible values | +|---------------------|----------------------------------------------------------------------------------------------|---------------------------|--------------------------------------------------------------------------------------------| +| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` | +| `edition` | The edition used to build the test | All except for `run-make` | Any valid `--edition` value | +| `rustc-env` | Env var to set when running `rustc` | All except for `run-make` | `=` | +| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make` | Any env var name | +| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A | +| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |
Tests (outside of `run-make`) that want to use incremental tests not in the From 0423c7b2df61391b126d5a4f4f883fac40056497 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 10 Apr 2025 19:33:04 +0300 Subject: [PATCH 181/447] dev-guide: Document `dont-require-annotations` and its use cases in more detail --- src/tests/directives.md | 1 + src/tests/ui.md | 55 ++++++++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 8e4a71017..2ebd98f68 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -101,6 +101,7 @@ for more details. | `normalize-stdout` | Normalize actual stdout with a rule `"" -> ""` before comparing against snapshot | `ui`, `incremental` | `"" -> ""`, ``/`` is regex capture and replace syntax | | `dont-check-compiler-stderr` | Don't check actual compiler stderr vs stderr snapshot | `ui` | N/A | | `dont-check-compiler-stdout` | Don't check actual compiler stdout vs stdout snapshot | `ui` | N/A | +| `dont-require-annotations` | Don't require line annotations for the given diagnostic kind (`//~ KIND`) to be exhaustive | `ui`, `incremental` | `ERROR`, `WARN`, `NOTE`, `HELP`, `SUGGESTION` | | `run-rustfix` | Apply all suggestions via `rustfix`, snapshot fixed output, and check fixed output builds | `ui` | N/A | | `rustfix-only-machine-applicable` | `run-rustfix` but only machine-applicable suggestions | `ui` | N/A | | `exec-env` | Env var to set when executing a test | `ui`, `crashes` | `=` | diff --git a/src/tests/ui.md b/src/tests/ui.md index e862a07ca..3243a3535 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -303,8 +303,7 @@ It should be preferred to using `error-pattern`, which is imprecise and non-exha ### `error-pattern` The `error-pattern` [directive](directives.md) can be used for runtime messages, which don't -have a specific span, or for compile time messages if imprecise matching is required due to -multi-line platform specific diagnostics. +have a specific span, or in exceptional cases for compile time messages. Let's think about this test: @@ -318,7 +317,7 @@ fn main() { ``` We want to ensure this shows "index out of bounds" but we cannot use the `ERROR` -annotation since the error doesn't have any span. Then it's time to use the +annotation since the runtime error doesn't have any span. Then it's time to use the `error-pattern` directive: ```rust,ignore @@ -331,29 +330,51 @@ fn main() { } ``` -But for strict testing, try to use the `ERROR` annotation as much as possible, -including `//~?` annotations for diagnostics without span. -For compile time diagnostics `error-pattern` should very rarely be necessary. +Use of `error-pattern` is not recommended in general. -Per-line annotations (`//~`) are still checked in tests using `error-pattern`. -To opt out of these checks, use `//@ compile-flags: --error-format=human`. -Do that only in exceptional cases. +For strict testing of compile time output, try to use the line annotations `//~` as much as +possible, including `//~?` annotations for diagnostics without span. -### Error levels +If the compile time output is target dependent or too verbose, use directive +`//@ dont-require-annotations: ` to make the line annotation checking +non-exhaustive, some of the compiler messages can stay uncovered by annotations in this mode. -The error levels that you can have are: +For checking runtime output `//@ check-run-results` may be preferable. + +Only use `error-pattern` if none of the above works. + +Line annotations `//~` are still checked in tests using `error-pattern`. +In exceptional cases use `//@ compile-flags: --error-format=human` to opt out of these checks. + +### Diagnostic kinds (error levels) + +The diagnostic kinds that you can have are: - `ERROR` -- `WARN` or `WARNING` +- `WARN` (or `WARNING`) - `NOTE` -- `HELP` and `SUGGESTION` - -You are allowed to not include a level, but you should include it at least for -the primary message. +- `HELP` +- `SUGGESTION` -The `SUGGESTION` level is used for specifying what the expected replacement text +The `SUGGESTION` kind is used for specifying what the expected replacement text should be for a diagnostic suggestion. +`ERROR` and `WARN` kinds are required to be exhaustively covered by line annotations +`//~` by default. + +Other kinds only need to be line-annotated if at least one annotation of that kind appears +in the test file. For example, one `//~ NOTE` will also require all other `//~ NOTE`s in the file +to be written out explicitly. + +Use directive `//@ dont-require-annotations` to opt out of exhaustive annotations. +E.g. use `//@ dont-require-annotations: NOTE` to annotate notes selectively. +Avoid using this directive for `ERROR`s and `WARN`ings, unless there's a serious reason, like +target-dependent compiler output. + +Missing diagnostic kinds (`//~ message`) are currently accepted, but are being phased away. +They will match any compiler output kind, but will not force exhaustive annotations for that kind. +Prefer explicit kind and `//@ dont-require-annotations` to achieve the same effect. + UI tests use the `-A unused` flag by default to ignore all unused warnings, as unused warnings are usually not the focus of a test. However, simple code samples often have unused warnings. If the test is specifically testing an From ca410e88e47731b63c9f9f1ad626289be7e7315f Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Fri, 11 Apr 2025 12:12:46 +0300 Subject: [PATCH 182/447] Fix link to rustc_* TEST attributes in ui.md --- src/tests/ui.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index e862a07ca..41dc9299a 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -575,4 +575,4 @@ with "user-facing" Rust alone. Indeed, one could say that this slightly abuses the term "UI" (*user* interface) and turns such UI tests from black-box tests into white-box ones. Use them carefully and sparingly. -[compiler debugging]: ../compiler-debugging.md#rustc_test-attributes +[compiler debugging]: ../compiler-debugging.md#rustc_-test-attributes From 281f106cde5ab8556c52908a28cb31c861433894 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Tue, 8 Apr 2025 11:34:55 +0300 Subject: [PATCH 183/447] Update table of contents in about-this-guide.md 1. added two new parts: Bootstrapping and Supporting Infrastructure; 2. touched up names of pre-existing parts, to match actual names in sidebar; 3. syntactic nits (start description of Analysis with a capital letter); and 4. make numbered list use only 1. Co-authored-by: Tshepang Mbambo --- src/about-this-guide.md | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/about-this-guide.md b/src/about-this-guide.md index 781a5c51b..057e4a4cc 100644 --- a/src/about-this-guide.md +++ b/src/about-this-guide.md @@ -3,33 +3,41 @@ This guide is meant to help document how rustc – the Rust compiler – works, as well as to help new contributors get involved in rustc development. -There are seven parts to this guide: +There are several parts to this guide: -1. [Building `rustc`][p1]: +1. [Building and debugging `rustc`][p1]: Contains information that should be useful no matter how you are contributing, about building, debugging, profiling, etc. -2. [Contributing to `rustc`][p2]: +1. [Contributing to Rust][p2]: Contains information that should be useful no matter how you are contributing, about procedures for contribution, using git and Github, stabilizing features, etc. -3. [High-Level Compiler Architecture][p3]: +1. [Bootstrapping][p3]: + Describes how the Rust compiler builds itself using previous versions, including + an introduction to the bootstrap process and debugging methods. +1. [High-level Compiler Architecture][p4]: Discusses the high-level architecture of the compiler and stages of the compile process. -4. [Source Code Representation][p4]: +1. [Source Code Representation][p5]: Describes the process of taking raw source code from the user and transforming it into various forms that the compiler can work with easily. -5. [Analysis][p5]: - discusses the analyses that the compiler uses to check various properties of the code +1. [Supporting Infrastructure][p6]: + Covers command-line argument conventions, compiler entry points like rustc_driver and + rustc_interface, and the design and implementation of errors and lints. +1. [Analysis][p7]: + Discusses the analyses that the compiler uses to check various properties of the code and inform later stages of the compile process (e.g., type checking). -6. [From MIR to Binaries][p6]: How linked executable machine code is generated. -7. [Appendices][p7] at the end with useful reference information. +1. [MIR to Binaries][p8]: How linked executable machine code is generated. +1. [Appendices][p9] at the end with useful reference information. There are a few of these with different information, including a glossary. [p1]: ./building/how-to-build-and-run.html [p2]: ./contributing.md -[p3]: ./part-2-intro.md -[p4]: ./part-3-intro.md -[p5]: ./part-4-intro.md -[p6]: ./part-5-intro.md -[p7]: ./appendix/background.md +[p3]: ./building/bootstrapping/intro.md +[p4]: ./part-2-intro.md +[p5]: ./part-3-intro.md +[p6]: ./cli.md +[p7]: ./part-4-intro.md +[p8]: ./part-5-intro.md +[p9]: ./appendix/background.md ### Constant change From 35acfcc46b7f2fbbff57c6e27bf18c6bdaec907c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 11 Apr 2025 21:30:10 +0200 Subject: [PATCH 184/447] Document that `opt-dist` requires metrics to be enabled --- src/building/optimized-build.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/building/optimized-build.md b/src/building/optimized-build.md index 0849464ea..62dfaca89 100644 --- a/src/building/optimized-build.md +++ b/src/building/optimized-build.md @@ -109,11 +109,16 @@ like Python or LLVM. Here is an example of how can `opt-dist` be used locally (outside of CI): -1. Build the tool with the following command: +1. Enable metrics in your `bootstrap.toml` file, because `opt-dist` expects it to be enabled: + ```toml + [build] + metrics = true + ``` +2. Build the tool with the following command: ```bash ./x build tools/opt-dist ``` -2. Run the tool with the `local` mode and provide necessary parameters: +3. Run the tool with the `local` mode and provide necessary parameters: ```bash ./build/host/stage0-tools-bin/opt-dist local \ --target-triple \ # select target, e.g. "x86_64-unknown-linux-gnu" From 54b7da853ae269cf23c8469d89d7d8b4d6454a34 Mon Sep 17 00:00:00 2001 From: Freya Arbjerg Date: Sat, 12 Apr 2025 00:05:26 +0200 Subject: [PATCH 185/447] Update "crater" link to actually point to crater.md --- src/walkthrough.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/walkthrough.md b/src/walkthrough.md index 6e07ceb7d..48b3f8bb1 100644 --- a/src/walkthrough.md +++ b/src/walkthrough.md @@ -221,7 +221,7 @@ There are a couple of things that may happen for some PRs during the review proc some merge conflicts with other PRs that happen to get merged first. You should fix these merge conflicts using the normal git procedures. -[crater]: ./tests/intro.html#crater +[crater]: ./tests/crater.html If you are not doing a new feature or something like that (e.g. if you are fixing a bug), then that's it! Thanks for your contribution :) From 8d316037215b8665df30ca303cf0cff23279cf9d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 12 Apr 2025 06:14:37 +0200 Subject: [PATCH 186/447] ease copy-paste --- src/tests/ecosystem.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tests/ecosystem.md b/src/tests/ecosystem.md index f4b93492e..eee07dd07 100644 --- a/src/tests/ecosystem.md +++ b/src/tests/ecosystem.md @@ -15,9 +15,11 @@ CI. See the [Crater chapter](crater.md) for more details. `cargotest` is a small tool which runs `cargo test` on a few sample projects (such as `servo`, `ripgrep`, `tokei`, etc.). This runs as part of CI and ensures -there aren't any significant regressions. +there aren't any significant regressions: -> Example: `./x test src/tools/cargotest` +```console +./x test src/tools/cargotest +``` ### Large OSS Project builders From 5c08026fe23aa29a1f78080e17308213b3475b3e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 12 Apr 2025 09:39:13 +0200 Subject: [PATCH 187/447] use more simple language Not obvious what "sort by" means --- src/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contributing.md b/src/contributing.md index 09a7f912b..1dcda962d 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -346,7 +346,7 @@ function in the same way as other pull requests. [`src/doc`]: https://github.com/rust-lang/rust/tree/master/src/doc [std-root]: https://github.com/rust-lang/rust/blob/master/library/std/src/lib.rs#L1 -To find documentation-related issues, sort by the [A-docs label]. +To find documentation-related issues, use the [A-docs label]. You can find documentation style guidelines in [RFC 1574]. From 962701f4088dbc43654d41940507d10863ebb746 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 12 Apr 2025 10:21:10 +0200 Subject: [PATCH 188/447] remove implied text "how much to trust" implies the opposite --- src/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contributing.md b/src/contributing.md index 09a7f912b..579a2439f 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -373,7 +373,7 @@ Just a few things to keep in mind: There is no strict limit on line lengths; let the sentence or part of the sentence flow to its proper end on the same line. - When contributing text to the guide, please contextualize the information with some time period - and/or a reason so that the reader knows how much to trust or mistrust the information. + and/or a reason so that the reader knows how much to trust the information. Aim to provide a reasonable amount of context, possibly including but not limited to: - A reason for why the data may be out of date other than "change", From 8721d56e32c6fb3f2751baccce86166494859519 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 12 Apr 2025 10:24:31 +0200 Subject: [PATCH 189/447] add missing word --- src/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contributing.md b/src/contributing.md index 09a7f912b..9e75d9d8a 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -388,7 +388,7 @@ Just a few things to keep in mind: - january 2021 There is a CI action (in `~/.github/workflows/date-check.yml`) - that generates a monthly showing those that are over 6 months old + that generates a monthly report showing those that are over 6 months old ([example](https://github.com/rust-lang/rustc-dev-guide/issues/2052)). For the action to pick the date, From a0a83bc7c83c316ddf032e7375d0902e2313736f Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 12 Apr 2025 10:28:15 +0200 Subject: [PATCH 190/447] date-check rdg contribution section --- src/contributing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/contributing.md b/src/contributing.md index 73006de6b..aeea45046 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -395,20 +395,20 @@ Just a few things to keep in mind: add a special annotation before specifying the date: ```md - Sep 2024 + Apr 2025 ``` Example: ```md - As of Sep 2024, the foo did the bar. + As of Apr 2025, the foo did the bar. ``` For cases where the date should not be part of the visible rendered output, use the following instead: ```md - + ``` - A link to a relevant WG, tracking issue, `rustc` rustdoc page, or similar, that may provide From e4fab61c10cd56daa7d4f81cb5fc3c9fb1d319e5 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 12 Apr 2025 10:41:48 +0200 Subject: [PATCH 191/447] fix path --- src/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contributing.md b/src/contributing.md index 7946c444d..0e622fff8 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -387,7 +387,7 @@ Just a few things to keep in mind: - jan 2021 - january 2021 - There is a CI action (in `~/.github/workflows/date-check.yml`) + There is a CI action (in `.github/workflows/date-check.yml`) that generates a monthly report showing those that are over 6 months old ([example](https://github.com/rust-lang/rustc-dev-guide/issues/2052)). From 4a71db13fae335dd52ca21015d4222da9e88fb1e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 12 Apr 2025 13:01:16 +0200 Subject: [PATCH 192/447] use consistent title capitalization --- src/SUMMARY.md | 40 +++++++++---------- src/ast-validation.md | 2 +- src/bug-fix-procedure.md | 2 +- src/building/suggested.md | 2 +- src/coherence.md | 1 - src/contributing.md | 2 +- src/crates-io.md | 2 +- src/diagnostics.md | 4 +- src/feature-gates.md | 2 +- src/incrcomp-debugging.md | 2 +- src/memory.md | 2 +- src/panic-implementation.md | 2 +- src/parallel-rustc.md | 10 ++--- .../incremental-compilation-in-detail.md | 2 +- .../query-evaluation-model-in-detail.md | 2 +- src/serialization.md | 2 +- src/test-implementation.md | 4 +- src/the-parser.md | 4 +- src/unsafety-checking.md | 2 +- 19 files changed, 44 insertions(+), 45 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 95a3cd7c7..05c43c83a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -10,9 +10,9 @@ - [How to build and run the compiler](./building/how-to-build-and-run.md) - [Quickstart](./building/quickstart.md) - [Prerequisites](./building/prerequisites.md) - - [Suggested Workflows](./building/suggested.md) + - [Suggested workflows](./building/suggested.md) - [Distribution artifacts](./building/build-install-distribution-artifacts.md) - - [Building Documentation](./building/compiler-documenting.md) + - [Building documentation](./building/compiler-documenting.md) - [Rustdoc overview](./rustdoc.md) - [Adding a new target](./building/new-target.md) - [Optimized build](./building/optimized-build.md) @@ -42,11 +42,11 @@ - [with the linux perf tool](./profiling/with_perf.md) - [with Windows Performance Analyzer](./profiling/wpa_profiling.md) - [with the Rust benchmark suite](./profiling/with_rustc_perf.md) -- [crates.io Dependencies](./crates-io.md) +- [crates.io dependencies](./crates-io.md) # Contributing to Rust -- [Contribution Procedures](./contributing.md) +- [Contribution procedures](./contributing.md) - [About the compiler team](./compiler-team.md) - [Using Git](./git.md) - [Mastering @rustbot](./rustbot.md) @@ -56,7 +56,7 @@ - [Stabilizing Features](./stabilization_guide.md) - [Feature Gates](./feature-gates.md) - [Coding conventions](./conventions.md) -- [Procedures for Breaking Changes](./bug-fix-procedure.md) +- [Procedures for breaking changes](./bug-fix-procedure.md) - [Using external repositories](./external-repos.md) - [Fuzzing](./fuzzing.md) - [Notification groups](notification-groups/about.md) @@ -88,14 +88,14 @@ - [Overview of the compiler](./overview.md) - [The compiler source code](./compiler-src.md) - [Queries: demand-driven compilation](./query.md) - - [The Query Evaluation Model in Detail](./queries/query-evaluation-model-in-detail.md) + - [The Query Evaluation Model in detail](./queries/query-evaluation-model-in-detail.md) - [Incremental compilation](./queries/incremental-compilation.md) - - [Incremental compilation In Detail](./queries/incremental-compilation-in-detail.md) - - [Debugging and Testing](./incrcomp-debugging.md) + - [Incremental compilation in detail](./queries/incremental-compilation-in-detail.md) + - [Debugging and testing](./incrcomp-debugging.md) - [Salsa](./queries/salsa.md) -- [Memory Management in Rustc](./memory.md) -- [Serialization in Rustc](./serialization.md) -- [Parallel Compilation](./parallel-rustc.md) +- [Memory management in rustc](./memory.md) +- [Serialization in rustc](./serialization.md) +- [Parallel compilation](./parallel-rustc.md) - [Rustdoc internals](./rustdoc-internals.md) - [Search](./rustdoc-internals/search.md) - [The `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md) @@ -103,14 +103,14 @@ - [Prologue](./part-3-intro.md) - [Syntax and the AST](./syntax-intro.md) - - [Lexing and Parsing](./the-parser.md) + - [Lexing and parsing](./the-parser.md) - [Macro expansion](./macro-expansion.md) - [Name resolution](./name-resolution.md) - [Attributes](./attributes.md) - - [`#[test]` Implementation](./test-implementation.md) - - [Panic Implementation](./panic-implementation.md) - - [AST Validation](./ast-validation.md) - - [Feature Gate Checking](./feature-gate-ck.md) + - [`#[test]` implementation](./test-implementation.md) + - [Panic implementation](./panic-implementation.md) + - [AST validation](./ast-validation.md) + - [Feature gate checking](./feature-gate-ck.md) - [Lang Items](./lang-items.md) - [The HIR (High-level IR)](./hir.md) - [Lowering AST to HIR](./ast-lowering.md) @@ -129,7 +129,7 @@ - [Example: Type checking](./rustc-driver/interacting-with-the-ast.md) - [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.md) - [Remarks on perma-unstable features](./rustc-driver/remarks-on-perma-unstable-features.md) -- [Errors and Lints](diagnostics.md) +- [Errors and lints](diagnostics.md) - [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md) - [Translation](./diagnostics/translation.md) - [`LintStore`](./diagnostics/lintstore.md) @@ -175,14 +175,14 @@ - [Type checking](./type-checking.md) - [Method Lookup](./method-lookup.md) - [Variance](./variance.md) - - [Coherence Checking](./coherence.md) - - [Opaque Types](./opaque-types-type-alias-impl-trait.md) + - [Coherence checking](./coherence.md) + - [Opaque types](./opaque-types-type-alias-impl-trait.md) - [Inference details](./opaque-types-impl-trait-inference.md) - [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md) - [Region inference restrictions][opaque-infer] - [Const condition checking](./effects.md) - [Pattern and Exhaustiveness Checking](./pat-exhaustive-checking.md) -- [Unsafety Checking](./unsafety-checking.md) +- [Unsafety checking](./unsafety-checking.md) - [MIR dataflow](./mir/dataflow.md) - [Drop elaboration](./mir/drop-elaboration.md) - [The borrow checker](./borrow_check.md) diff --git a/src/ast-validation.md b/src/ast-validation.md index fa0f1d954..8f10bbecf 100644 --- a/src/ast-validation.md +++ b/src/ast-validation.md @@ -1,4 +1,4 @@ -# AST Validation +# AST validation _AST validation_ is a separate AST pass that visits each item in the tree and performs simple checks. This pass diff --git a/src/bug-fix-procedure.md b/src/bug-fix-procedure.md index e6a16df6d..8e6725c54 100644 --- a/src/bug-fix-procedure.md +++ b/src/bug-fix-procedure.md @@ -1,4 +1,4 @@ -# Procedures for Breaking Changes +# Procedures for breaking changes diff --git a/src/building/suggested.md b/src/building/suggested.md index 43ff2ba72..a70d9d88e 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -1,4 +1,4 @@ -# Suggested Workflows +# Suggested workflows The full bootstrapping process takes quite a while. Here are some suggestions to make your life easier. diff --git a/src/coherence.md b/src/coherence.md index b3af101fb..73f9213bf 100644 --- a/src/coherence.md +++ b/src/coherence.md @@ -1,4 +1,3 @@ - # Coherence > NOTE: this is based on [notes by @lcnr](https://github.com/rust-lang/rust/pull/121848) diff --git a/src/contributing.md b/src/contributing.md index 0e622fff8..cc68c011d 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -1,4 +1,4 @@ -# Contribution Procedures +# Contribution procedures diff --git a/src/crates-io.md b/src/crates-io.md index 403d61a81..4431585a2 100644 --- a/src/crates-io.md +++ b/src/crates-io.md @@ -1,4 +1,4 @@ -# crates.io Dependencies +# crates.io dependencies The Rust compiler supports building with some dependencies from `crates.io`. Examples are `log` and `env_logger`. diff --git a/src/diagnostics.md b/src/diagnostics.md index 6f72ea902..2f8f4b0ab 100644 --- a/src/diagnostics.md +++ b/src/diagnostics.md @@ -1,4 +1,4 @@ -# Errors and Lints +# Errors and lints @@ -772,7 +772,7 @@ store.register_renamed("single_use_lifetime", "single_use_lifetimes"); [`store.register_removed`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html#method.register_removed [`rustc_lint::register_builtins`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/fn.register_builtins.html -### Lint Groups +### Lint groups Lints can be turned on in groups. These groups are declared in the [`register_builtins`][rbuiltins] function in [`rustc_lint::lib`][builtin]. The diff --git a/src/feature-gates.md b/src/feature-gates.md index 24ce9bb71..9806f73c4 100644 --- a/src/feature-gates.md +++ b/src/feature-gates.md @@ -1,4 +1,4 @@ -# Feature Gates +# Feature gates This chapter is intended to provide basic help for adding, removing, and modifying feature gates. diff --git a/src/incrcomp-debugging.md b/src/incrcomp-debugging.md index 7045d3fa3..a548215cf 100644 --- a/src/incrcomp-debugging.md +++ b/src/incrcomp-debugging.md @@ -1,4 +1,4 @@ -# Debugging and Testing Dependencies +# Debugging and testing dependencies ## Testing the dependency graph diff --git a/src/memory.md b/src/memory.md index 1e030ff45..eeb4a8139 100644 --- a/src/memory.md +++ b/src/memory.md @@ -1,4 +1,4 @@ -# Memory Management in Rustc +# Memory management in rustc Generally rustc tries to be pretty careful how it manages memory. The compiler allocates _a lot_ of data structures throughout compilation, diff --git a/src/panic-implementation.md b/src/panic-implementation.md index f35874286..468190ffc 100644 --- a/src/panic-implementation.md +++ b/src/panic-implementation.md @@ -1,4 +1,4 @@ -# Panicking in rust +# Panicking in Rust diff --git a/src/parallel-rustc.md b/src/parallel-rustc.md index 690fb19c9..ce69b66c2 100644 --- a/src/parallel-rustc.md +++ b/src/parallel-rustc.md @@ -1,4 +1,4 @@ -# Parallel Compilation +# Parallel compilation
As of November 2024, @@ -28,7 +28,7 @@ The following sections are kept for now but are quite outdated. [codegen]: backend/codegen.md -## Code Generation +## Code generation During monomorphization the compiler splits up all the code to be generated into smaller chunks called _codegen units_. These are then generated by @@ -38,7 +38,7 @@ occurs in the [`rustc_codegen_ssa::base`] module. [`rustc_codegen_ssa::base`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/index.html -## Data Structures +## Data structures The underlying thread-safe data-structures used in the parallel compiler can be found in the [`rustc_data_structures::sync`] module. These data structures @@ -83,7 +83,7 @@ can be accessed directly through `Deref::deref`. [`rustc_data_structures::sync::worker_local`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/sync/worker_local/index.html [`WorkerLocal`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/sync/worker_local/struct.WorkerLocal.html -## Parallel Iterator +## Parallel iterator The parallel iterators provided by the [`rayon`] crate are easy ways to implement parallelism. In the current implementation of the parallel compiler @@ -124,7 +124,7 @@ the parallel iterator function has been used are as follows: There are still many loops that have the potential to use parallel iterators. -## Query System +## Query system The query model has some properties that make it actually feasible to evaluate multiple queries in parallel without too much effort: diff --git a/src/queries/incremental-compilation-in-detail.md b/src/queries/incremental-compilation-in-detail.md index 4133b196c..03c822d4f 100644 --- a/src/queries/incremental-compilation-in-detail.md +++ b/src/queries/incremental-compilation-in-detail.md @@ -1,4 +1,4 @@ -# Incremental Compilation In Detail +# Incremental Compilation in detail diff --git a/src/queries/query-evaluation-model-in-detail.md b/src/queries/query-evaluation-model-in-detail.md index f7f204bf7..444e20bc5 100644 --- a/src/queries/query-evaluation-model-in-detail.md +++ b/src/queries/query-evaluation-model-in-detail.md @@ -1,4 +1,4 @@ -# The Query Evaluation Model in Detail +# The Query Evaluation Model in detail diff --git a/src/serialization.md b/src/serialization.md index 0ff049901..670a37ffb 100644 --- a/src/serialization.md +++ b/src/serialization.md @@ -1,4 +1,4 @@ -# Serialization in Rustc +# Serialization in rustc rustc has to [serialize] and deserialize various data during compilation. Specifically: diff --git a/src/test-implementation.md b/src/test-implementation.md index bee783c0f..e906dd29f 100644 --- a/src/test-implementation.md +++ b/src/test-implementation.md @@ -83,7 +83,7 @@ with your hand-written one, it will not share a [Symbol][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 using [`rustc_ast`][ast] generates a module like so: @@ -106,7 +106,7 @@ called [`test`][test] that is part of Rust core, that implements all of the runtime for testing. [`test`][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 diff --git a/src/the-parser.md b/src/the-parser.md index 60a71ae38..601a81e2e 100644 --- a/src/the-parser.md +++ b/src/the-parser.md @@ -1,4 +1,4 @@ -# Lexing and Parsing +# Lexing and parsing The very first thing the compiler does is take the program (in UTF-8 Unicode text) and turn it into a data format the compiler can work with more conveniently than strings. @@ -59,7 +59,7 @@ Note that while parsing, we may encounter macro definitions or invocations. We set these aside to be expanded (see [Macro Expansion](./macro-expansion.md)). Expansion itself may require parsing the output of a macro, which may reveal more macros to be expanded, and so on. -## More on Lexical Analysis +## More on lexical analysis Code for lexical analysis is split between two crates: diff --git a/src/unsafety-checking.md b/src/unsafety-checking.md index 113087894..fbc19d896 100644 --- a/src/unsafety-checking.md +++ b/src/unsafety-checking.md @@ -1,4 +1,4 @@ -# Unsafety Checking +# Unsafety checking Certain expressions in Rust can violate memory safety and as such need to be inside an `unsafe` block or function. The compiler will also warn if an unsafe From 031d694d696091f649415d4547aaffea2b7ec5a4 Mon Sep 17 00:00:00 2001 From: Urgau <3616612+Urgau@users.noreply.github.com> Date: Sat, 12 Apr 2025 18:24:59 +0200 Subject: [PATCH 193/447] Enable [canonicalize-issue-links] and [no-mentions] in triagebot.toml --- triagebot.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 12aa0b7b8..6232dbf05 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -7,5 +7,9 @@ allow-unauthenticated = [ "blocked", ] +[no-mentions] + +[canonicalize-issue-links] + # Automatically close and reopen PRs made by bots to run CI on them [bot-pull-requests] From 79af744efe165cb9627b23b7a4e2f3dcee6d9ebb Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 10 Apr 2025 07:14:39 +0800 Subject: [PATCH 194/447] tests: document `-A {unused,internal_features}` ui test mode presets --- src/tests/ui.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/tests/ui.md b/src/tests/ui.md index 41dc9299a..e10bc2daa 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -576,3 +576,26 @@ the term "UI" (*user* interface) and turns such UI tests from black-box tests into white-box ones. Use them carefully and sparingly. [compiler debugging]: ../compiler-debugging.md#rustc_-test-attributes + +## UI test mode preset lint levels + +By default, test suites under UI test mode (`tests/ui`, `tests/ui-fulldeps`, +but not `tests/rustdoc-ui`) will specify + +- `-A unused` +- `-A internal_features` + +If: + +- The ui test's pass mode is below `run` (i.e. check or build). +- No compare modes are specified. + +Since they can be very noisy in ui tests. + +You can override them with `compile-flags` lint level flags or +in-source lint level attributes as required. + +Note that the `rustfix` version will *not* have `-A unused` passed, +meaning that you may have to `#[allow(unused)]` to suppress `unused` +lints on the rustfix'd file (because we might be testing rustfix +on `unused` lints themselves). From b557b97e1ec1f35a5254b28c821eb888f564cb82 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 2 Apr 2025 13:00:45 +1100 Subject: [PATCH 195/447] Documentation fixes. Remove old references to the HIR map. --- src/appendix/glossary.md | 1 - src/hir.md | 43 ++++++++++++++++++---------------------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/appendix/glossary.md b/src/appendix/glossary.md index a7c3236d3..1837b59e8 100644 --- a/src/appendix/glossary.md +++ b/src/appendix/glossary.md @@ -31,7 +31,6 @@ Term | Meaning generics | The list of generic parameters defined on an item. There are three kinds of generic parameters: Type, lifetime and const parameters. HIR | The _high-level [IR](#ir)_, created by lowering and desugaring the AST. ([see more](../hir.md)) `HirId` | Identifies a particular node in the HIR by combining a def-id with an "intra-definition offset". See [the HIR chapter for more](../hir.md#identifiers-in-the-hir). -HIR map | The HIR map, accessible via `tcx.hir()`, allows you to quickly navigate the HIR and convert between various forms of identifiers. ICE | Short for _internal compiler error_, this is when the compiler crashes. ICH | Short for _incremental compilation hash_, these are used as fingerprints for things such as HIR and crate metadata, to check if changes have been made. This is useful in incremental compilation to see if part of a crate has changed and should be recompiled. `infcx` | The type inference context (`InferCtxt`). (see `rustc_middle::infer`) diff --git a/src/hir.md b/src/hir.md index 75f5a9e20..65779f312 100644 --- a/src/hir.md +++ b/src/hir.md @@ -100,7 +100,7 @@ The HIR uses a bunch of different identifiers that coexist and serve different p a wrapper around a [`HirId`]. For more info about HIR bodies, please refer to the [HIR chapter][hir-bodies]. -These identifiers can be converted into one another through the [HIR map][map]. +These identifiers can be converted into one another through the `TyCtxt`. [`DefId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html [`LocalDefId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.LocalDefId.html @@ -110,30 +110,24 @@ These identifiers can be converted into one another through the [HIR map][map]. [`CrateNum`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.CrateNum.html [`DefIndex`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefIndex.html [`Body`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Body.html -[hir-map]: ./hir.md#the-hir-map [hir-bodies]: ./hir.md#hir-bodies -[map]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html -## The HIR Map +## HIR Operations 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 -the [`hir::map`] module). The [HIR map] contains a [number of methods] to -convert between IDs of various kinds and to lookup data associated -with a HIR node. +`TyCtxt`. It contains a number of methods, defined in the `hir::map` module and +mostly prefixed with `hir_`, to convert between IDs of various kinds and to +lookup data associated with a HIR node. -[`tcx.hir()`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.hir -[`hir::map`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/index.html -[HIR map]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html -[number of methods]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#methods +[`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html For example, if you have a [`LocalDefId`], and you would like to convert it -to a [`HirId`], you can use [`tcx.hir().local_def_id_to_hir_id(def_id)`][local_def_id_to_hir_id]. +to a [`HirId`], you can use [`tcx.local_def_id_to_hir_id(def_id)`][local_def_id_to_hir_id]. You need a `LocalDefId`, rather than a `DefId`, since only local items have HIR nodes. -[local_def_id_to_hir_id]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.local_def_id_to_hir_id +[local_def_id_to_hir_id]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.local_def_id_to_hir_id -Similarly, you can use [`tcx.hir().find(n)`][find] to lookup the node for a +Similarly, you can use [`tcx.hir_node(n)`][hir_node] to lookup the node for a [`HirId`]. This returns a `Option>`, where [`Node`] is an enum defined in the map. By matching on this, you can find out what sort of node the `HirId` referred to and also get a pointer to the data @@ -142,15 +136,16 @@ that `n` must be some HIR expression, you can do [`tcx.hir_expect_expr(n)`][expect_expr], which will extract and return the [`&hir::Expr`][Expr], panicking if `n` is not in fact an expression. -[find]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.find +[hir_node]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.hir_node [`Node`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html [expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.expect_expr [Expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Expr.html -Finally, you can use the HIR map to find the parents of nodes, via -calls like [`tcx.hir().get_parent(n)`][get_parent]. +Finally, you can find the parents of nodes, via +calls like [`tcx.parent_hir_node(n)`][parent_hir_node]. + +[get_parent_item]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.parent_hir_node -[get_parent]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.get_parent ## HIR Bodies @@ -158,10 +153,10 @@ A [`rustc_hir::Body`] represents some kind of executable code, such as the body of a function/closure or the definition of a constant. Bodies are associated with an **owner**, which is typically some kind of item (e.g. an `fn()` or `const`), but could also be a closure expression -(e.g. `|x, y| x + y`). You can use the HIR map to find the body -associated with a given def-id ([`maybe_body_owned_by`]) or to find -the owner of a body ([`body_owner_def_id`]). +(e.g. `|x, y| x + y`). You can use the `TyCtxt` to find the body +associated with a given def-id ([`hir_maybe_body_owned_by`]) or to find +the owner of a body ([`hir_body_owner_def_id`]). [`rustc_hir::Body`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Body.html -[`maybe_body_owned_by`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.maybe_body_owned_by -[`body_owner_def_id`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.body_owner_def_id +[`hir_maybe_body_owned_by`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.hir_maybe_body_owned_by +[`hir_body_owner_def_id`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.hir_body_owner_def_id From 07d3c696375905175631b923d9c6e4815c1662a1 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 14 Apr 2025 08:41:22 +0200 Subject: [PATCH 196/447] clean "Coding conventions" chapter - use correct code block markers - add missing title - rustfmt can now use edition setting in its config ... and this is set in Rust repo - reduce visual noise - needless repetition - convention is to start sentence with upper case - sembr - whitespace - semi-heading not adding much value - fix grammar --- src/conventions.md | 65 +++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/src/conventions.md b/src/conventions.md index 0e624a456..4356cf246 100644 --- a/src/conventions.md +++ b/src/conventions.md @@ -1,3 +1,5 @@ +# Coding conventions + This file offers some tips on the coding conventions for rustc. This chapter covers [formatting](#formatting), [coding for correctness](#cc), [using crates from crates.io](#cio), and some tips on @@ -5,7 +7,7 @@ chapter covers [formatting](#formatting), [coding for correctness](#cc), -# Formatting and the tidy script +## Formatting and the tidy script rustc is moving towards the [Rust standard coding style][fmt]. @@ -20,44 +22,42 @@ Formatting is checked by the `tidy` script. It runs automatically when you do `./x test` and can be run in isolation with `./x fmt --check`. If you want to use format-on-save in your editor, the pinned version of -`rustfmt` is built under `build//stage0/bin/rustfmt`. You'll have to -pass the `--edition=2021` argument yourself when calling -`rustfmt` directly. +`rustfmt` is built under `build//stage0/bin/rustfmt`. [fmt]: https://github.com/rust-dev-tools/fmt-rfcs - [`rustfmt`]:https://github.com/rust-lang/rustfmt -## Formatting C++ code +### Formatting C++ code The compiler contains some C++ code for interfacing with parts of LLVM that don't have a stable C API. When modifying that code, use this command to format it: -```sh -./x test tidy --extra-checks=cpp:fmt --bless +```console +./x test tidy --extra-checks cpp:fmt --bless ``` This uses a pinned version of `clang-format`, to avoid relying on the local environment. -## Formatting and linting Python code +### Formatting and linting Python code The Rust repository contains quite a lot of Python code. We try to keep -it both linted and formatted by the [ruff][ruff] tool. +it both linted and formatted by the [ruff] tool. When modifying Python code, use this command to format it: -```sh -./x test tidy --extra-checks=py:fmt --bless + +```console +./x test tidy --extra-checks py:fmt --bless ``` -and the following command to run lints: -```sh -./x test tidy --extra-checks=py:lint +And, the following command to run lints: + +```console +./x test tidy --extra-checks py:lint ``` -This uses a pinned version of `ruff`, to avoid relying on the local -environment. +These use a pinned version of `ruff`, to avoid relying on the local environment. [ruff]: https://github.com/astral-sh/ruff @@ -65,7 +65,7 @@ environment. -## Copyright notice +### Copyright notice In the past, files began with a copyright and license notice. Please **omit** @@ -75,41 +75,42 @@ MIT/Apache-2.0). All of the copyright notices should be gone by now, but if you come across one in the rust-lang/rust repo, feel free to open a PR to remove it. -## Line length +### Line length Lines should be at most 100 characters. It's even better if you can keep things to 80. -**Ignoring the line length limit.** Sometimes – in particular for -tests – it can be necessary to exempt yourself from this limit. In -that case, you can add a comment towards the top of the file like so: +Sometimes, and particularly for tests, it can be necessary to exempt yourself from this limit. +In that case, you can add a comment towards the top of the file like so: ```rust // ignore-tidy-linelength ``` -## Tabs vs spaces +### Tabs vs spaces -Prefer 4-space indent. +Prefer 4-space indents. -# Coding for correctness +## Coding for correctness Beyond formatting, there are a few other tips that are worth following. -## Prefer exhaustive matches +### Prefer exhaustive matches Using `_` in a match is convenient, but it means that when new variants are added to the enum, they may not get handled correctly. Ask yourself: if a new variant were added to this enum, what's the chance that it would want to use the `_` code, versus having some other treatment? Unless the answer is "low", then prefer an -exhaustive match. (The same advice applies to `if let` and `while -let`, which are effectively tests for a single variant.) +exhaustive match. + +The same advice applies to `if let` and `while let`, +which are effectively tests for a single variant. -## Use "TODO" comments for things you don't want to forget +### Use "TODO" comments for things you don't want to forget As a useful tool to yourself, you can insert a `// TODO` comment for something that you want to get back to before you land your PR: @@ -136,13 +137,13 @@ if foo { -# Using crates from crates.io +## Using crates from crates.io See the [crates.io dependencies][crates] section. -# How to structure your PR +## How to structure your PR How you prepare the commits in your PR can make a big difference for the reviewer. Here are some tips. @@ -172,7 +173,7 @@ require that every intermediate commit successfully builds – we only expect to be able to bisect at a PR level. However, if you *can* make individual commits build, that is always helpful. -# Naming conventions +## Naming conventions Apart from normal Rust style/naming conventions, there are also some specific to the compiler. From b4426b7c4b6da4d1a8054fbbac4abda5c4684b94 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Tue, 25 Mar 2025 20:17:32 +0300 Subject: [PATCH 197/447] document config extensions Signed-off-by: onur-ozkan --- src/building/suggested.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/building/suggested.md b/src/building/suggested.md index 43ff2ba72..5d37a78af 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -20,6 +20,42 @@ your `.git/hooks` folder as `pre-push` (without the `.sh` extension!). You can also install the hook as a step of running `./x setup`! +## Config extensions + +When working on different tasks, you might need to switch between different bootstrap configurations. +Sometimes you may want to keep an old configuration for future use. But saving raw config values in +random files and manually copying and pasting them can quickly become messy, especially if you have a +long history of different configurations. + +To simplify managing multiple configurations, you can create config extensions. + +For example, you can create a simple config file named `cross.toml`: + +```toml +[build] +build = "x86_64-unknown-linux-gnu" +host = ["i686-unknown-linux-gnu"] +target = ["i686-unknown-linux-gnu"] + + +[llvm] +download-ci-llvm = false + +[target.x86_64-unknown-linux-gnu] +llvm-config = "/path/to/llvm-19/bin/llvm-config" +``` + +Then, include this in your `bootstrap.toml`: + +```toml +include = ["cross.toml"] +``` + +You can also include extensions within extensions recursively. + +**Note:** In the `include` field, the overriding logic follows a right-to-left order. Also, the outer +extension/config always overrides the inner ones. + ## Configuring `rust-analyzer` for `rustc` ### Project-local rust-analyzer setup From 3ed7cc887e32fe09a710ec00e0089bf19ecb3210 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Tue, 1 Apr 2025 11:53:32 +0300 Subject: [PATCH 198/447] document `include` in `bootstrap.example.toml` Signed-off-by: onur-ozkan --- src/building/suggested.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/building/suggested.md b/src/building/suggested.md index 5d37a78af..b2e258be0 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -53,8 +53,9 @@ include = ["cross.toml"] You can also include extensions within extensions recursively. -**Note:** In the `include` field, the overriding logic follows a right-to-left order. Also, the outer -extension/config always overrides the inner ones. +**Note:** In the `include` field, the overriding logic follows a right-to-left order. For example, +in `include = ["a.toml", "b.toml"]`, extension `b.toml` overrides `a.toml`. Also, parent extensions +always overrides the inner ones. ## Configuring `rust-analyzer` for `rustc` From 220d208efdd5b4c1b9219af51da9670e08ccf0fe Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Mar 2025 15:52:33 +1100 Subject: [PATCH 199/447] Rename `LifetimeName` as `LifetimeKind`. It's a much better name, more consistent with how we name such things. Also rename `Lifetime::res` as `Lifetime::kind` to match. I suspect this field used to have the type `LifetimeRes` and then the type was changed but the field name remained the same. --- src/ty.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ty.md b/src/ty.md index b33d54035..ce6cffec1 100644 --- a/src/ty.md +++ b/src/ty.md @@ -61,11 +61,11 @@ Here is a summary: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Describe the *syntax* of a type: what the user wrote (with some desugaring). | Describe the *semantics* of a type: the meaning of what the user wrote. | | Each `rustc_hir::Ty` has its own spans corresponding to the appropriate place in the program. | Doesn’t correspond to a single place in the user’s program. | -| `rustc_hir::Ty` has generics and lifetimes; however, some of those lifetimes are special markers like [`LifetimeName::Implicit`][implicit]. | `ty::Ty` has the full type, including generics and lifetimes, even if the user left them out | +| `rustc_hir::Ty` has generics and lifetimes; however, some of those lifetimes are special markers like [`LifetimeKind::Implicit`][implicit]. | `ty::Ty` has the full type, including generics and lifetimes, even if the user left them out | | `fn foo(x: u32) → u32 { }` - Two `rustc_hir::Ty` representing each usage of `u32`, each has its own `Span`s, and `rustc_hir::Ty` doesn’t tell us that both are the same type | `fn foo(x: u32) → u32 { }` - One `ty::Ty` for all instances of `u32` throughout the program, and `ty::Ty` tells us that both usages of `u32` mean the same type. | -| `fn foo(x: &u32) -> &u32)` - Two `rustc_hir::Ty` again. Lifetimes for the references show up in the `rustc_hir::Ty`s using a special marker, [`LifetimeName::Implicit`][implicit]. | `fn foo(x: &u32) -> &u32)`- A single `ty::Ty`. The `ty::Ty` has the hidden lifetime param. | +| `fn foo(x: &u32) -> &u32)` - Two `rustc_hir::Ty` again. Lifetimes for the references show up in the `rustc_hir::Ty`s using a special marker, [`LifetimeKind::Implicit`][implicit]. | `fn foo(x: &u32) -> &u32)`- A single `ty::Ty`. The `ty::Ty` has the hidden lifetime param. | -[implicit]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.LifetimeName.html#variant.Implicit +[implicit]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.LifetimeKind.html#variant.Implicit **Order** @@ -323,4 +323,4 @@ When looking at the debug output of `Ty` or simply talking about different types - Generic parameters: `{name}/#{index}` e.g. `T/#0`, where `index` corresponds to its position in the list of generic parameters - Inference variables: `?{id}` e.g. `?x`/`?0`, where `id` identifies the inference variable - Variables from binders: `^{binder}_{index}` e.g. `^0_x`/`^0_2`, where `binder` and `index` identify which variable from which binder is being referred to -- Placeholders: `!{id}` or `!{id}_{universe}` e.g. `!x`/`!0`/`!x_2`/`!0_2`, representing some unique type in the specified universe. The universe is often elided when it is `0` \ No newline at end of file +- Placeholders: `!{id}` or `!{id}_{universe}` e.g. `!x`/`!0`/`!x_2`/`!0_2`, representing some unique type in the specified universe. The universe is often elided when it is `0` From 299077b6c33c40da5de093ee48b743ffbe9d57aa Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 16 Apr 2025 08:57:15 +1000 Subject: [PATCH 200/447] Improve `borrowck_graphviz_*` documentation. In particular, `borrowck_graphviz_preflow` no longer exists. --- src/compiler-debugging.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler-debugging.md b/src/compiler-debugging.md index 47f397620..102e20207 100644 --- a/src/compiler-debugging.md +++ b/src/compiler-debugging.md @@ -301,7 +301,8 @@ Right below you can find elaborate explainers on a selected few. Some compiler options for debugging specific features yield graphviz graphs - e.g. the `#[rustc_mir(borrowck_graphviz_postflow="suffix.dot")]` attribute -dumps various borrow-checker dataflow graphs. +on a function dumps various borrow-checker dataflow graphs in conjunction with +`-Zdump-mir-dataflow`. These all produce `.dot` files. To view these files, install graphviz (e.g. `apt-get install graphviz`) and then run the following commands: From 523f2a571af427c74da9dbb6b10f1df3f8ca2a7d Mon Sep 17 00:00:00 2001 From: xizheyin Date: Wed, 16 Apr 2025 13:09:29 +0800 Subject: [PATCH 201/447] Remind to update dev branch while behind too many commits Signed-off-by: xizheyin --- src/contributing.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/contributing.md b/src/contributing.md index 09a7f912b..8c59ac6ef 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -150,6 +150,20 @@ when contributing to Rust under [the git section](./git.md). [t-compiler]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler [triagebot]: https://github.com/rust-lang/rust/blob/master/triagebot.toml +### Keeping your branch up-to-date + +The CI in rust-lang/rust applies your patches directly against the current master, +not against the commit your branch is based on. This can lead to unexpected failures +if your branch is outdated, even when there are no explicit merge conflicts. + +Before submitting or updating a PR, make sure to update your branch +as mentioned [here](git.md#keeping-things-up-to-date) if it's significantly +behind the master branch (e.g., more than 100 commits behind). +This fetches the latest master branch and rebases your changes on top of it, +ensuring your PR is tested against the latest code. + +After rebasing, it's recommended to [run the relevant tests locally](tests/intro.md) to catch any issues before CI runs. + ### r? All pull requests are reviewed by another person. We have a bot, From 5cedd19842f4f9fc0fc4dd6776ab9348ead9d354 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Wed, 16 Apr 2025 20:03:05 -0400 Subject: [PATCH 202/447] add a first version of autodiff docs --- src/SUMMARY.md | 5 ++ src/autodiff/debugging.md | 113 ++++++++++++++++++++++++++++++++++++ src/autodiff/flags.md | 42 ++++++++++++++ src/autodiff/internals.md | 27 +++++++++ src/autodiff/limitations.md | 27 +++++++++ 5 files changed, 214 insertions(+) create mode 100644 src/autodiff/debugging.md create mode 100644 src/autodiff/flags.md create mode 100644 src/autodiff/internals.md create mode 100644 src/autodiff/limitations.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 95a3cd7c7..d8c7243f6 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -99,6 +99,11 @@ - [Rustdoc internals](./rustdoc-internals.md) - [Search](./rustdoc-internals/search.md) - [The `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md) +- [Autodiff internals](./autodiff/internals.md) + - [How to debug](./autodiff/debugging.md) + - [Autodiff flags](./autodiff/flags.md) + - [Current limitations](./autodiff/limitations.md) + # Source Code Representation - [Prologue](./part-3-intro.md) diff --git a/src/autodiff/debugging.md b/src/autodiff/debugging.md new file mode 100644 index 000000000..bd46a66fa --- /dev/null +++ b/src/autodiff/debugging.md @@ -0,0 +1,113 @@ +# Reporting backend crashes + +If after a compilation failure you are greeted by a large amount of llvm-ir code, then our enzyme backend likely failed to compile your code. These cases are harder to debug, so your help is highly appreciated. Please also keep in mind that release builds are usually much more likely to work at the moment. + +The final goal here is to reproduce your bug in the enzyme [compiler explorer](https://enzyme.mit.edu/explorer/), in order to create a bug report in the [Enzyme](https://github.com/enzymead/enzyme/issues) repository. + +We have an `autodiff` flag which you can pass to `rustflags` to help with this. it will print the whole llvm-ir module, along with some `__enzyme_fwddiff` or `__enzyme_autodiff` calls. A potential workflow on linux could look like: + +## Controlling llvm-ir generation + +Before generating the llvm-ir, keep in mind two techniques that can help ensure the relevant rust code is visible for debugging: + +- **`std::hint::black_box`**: wrap rust variables or expressions in `std::hint::black_box()` to prevent rust and llvm from optimizing them away. This is useful when you need to inspect or manually manipulate specific values in the llvm-ir. +- **`extern "rust"` or `extern "c"`**: if you want to see how a specific function declaration is lowered to llvm-ir, you can declare it as `extern "rust"` or `extern "c"`. You can also look for existing `__enzyme_autodiff` or similar declarations within the generated module for examples. + +## 1) Generate an llvm-ir reproducer + +```sh +rustflags="-z autodiff=enable,printmodbefore" cargo +enzyme build --release &> out.ll +``` + +This also captures a few warnings and info messages above and below your module. open out.ll and remove every line above `; moduleid = `. Now look at the end of the file and remove everything that's not part of llvm-ir, i.e. remove errors and warnings. The last line of your llvm-ir should now start with `! = `, i.e. `!40831 = !{i32 0, i32 1037508, i32 1037538, i32 1037559}` or `!43760 = !dilocation(line: 297, column: 5, scope: !43746)`. + +The actual numbers will depend on your code. + +## 2) Check your llvm-ir reproducer + +To confirm that your previous step worked, we will use llvm's `opt` tool. find your path to the opt binary, with a path similar to `/rust/build//build/bin/opt`. also find `llvmenzyme-19.` path, similar to `/rust/build/target-tripple/enzyme/build/enzyme/llvmenzyme-19`. Please keep in mind that llvm frequently updates it's llvm backend, so the version number might be higher (20, 21, ...). Once you have both, run the following command: + +```sh + out.ll -load-pass-plugin=/path/to/llvmenzyme-19.so -passes="enzyme" -s +``` + +If the previous step succeeded, you are going to see the same error that you saw when compiling your rust code with cargo. + +If you fail to get the same error, please open an issue in the rust repository. If you succeed, congrats! the file is still huge, so let's automatically minimize it. + +## 3) Minimize your llvm-ir reproducer + +First find your `llvm-extract` binary, it's in the same folder as your opt binary. then run: + +```sh + -s --func= --recursive --rfunc="enzyme_autodiff*" --rfunc="enzyme_fwddiff*" --rfunc= out.ll -o mwe.ll +``` + +This command creates `mwe.ll`, a minimal working example. + +Please adjust the name passed with the last `--func` flag. You can either apply the `#[no_mangle]` attribute to the function you differentiate, then you can replace it with the rust name. otherwise you will need to look up the mangled function name. To do that, open `out.ll` and search for `__enzyme_fwddiff` or `__enzyme_autodiff`. the first string in that function call is the name of your function. example: + +```llvm-ir +define double @enzyme_opt_helper_0(ptr %0, i64 %1, double %2) { + %4 = call double (...) @__enzyme_fwddiff(ptr @_zn2ad3_f217h3b3b1800bd39fde3e, metadata !"enzyme_const", ptr %0, metadata !"enzyme_const", i64 %1, metadata !"enzyme_dup", double %2, double %2) + ret double %4 +} +``` + +Here, `_zn2ad3_f217h3b3b1800bd39fde3e` is the correct name. make sure to not copy the leading `@`. redo step 2) by running the `opt` command again, but this time passing `mwe.ll` as the input file instead of `out.ll`. Check if this minimized example still reproduces the crash. + +## 4) (Optional) Minimize your llvm-ir reproducer further. + +After the previous step you should have an `mwe.ll` file with ~5k loc. let's try to get it down to 50. find your `llvm-reduce` binary next to `opt` and `llvm-extract`. Copy the first line of your error message, an example could be: + +```sh +opt: /home/manuel/prog/rust/src/llvm-project/llvm/lib/ir/instructions.cpp:686: void llvm::callinst::init(llvm::functiontype*, llvm::value*, llvm::arrayref, llvm::arrayref >, const llvm::twine&): assertion `(args.size() == fty->getnumparams() || (fty->isvararg() && args.size() > fty->getnumparams())) && "calling a function with bad signature!"' failed. +``` + +If you just get a `segfault` there is no sensible error message and not much to do automatically, so continue to 5). +otherwise, create a `script.sh` file containing + +```sh +#!/bin/bash + $1 -load-pass-plugin=/path/to/llvmenzyme-19.so -passes="enzyme" \ + |& grep "/some/path.cpp:686: void llvm::callinst::init" +``` + +Experiment a bit with which error message you pass to grep. it should be long enough to make sure that the error is unique. However, for longer errors including `(` or `)` you will need to escape them correctly which can become annoying. Run + +```sh + --test=script.sh mwe.ll +``` + +If you see `input isn't interesting! verify interesting-ness test`, you got the error message in script.sh wrong, you need to make sure that grep matches your actual error. If all works out, you will see a lot of iterations, ending with a new `reduced.ll` file. Verify with `opt` that you still get the same error. + +### Advanced debugging: manual llvm-ir investigation + +Once you have a minimized reproducer (`mwe.ll` or `reduced.ll`), you can delve deeper: + +- **manual editing:** try manually rewriting the llvm-ir. for certain issues, like those involving indirect calls, you might investigate enzyme-specific intrinsics like `__enzyme_virtualreverse`. Understanding how to use these might require consulting enzyme's documentation or source code. +- **enzyme test cases:** look for relevant test cases within the [enzyme repository](https://github.com/enzymead/enzyme/tree/main/enzyme/test) that might demonstrate the correct usage of features or intrinsics related to your problem. + +## 5) Report your bug. + +Afterwards, you should be able to copy and paste your `mwe.ll` (or `reduced.ll`) example into our [compiler explorer](https://enzyme.mit.edu/explorer/). + +- Select `llvm ir` as language and `opt 20` as compiler. +- Replace the field to the right of your compiler with `-passes="enzyme"`, if it is not already set. +- Hopefully, you will see once again your now familiar error. +- Please use the share button to copy links to them. +- Please create an issue on [https://github.com/enzymead/enzyme/issues](https://github.com/enzymead/enzyme/issues) and share `mwe.ll` and (if you have it) `reduced.ll`, as well as links to the compiler explorer. Please feel free to also add your rust code or a link to it. + +#### Documenting findings + +some enzyme errors, like `"attempting to call an indirect active function whose runtime value is inactive"`, have historically caused confusion. If you investigate such an issue, even if you don't find a complete solution, please consider documenting your findings. If the insights are general to enzyme and not specific to its rust usage, contributing them to the main [enzyme documentation](https://github.com/enzymead/www) is often the best first step. You can also mention your findings in the relevant enzyme github issue or propose updates to these docs if appropriate. This helps prevent others from starting from scratch. + +With a clear reproducer and documentation, hopefully an enzyme developer will be able to fix your bug. Once that happens, the enzyme submodule inside the rust compiler will be updated, which should allow you to differentiate your rust code. Thanks for helping us to improve rust-ad. + +# Minimize rust code + +Beyond having a minimal llvm-ir reproducer, it is also helpful to have a minimal rust reproducer without dependencies. This allows us to add it as a test case to ci once we fix it, which avoids regressions for the future. + +There are a few solutions to help you with minimizing the rust reproducer. This is probably the most simple automated approach: [cargo-minimize](https://github.com/nilstrieb/cargo-minimize). + +Otherwise we have various alternatives, including [`treereduce`](https://github.com/langston-barrett/treereduce), [`halfempty`](https://github.com/googleprojectzero/halfempty), or [`picireny`](https://github.com/renatahodovan/picireny), potentially also [`creduce`](https://github.com/csmith-project/creduce). diff --git a/src/autodiff/flags.md b/src/autodiff/flags.md new file mode 100644 index 000000000..946ae1d03 --- /dev/null +++ b/src/autodiff/flags.md @@ -0,0 +1,42 @@ +# Supported `RUSTFLAGS` + +To support you while debugging or profiling, we have added support for an experimental `-Z autodiff` rustc flag (which can be passed to cargo via `RUSTFLAGS`), which allow changing the behaviour of Enzyme, without recompiling rustc. We currently support the following values for `autodiff`. + +### Debug Flags + +```text +PrintTA // Print TypeAnalysis information +PrintAA // Print ActivityAnalysis information +Print // Print differentiated functions while they are being generated and optimized +PrintPerf // Print AD related Performance warnings +PrintModBefore // Print the whole LLVM-IR module directly before running AD +PrintModAfter // Print the whole LLVM-IR module after running AD, before optimizations +PrintModFinal // Print the whole LLVM-IR module after running optimizations and AD +LooseTypes // Risk incorrect derivatives instead of aborting when missing Type Info +``` + +
+`LooseTypes` is often helpful to get rid of Enzyme errors stating `Can not deduce type of ` and to be able to run some code. But please keep in mind that this flag absolutely has the chance to cause incorrect gradients. Even worse, the gradients might be correct for certain input values, but not for others. So please create issues about such bugs and only use this flag temporarily while you wait for your bug to be fixed. +
+ +### Benchmark flags + +For performance experiments and benchmarking we also support + +```text +NoPostopt // We won't optimize the LLVM-IR Module after AD +RuntimeActivity // Enables the runtime activity feature from Enzyme +Inline // Instructs Enzyme to maximize inlining as far as possible, beyond LLVM's default +``` + +You can combine multiple `autodiff` values using a comma as separator: + +```bash +RUSTFLAGS="-Z autodiff=Enable,LooseTypes,PrintPerf" cargo +enzyme build +``` + +Using `-Zautodiff=Enable` will allow using autodiff and update your normal rustc compilation pipeline: + +1. Run your selected compilation pipeline. If you selected a release build, we will disable vectorization and loop unrolling. +2. Differentiate your functions. +3. Run your selected compilation pipeline again on the whole module. This time we do not disable vectorization or loop unrolling. diff --git a/src/autodiff/internals.md b/src/autodiff/internals.md new file mode 100644 index 000000000..0093ef044 --- /dev/null +++ b/src/autodiff/internals.md @@ -0,0 +1,27 @@ +The `std::autodiff` module in Rust allows differentiable programming: + +```rust +#![feature(autodiff)] +use std::autodiff::autodiff; + +// f(x) = x * x, f'(x) = 2.0 * x +// bar therefore returns (x * x, 2.0 * x) +#[autodiff(bar, Reverse, Active, Active)] +fn foo(x: f32) -> f32 { x * x } + +fn main() { + assert_eq!(bar(3.0, 1.0), (9.0, 6.0)); + assert_eq!(bar(4.0, 1.0), (16.0, 8.0)); +} +``` + +The detailed documentation for the `std::autodiff` module is available at [std::autodiff](https://doc.rust-lang.org/std/autodiff/index.html). + +Differentiable programing is used in various fields like numerical computing, [solid mechanics][ratel], [computational chemistry][molpipx], [fluid dynamics][waterlily] or for Neural Network training via Backpropagation, [ODE solver][diffsol], [differentiable rendering][libigl], [quantum computing][catalyst], and climate simulations. + +[ratel]: https://gitlab.com/micromorph/ratel +[molpipx]: https://arxiv.org/abs/2411.17011v +[waterlily]: https://github.com/WaterLily-jl/WaterLily.jl +[diffsol]: https://github.com/martinjrobins/diffsol +[libigl]: https://github.com/alecjacobson/libigl-enzyme-example?tab=readme-ov-file#run +[catalyst]: https://github.com/PennyLaneAI/catalyst diff --git a/src/autodiff/limitations.md b/src/autodiff/limitations.md new file mode 100644 index 000000000..90afbd51f --- /dev/null +++ b/src/autodiff/limitations.md @@ -0,0 +1,27 @@ +# Current limitations + +## Safety and Soundness + +Enzyme currently assumes that the user passes shadow arguments (`dx`, `dy`, ...) of appropriate size. Under Reverse Mode, we additionally assume that shadow arguments are mutable. In Reverse Mode we adjust the outermost pointer or reference to be mutable. Therefore `&f32` will receive the shadow type `&mut f32`. However, we do not check length for other types than slices (e.g. enums, Vec). We also do not enforce mutability of inner references, but will warn if we recognize them. We do intend to add additional checks over time. + +## ABI adjustments + +In some cases, a function parameter might get lowered in a way that we currently don't handle correctly, leading to a compile time type mismatch in the `rustc_codegen_llvm` backend. Here are some [examples](https://github.com/EnzymeAD/rust/issues/105). + +## Compile Times + +Enzyme will often achieve excellent runtime performance, but might increase your compile time by a large factor. For Rust, we already have made significant improvements and have a list of further improvements planed - please reach out if you have time to help here. + +### Type Analysis + +Most of the times, Type Analysis (TA) is the reason of large (>5x) compile time increases when using Enzyme. This poster explains why we need to run Type Analysis in the bottom left part: [Poster Link](https://c.wsmoses.com/posters/Enzyme-llvmdev.pdf). + +We intend to increase the number of locations where we pass down Type information based on Rust types, which in turn will reduce the number of locations where Enzyme has to run Type Analysis, which will help compile times. + +### Duplicated Optimizations + +The key reason for Enzyme offering often excellent performance is that Enzyme differentiates already optimized LLVM-IR. However, we also (have to) run LLVM's optimization pipeline after differentiating, to make sure that the code which Enzyme generates is optimized properly. As a result you should have excellent runtime performance (please fill an issue if not), but at a compile time cost for running optimizations twice. + +### Fat-LTO + +The usage of `#[autodiff(...)]` currently requires compiling your project with Fat-LTO. We technically only need LTO if the function being differentiated calls functions in other compilation units. Therefore, other solutions are possible, but this is the most simple one to get started. From bde086e3fa6e5d19340b9379936d008968cf932c Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 17 Apr 2025 17:04:30 +0800 Subject: [PATCH 203/447] rustc-dev-guide: document `//@ ignore-auxiliary` --- src/tests/best-practices.md | 2 ++ src/tests/directives.md | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/tests/best-practices.md b/src/tests/best-practices.md index 6905ee132..2bdc7f3a2 100644 --- a/src/tests/best-practices.md +++ b/src/tests/best-practices.md @@ -175,6 +175,8 @@ See [compiletest directives] for a listing of directives. - For `ignore-*`/`needs-*`/`only-*` directives, unless extremely obvious, provide a brief remark on why the directive is needed. E.g. `"//@ ignore-wasi (wasi codegens the main symbol differently)"`. +- When using `//@ ignore-auxiliary`, specify the corresponding main test files, + e.g. ``//@ ignore-auxiliary (used by `./foo.rs`)``. ## FileCheck best practices diff --git a/src/tests/directives.md b/src/tests/directives.md index 0aad8be98..dae659e63 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -124,6 +124,9 @@ means the test won't be compiled or run. * `ignore-X` where `X` is a target detail or other criteria on which to ignore the test (see below) * `only-X` is like `ignore-X`, but will *only* run the test on that target or stage +* `ignore-auxiliary` is intended for files that *participate* in one or more other + main test files but that `compiletest` should not try to build the file itself. + Please backlink to which main test is actually using the auxiliary file. * `ignore-test` always ignores the test. This can be used to temporarily disable a test if it is currently not working, but you want to keep it in tree to re-enable it later. From 23c4b36751ea7450950854b47ffd269a96db69d9 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Thu, 17 Apr 2025 20:52:07 -0400 Subject: [PATCH 204/447] upstream autodiff build instructions --- src/SUMMARY.md | 1 + src/autodiff/installation.md | 86 ++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/autodiff/installation.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 6526e2f0e..90fcde072 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -100,6 +100,7 @@ - [Search](./rustdoc-internals/search.md) - [The `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md) - [Autodiff internals](./autodiff/internals.md) + - [Installation](./autodiff/installation.md) - [How to debug](./autodiff/debugging.md) - [Autodiff flags](./autodiff/flags.md) - [Current limitations](./autodiff/limitations.md) diff --git a/src/autodiff/installation.md b/src/autodiff/installation.md new file mode 100644 index 000000000..dbea9dbe1 --- /dev/null +++ b/src/autodiff/installation.md @@ -0,0 +1,86 @@ +# Installation + +In the near future, `std::autodiff` should become available in nightly builds for users. As a contribute however, you will still need to build rustc from source. Please be aware that the msvc target is not supported at the moment, all other tier 1 targets should work. Please open an issue if you encounter any problems on a supported tier 1 target, or if you succesfully build this project on a tier2/tier3 target. + +## Build instructions + +First you need to clone and configure the Rust repository: +```bash +git clone --depth=1 git@github.com:rust-lang/rust.git +cd rust +./configure --enable-llvm-link-shared --enable-llvm-plugins --enable-llvm-enzyme --release-channel=nightly --enable-llvm-assertions --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs +``` + +Afterwards you can build rustc using: +```bash +./x.py build --stage 1 library +``` + +Afterwards rustc toolchain link will allow you to use it through cargo: +``` +rustup toolchain link enzyme build/host/stage1 +rustup toolchain install nightly # enables -Z unstable-options +``` + +You can then run our test cases: + +```bash +./x.py test --stage 1 library tests/ui/autodiff +./x.py test --stage 1 library tests/codegen/autodiff +./x.py test --stage 1 library tests/pretty/autodiff* +``` + +Autodiff is still experimental, so if you want to use it in your own projects, you will need to add `lto="fat"` to your Cargo.toml +and use `RUSTFLAGS="-Zautodiff=Enable" cargo +enzyme` instead of `cargo` or `cargo +nightly`. + +## Compiler Explorer and dist builds + +Our compiler explorer instance can be updated to a newer rustc in a similar way. First, prepare a docker instance. +```bash +docker run -it ubuntu:22.04 +export CC=clang CXX=clang++ +apt update +apt install wget vim python3 git curl libssl-dev pkg-config lld ninja-build cmake clang build-essential +``` +Then build rustc in a slightly altered way: +```bash +git clone --depth=1 https://github.com/EnzymeAD/rust.git +cd rust +./configure --enable-llvm-link-shared --enable-llvm-plugins --enable-llvm-enzyme --release-channel=nightly --enable-llvm-assertions --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs +./x dist +``` +We then copy the tarball to our host. The dockerid is the newest entry under `docker ps -a`. +```bash +docker cp :/rust/build/dist/rust-nightly-x86_64-unknown-linux-gnu.tar.gz rust-nightly-x86_64-unknown-linux-gnu.tar.gz +``` +Afterwards we can create a new (pre-release) tag on the EnzymeAD/rust repository and make a PR against the EnzymeAD/enzyme-explorer repository to update the tag. +Remember to ping `tgymnich` on the PR to run his update script. + + +## Build instruction for Enzyme itself + +Following the Rust build instruction above will build LLVMEnzyme, LLDEnzyme, and ClangEnzyme along with the Rust compiler. +We recommend that approach, if you just want to use any of them and have no experience with cmake. +However, if you prefer to just build Enzyme without Rust, then these instructions might help. + +```bash +git clone --depth=1 git@github.com:llvm/llvm-project.git +cd llvm-project +mkdir build +cd build +cmake -G Ninja ../llvm -DLLVM_TARGETS_TO_BUILD="host" -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_ENABLE_RUNTIMES="openmp" -DLLVM_ENABLE_PLUGINS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=. +ninja +ninja install +``` +This gives you a working LLVM build, now we can continue with building Enzyme. +Leave the `llvm-project` folder, and execute the following commands: +```bash +git clone git@github.com:EnzymeAD/Enzyme.git +cd Enzyme/enzyme +mkdir build +cd build +cmake .. -G Ninja -DLLVM_DIR=/llvm-project/build/lib/cmake/llvm/ -DLLVM_EXTERNAL_LIT=/llvm-project/llvm/utils/lit/lit.py -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=YES -DBUILD_SHARED_LIBS=ON +ninja +``` +This will build Enzyme, and you can find it in `Enzyme/enzyme/build/lib/Enzyme.so`. (Endings might differ based on your OS). + From a250445f8eae24958ec383b42a7e34fe517246db Mon Sep 17 00:00:00 2001 From: Haowei Hsu Date: Fri, 18 Apr 2025 18:49:34 +0800 Subject: [PATCH 205/447] fix(docs): add newlines between prefix/suffix chapters add newlines between prefix/suffix chapters in SUMMARY.md to ensure correct extraction by mdbook-i18n-helpers. --- src/SUMMARY.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 90fcde072..e137eb82f 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -1,6 +1,7 @@ # Summary [Getting Started](./getting-started.md) + [About this guide](./about-this-guide.md) --- @@ -230,9 +231,13 @@ --- [Appendix A: Background topics](./appendix/background.md) + [Appendix B: Glossary](./appendix/glossary.md) + [Appendix C: Code Index](./appendix/code-index.md) + [Appendix D: Compiler Lecture Series](./appendix/compiler-lecture.md) + [Appendix E: Bibliography](./appendix/bibliography.md) [Appendix Z: HumorRust](./appendix/humorust.md) From 1bc859ed76451c8f36165941713c46f09defda75 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 19 Apr 2025 13:08:43 +0200 Subject: [PATCH 206/447] readme: be copy-paste friendly --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6a25a91f5..9f468b933 100644 --- a/README.md +++ b/README.md @@ -43,13 +43,13 @@ 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-toc mdbook-mermaid ``` and execute the following command in the root of the repository: ``` -> mdbook build --open +mdbook build --open ``` The build files are found in the `book/html` directory. @@ -61,8 +61,8 @@ checking is **not** run by default locally, though it is in CI. To enable it locally, set the environment variable `ENABLE_LINKCHECK=1` like in the following example. -```console -$ ENABLE_LINKCHECK=1 mdbook serve +``` +ENABLE_LINKCHECK=1 mdbook serve ``` ### Table of Contents @@ -86,14 +86,14 @@ Older versions of `josh-proxy` may not round trip commits losslessly so it is im 1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide` 2) Run the pull command ``` - $ cargo run --manifest-path josh-sync/Cargo.toml rustc-pull + cargo run --manifest-path josh-sync/Cargo.toml rustc-pull ``` 3) Push the branch to your fork and create a PR into `rustc-dev-guide` ### Push changes from this repository into `rust-lang/rust` 1) Run the push command to create a branch named `` in a `rustc` fork under the `` account ``` - $ cargo run --manifest-path josh-sync/Cargo.toml rustc-push + cargo run --manifest-path josh-sync/Cargo.toml rustc-push ``` 2) Create a PR from `` into `rust-lang/rust` @@ -106,5 +106,5 @@ You may observe "Nothing to pull" even if you *know* rustc-pull has something to To minimize the likelihood of this happening, you may wish to keep a separate *minimal* git config that *only* has `[user]` entries from global git config, then repoint system git to use the minimal git config instead. E.g. ``` -$ GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo +stable run --manifest-path josh-sync/Cargo.toml -- rustc-pull +GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo +stable run --manifest-path josh-sync/Cargo.toml -- rustc-pull ``` From ac84606523a0877bee2e4ab440a8d0f37bad8ec8 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 19 Apr 2025 13:34:13 +0200 Subject: [PATCH 207/447] toolchain version does not need to be specified - Rust backcompat removes the need to specify the version here - Using these commands can result in a needless toolchain getting downloaded, like in the case where user only has Nightly installed --- .github/workflows/rustc-pull.yml | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index b19eccf9e..1e430d8b4 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -28,7 +28,7 @@ jobs: # Cache the josh directory with checked out rustc cache-directories: "/home/runner/.cache/rustc-dev-guide-josh" - name: Install josh - run: RUSTFLAGS="--cap-lints warn" cargo +stable install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04 + run: RUSTFLAGS="--cap-lints warn" cargo install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04 - name: Setup bot git name and email run: | git config --global user.name 'The rustc-dev-guide Cronjob Bot' diff --git a/README.md b/README.md index 9f468b933..081588017 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.g You'll need to install `josh-proxy` locally via ``` -cargo +stable install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04 +cargo install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04 ``` Older versions of `josh-proxy` may not round trip commits losslessly so it is important to install this exact version. @@ -106,5 +106,5 @@ You may observe "Nothing to pull" even if you *know* rustc-pull has something to To minimize the likelihood of this happening, you may wish to keep a separate *minimal* git config that *only* has `[user]` entries from global git config, then repoint system git to use the minimal git config instead. E.g. ``` -GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo +stable run --manifest-path josh-sync/Cargo.toml -- rustc-pull +GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull ``` From 85a22b893cea20cb863dfae8be20661b1e3f43cf Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Sat, 19 Apr 2025 13:53:05 +0000 Subject: [PATCH 208/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index a6f295108..67de4a981 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -25a615bf829b9f6d6f22da537e3851043f92e5f2 +a7c39b68616668a45f0afd62849a1da7c8ad2516 From 3a23ec25298731cabfca2df71521f59d9e071fca Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 19 Apr 2025 16:04:22 +0200 Subject: [PATCH 209/447] fix broken link --- src/hir.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hir.md b/src/hir.md index 65779f312..0c1c99415 100644 --- a/src/hir.md +++ b/src/hir.md @@ -144,7 +144,7 @@ that `n` must be some HIR expression, you can do Finally, you can find the parents of nodes, via calls like [`tcx.parent_hir_node(n)`][parent_hir_node]. -[get_parent_item]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.parent_hir_node +[parent_hir_node]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.parent_hir_node ## HIR Bodies From 4aa47cdf024528e8e2f14176d3897db9a0fe8264 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 19 Apr 2025 15:12:11 +0200 Subject: [PATCH 210/447] document `#[cfg(bootstrap)]` in dependencies --- src/SUMMARY.md | 1 + .../bootstrap-in-dependencies.md | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/building/bootstrapping/bootstrap-in-dependencies.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 90fcde072..68112d061 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -81,6 +81,7 @@ - [How Bootstrap does it](./building/bootstrapping/how-bootstrap-does-it.md) - [Writing tools in Bootstrap](./building/bootstrapping/writing-tools-in-bootstrap.md) - [Debugging bootstrap](./building/bootstrapping/debugging-bootstrap.md) +- [cfg(bootstrap) in dependencies](./building/bootstrapping/bootstrap-in-dependencies.md) # High-level Compiler Architecture diff --git a/src/building/bootstrapping/bootstrap-in-dependencies.md b/src/building/bootstrapping/bootstrap-in-dependencies.md new file mode 100644 index 000000000..68c5c2386 --- /dev/null +++ b/src/building/bootstrapping/bootstrap-in-dependencies.md @@ -0,0 +1,53 @@ +# `cfg(bootstrap)` in compiler dependencies + +The rust compiler uses some external crates that can run into cyclic dependencies with the compiler itself: the compiler needs an updated crate to build, but the crate needs an updated compiler. This page describes how `#[cfg(bootstrap)]` can be used to break this cycle. + +## Enabling `#[cfg(bootstrap)]` + +Usually the use of `#[cfg(bootstrap)]` in an external crate causes a warning: + +``` +warning: unexpected `cfg` condition name: `bootstrap` + --> src/main.rs:1:7 + | +1 | #[cfg(bootstrap)] + | ^^^^^^^^^ + | + = help: expected names are: `docsrs`, `feature`, and `test` and 31 more + = help: consider using a Cargo feature instead + = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint: + [lints.rust] + unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } + = help: or consider adding `println!("cargo::rustc-check-cfg=cfg(bootstrap)");` to the top of the `build.rs` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default +``` + +This warning can be silenced by adding these lines to the project's `Cargo.toml`: + +```toml +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } +``` + +Now `#[cfg(bootstrap)]` can be used in the crate just like it can be in the compiler: when the bootstrap compiler is used, code annotated with `#[cfg(bootstrap)]` is compiled, otherwise code annotated with `#[cfg(not(bootstrap))]` is compiled. + +## The update dance + +As a concrete example we'll use a change where the `#[naked]` attribute was made into an unsafe attribute, which caused a cyclic dependency with the `compiler-builtins` crate. + +### Step 1: accept the new behavior in the compiler ([#139797](https://github.com/rust-lang/rust/pull/139797)) + +In this example it is possible to accept both the old and new behavior at the same time by disabling an error. + +### Step 2: update the crate ([#821](https://github.com/rust-lang/compiler-builtins/pull/821)) + +Now in the crate, use `#[cfg(bootstrap)]` to use the old behavior, or `#[cfg(not(bootstrap))]` to use the new behavior. + +### Step 3: update the crate version used by the compiler ([#139934](https://github.com/rust-lang/rust/pull/139934)) + +For `compiler-builtins` this meant a version bump, in other cases it may be a git submodule update. + +### Step 4: remove the old behavior from the compiler ([#139753](https://github.com/rust-lang/rust/pull/139753)) + +The updated crate can now be used. In this example that meant that the old behavior could be removed. From 58d5664e4e65b44726114c2218f5cded00a7193a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 19 Apr 2025 17:51:41 +0200 Subject: [PATCH 211/447] needed a stronger pause --- src/tests/ui.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index 7c4e2a0fd..f7857ae69 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -337,7 +337,8 @@ possible, including `//~?` annotations for diagnostics without span. If the compile time output is target dependent or too verbose, use directive `//@ dont-require-annotations: ` to make the line annotation checking -non-exhaustive, some of the compiler messages can stay uncovered by annotations in this mode. +non-exhaustive. +Some of the compiler messages can stay uncovered by annotations in this mode. For checking runtime output `//@ check-run-results` may be preferable. From 0e5847e7c8e5ce5051ca1584db394557316eae94 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 19 Apr 2025 17:57:56 +0200 Subject: [PATCH 212/447] fix grammar --- src/tests/ui.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index f7857ae69..06b13a324 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -333,7 +333,7 @@ fn main() { Use of `error-pattern` is not recommended in general. For strict testing of compile time output, try to use the line annotations `//~` as much as -possible, including `//~?` annotations for diagnostics without span. +possible, including `//~?` annotations for diagnostics without spans. If the compile time output is target dependent or too verbose, use directive `//@ dont-require-annotations: ` to make the line annotation checking From 43a4aedbbe3332a3490aed3018808aaa2f7e4535 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 19 Apr 2025 17:56:23 +0200 Subject: [PATCH 213/447] improve readability by adding pauses --- src/tests/ui.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index 06b13a324..6232c8bcc 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -303,7 +303,7 @@ It should be preferred to using `error-pattern`, which is imprecise and non-exha ### `error-pattern` The `error-pattern` [directive](directives.md) can be used for runtime messages, which don't -have a specific span, or in exceptional cases for compile time messages. +have a specific span, or in exceptional cases, for compile time messages. Let's think about this test: @@ -316,7 +316,7 @@ fn main() { } ``` -We want to ensure this shows "index out of bounds" but we cannot use the `ERROR` +We want to ensure this shows "index out of bounds", but we cannot use the `ERROR` annotation since the runtime error doesn't have any span. Then it's time to use the `error-pattern` directive: @@ -340,12 +340,12 @@ If the compile time output is target dependent or too verbose, use directive non-exhaustive. Some of the compiler messages can stay uncovered by annotations in this mode. -For checking runtime output `//@ check-run-results` may be preferable. +For checking runtime output, `//@ check-run-results` may be preferable. Only use `error-pattern` if none of the above works. Line annotations `//~` are still checked in tests using `error-pattern`. -In exceptional cases use `//@ compile-flags: --error-format=human` to opt out of these checks. +In exceptional cases, use `//@ compile-flags: --error-format=human` to opt out of these checks. ### Diagnostic kinds (error levels) From d5cf5a36511bf129d011abb0ad247f3d36ec653c Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Mon, 21 Apr 2025 04:03:02 +0000 Subject: [PATCH 214/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 67de4a981..dc52e0928 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -a7c39b68616668a45f0afd62849a1da7c8ad2516 +b8005bff3248cfc6e327faf4fa631ac49bb49ba9 From e74f97682c0a19a2d27bb39987127e8b2f947622 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Tue, 22 Apr 2025 01:16:04 -0400 Subject: [PATCH 215/447] update build and test instructions --- src/autodiff/installation.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/autodiff/installation.md b/src/autodiff/installation.md index dbea9dbe1..f3c113955 100644 --- a/src/autodiff/installation.md +++ b/src/autodiff/installation.md @@ -25,9 +25,10 @@ rustup toolchain install nightly # enables -Z unstable-options You can then run our test cases: ```bash -./x.py test --stage 1 library tests/ui/autodiff -./x.py test --stage 1 library tests/codegen/autodiff -./x.py test --stage 1 library tests/pretty/autodiff* +./x.py test --stage 1 tests/codegen/autodiff +./x.py test --stage 1 tests/pretty/autodiff +./x.py test --stage 1 tests/ui/autodiff +./x.py test --stage 1 tests/ui/feature-gates/feature-gate-autodiff.rs ``` Autodiff is still experimental, so if you want to use it in your own projects, you will need to add `lto="fat"` to your Cargo.toml @@ -44,7 +45,7 @@ apt install wget vim python3 git curl libssl-dev pkg-config lld ninja-build cmak ``` Then build rustc in a slightly altered way: ```bash -git clone --depth=1 https://github.com/EnzymeAD/rust.git +git clone --depth=1 https://github.com/rust-lang/rust.git cd rust ./configure --enable-llvm-link-shared --enable-llvm-plugins --enable-llvm-enzyme --release-channel=nightly --enable-llvm-assertions --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs ./x dist @@ -54,7 +55,8 @@ We then copy the tarball to our host. The dockerid is the newest entry under `do docker cp :/rust/build/dist/rust-nightly-x86_64-unknown-linux-gnu.tar.gz rust-nightly-x86_64-unknown-linux-gnu.tar.gz ``` Afterwards we can create a new (pre-release) tag on the EnzymeAD/rust repository and make a PR against the EnzymeAD/enzyme-explorer repository to update the tag. -Remember to ping `tgymnich` on the PR to run his update script. +Remember to ping `tgymnich` on the PR to run his update script. Note: We should archive EnzymeAD/rust and update the instructions here. The explorer should soon +be able to get the rustc toolchain from the official rust servers. ## Build instruction for Enzyme itself From dd639a47fe6f75dfc4dbf7de04f0bdbe049000ab Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Wed, 23 Apr 2025 17:18:20 +0800 Subject: [PATCH 216/447] rustc-dev-guide: document that `//@ add-core-stubs` imply `-Cforce-unwind-tables=yes` --- src/tests/minicore.md | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/tests/minicore.md b/src/tests/minicore.md index e4853b6d4..507b259e0 100644 --- a/src/tests/minicore.md +++ b/src/tests/minicore.md @@ -6,25 +6,37 @@ ui/codegen/assembly test suites. It provides `core` stubs for tests that need to build for cross-compiled targets but do not need/want to run. +
+Please note that [`minicore`] is only intended for `core` items, and explicitly +**not** `std` or `alloc` items because `core` items are applicable to a wider +range of tests. +
+ A test can use [`minicore`] by specifying the `//@ add-core-stubs` directive. Then, mark the test with `#![feature(no_core)]` + `#![no_std]` + `#![no_core]`. Due to Edition 2015 extern prelude rules, you will probably need to declare `minicore` as an extern crate. +## Implied compiler flags + Due to the `no_std` + `no_core` nature of these tests, `//@ add-core-stubs` implies and requires that the test will be built with `-C panic=abort`. -Unwinding panics are not supported. +**Unwinding panics are not supported.** + +Tests will also be built with `-C force-unwind-tables=yes` to preserve CFI +directives in assembly tests. + +TL;DR: `//@ add-core-stubs` implies two compiler flags: + +1. `-C panic=abort` +2. `-C force-unwind-tables=yes` + +## Adding more `core` stubs If you find a `core` item to be missing from the [`minicore`] stub, consider adding it to the test auxiliary if it's likely to be used or is already needed by more than one test. -
-Please note that [`minicore`] is only intended for `core` items, and explicitly -**not** `std` or `alloc` items because `core` items are applicable to a wider -range of tests. -
- ## Example codegen test that uses `minicore` ```rust,no_run From ed695f448484768bb2b4ef3b2eaabe4f5798687b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 18 Apr 2025 10:46:20 +1000 Subject: [PATCH 217/447] Separate `Analysis` and `Results`. `Results` contains and `Analysis` and an `EntryStates`. The unfortunate thing about this is that the analysis needs to be mutable everywhere (`&mut Analysis`) which forces the `Results` to be mutable everywhere, even though `EntryStates` is immutable everywhere. To fix this, this commit renames `Results` as `AnalysisAndResults`, renames `EntryStates` as `Results`, and separates the analysis and results as much as possible. (`AnalysisAndResults` doesn't get much use, it's mostly there to facilitate method chaining of `iterate_to_fixpoint`.) `Results` is immutable everywhere, which: - is a bit clearer on how the data is used, - avoids an unnecessary clone of entry states in `locals_live_across_suspend_points`, and - moves the results outside the `RefCell` in Formatter. The commit also reformulates `ResultsHandle` as the generic `CowMut`, which is simpler than `ResultsHandle` because it doesn't need the `'tcx` lifetime and the trait bounds. It also which sits nicely alongside the new use of `Cow` in `ResultsCursor`. --- src/mir/dataflow.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mir/dataflow.md b/src/mir/dataflow.md index f31da5ca2..85e57dd83 100644 --- a/src/mir/dataflow.md +++ b/src/mir/dataflow.md @@ -148,8 +148,7 @@ whereas this code uses [`ResultsCursor`]: ```rust,ignore let mut results = MyAnalysis::new() - .into_engine(tcx, body, def_id) - .iterate_to_fixpoint() + .iterate_to_fixpoint(tcx, body, None); .into_results_cursor(body); // Inspect the fixpoint state immediately before each `Drop` terminator. From 4837eb332b17fb909a3c94b3ffe370691737c0e4 Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Thu, 24 Apr 2025 04:02:49 +0000 Subject: [PATCH 218/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index dc52e0928..dd333f98f 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -b8005bff3248cfc6e327faf4fa631ac49bb49ba9 +c02a4f0852e6665cf3df3867982021383f5615df From da24e304205f052886f167a169d79ac464d9adf1 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 25 Apr 2025 15:17:19 +0800 Subject: [PATCH 219/447] Enable [behind-upstream] triagebot option Signed-off-by: xizheyin --- triagebot.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 12aa0b7b8..61093ecaa 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -9,3 +9,6 @@ allow-unauthenticated = [ # Automatically close and reopen PRs made by bots to run CI on them [bot-pull-requests] + +[behind-upstream] +days-threshold = 7 \ No newline at end of file From 55d22e3d8cb8584df0fc3a5e76991834c9703084 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 25 Apr 2025 18:32:43 +0200 Subject: [PATCH 220/447] typo --- src/building/bootstrapping/what-bootstrapping-does.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/building/bootstrapping/what-bootstrapping-does.md b/src/building/bootstrapping/what-bootstrapping-does.md index 1dd5402f4..ffcfe2596 100644 --- a/src/building/bootstrapping/what-bootstrapping-does.md +++ b/src/building/bootstrapping/what-bootstrapping-does.md @@ -394,8 +394,8 @@ will be rare to want to use it. Finally, `MAGIC_EXTRA_RUSTFLAGS` bypasses the this is `compiletest`. For unit tests and doc tests this is the `libtest` runner. -Most test runner accept `--help`, which you can use to find out the options -accepted by the runner. +Most test runners accept `--help`, +which you can use to find out the options accepted by the runner. ## Environment Variables From 0220b0b8a533edaf2d972e2221d9b5edd6a9ae06 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 26 Apr 2025 15:09:05 +0200 Subject: [PATCH 221/447] use correct code block markers --- src/git.md | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/git.md b/src/git.md index 177495b53..1f010e48f 100644 --- a/src/git.md +++ b/src/git.md @@ -38,13 +38,13 @@ If you've cloned your fork, then you will be able to reference it with `origin` in your local repo. It may be helpful to also set up a remote for the official rust-lang/rust repo via -```sh +```console git remote add upstream https://github.com/rust-lang/rust.git ``` if you're using HTTPS, or -```sh +```console git remote add upstream git@github.com:rust-lang/rust.git ``` @@ -112,7 +112,7 @@ See [Rebasing](#rebasing) for more about rebasing. This is not a problem from git's perspective. If you run `git remote -v`, it will say something like this: -``` +```console $ git remote -v origin git@github.com:jyn514/rust.git (fetch) origin git@github.com:jyn514/rust.git (push) @@ -158,11 +158,11 @@ To fix it, do the following things: ### I see "error: cannot rebase" when I try to rebase These are two common errors to see when rebasing: -``` +```console error: cannot rebase: Your index contains uncommitted changes. error: Please commit or stash them. ``` -``` +```console error: cannot rebase: You have unstaged changes. error: Please commit or stash them. ``` @@ -174,7 +174,7 @@ commit your changes, or make a temporary commit called a "stash" to have them st when you finish rebasing. You may want to configure git to make this "stash" automatically, which will prevent the "cannot rebase" error in nearly all cases: -``` +```console git config --global rebase.autostash true ``` @@ -205,7 +205,7 @@ git reset --hard master `git push` will not work properly and say something like this: -``` +```console ! [rejected] issue-xxxxx -> issue-xxxxx (non-fast-forward) error: failed to push some refs to 'https://github.com/username/rust.git' hint: Updates were rejected because the tip of your current branch is behind @@ -226,7 +226,7 @@ didn't write, it likely means you're trying to rebase over the wrong branch. For have a `rust-lang/rust` remote `upstream`, but ran `git rebase origin/master` instead of `git rebase upstream/master`. The fix is to abort the rebase and use the correct branch instead: -``` +```console git rebase --abort git rebase -i upstream/master ``` @@ -243,7 +243,7 @@ When updating your local repository with `git pull`, you may notice that sometim Git says you have modified some files that you have never edited. For example, running `git status` gives you something like (note the `new commits` mention): -``` +```console On branch master Your branch is up to date with 'origin/master'. @@ -278,12 +278,12 @@ merged. To do that, you need to rebase your work on top of rust-lang/rust. To rebase your feature branch on top of the newest version of the master branch of rust-lang/rust, checkout your branch, and then run this command: -``` +```console git pull --rebase https://github.com/rust-lang/rust.git master ``` > If you are met with the following error: -> ``` +> ```console > error: cannot pull with rebase: Your index contains uncommitted changes. > error: please commit or stash them. > ``` @@ -300,13 +300,13 @@ reapply the changes fails because your changes conflicted with other changes that have been made. You can tell that this happened because you'll see lines in the output that look like -``` +```console CONFLICT (content): Merge conflict in file.rs ``` When you open these files, you'll see sections of the form -``` +```console <<<<<<< HEAD Original code ======= @@ -346,7 +346,7 @@ will keep it up-to-date. You will also want to rebase your feature branches up-to-date as well. After pulling, you can checkout the feature branches and rebase them: -``` +```console git checkout master git pull upstream master --ff-only # to make certain there are no merge commits git rebase master feature_branch @@ -384,7 +384,7 @@ change the order in which they are applied, or "squash" them into each other. Alternatively, you can sacrifice the commit history like this: -``` +```console # squash all the changes into one commit so you only have to worry about conflicts once git rebase -i --keep-base master # and squash all changes along the way git rebase master @@ -422,7 +422,7 @@ it shows you the differences between your old diff and your new diff. Here's an example of `git range-diff` output (taken from [Git's docs][range-diff-example-docs]): -``` +```console -: ------- > 1: 0ddba11 Prepare for the inevitable! 1: c0debee = 2: cab005e Add a helpful message at the start 2: f00dbal ! 3: decafe1 Describe a bug @@ -499,7 +499,7 @@ Git and Github's default diff view for large moves *within* a file is quite poor line as deleted and each line as added, forcing you to compare each line yourself. Git has an option to show moved lines in a different color: -``` +```console git log -p --color-moved=dimmed-zebra --color-moved-ws=allow-indentation-change ``` @@ -515,7 +515,7 @@ that was force-pushed to make sure there are no unexpected changes. Many large files in the repo are autogenerated. To view a diff that ignores changes to those files, you can use the following syntax (e.g. Cargo.lock): -``` +```console git log -p ':!Cargo.lock' ``` @@ -545,7 +545,7 @@ The contents of submodules are ignored by Git: submodules are in some sense isol from the rest of the repository. However, if you try to `cd src/llvm-project` and then run `git status`: -``` +```console HEAD detached at 9567f08afc943 nothing to commit, working tree clean ``` @@ -576,7 +576,7 @@ that Git can nicely and fairly conveniently handle for us. Sometimes you might run into (when you run `git status`) -``` +```console Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git restore ..." to discard changes in working directory) @@ -586,7 +586,7 @@ Changes not staged for commit: and when you try to run `git submodule update` it breaks horribly with errors like -``` +```console error: RPC failed; curl 92 HTTP/2 stream 7 was not closed cleanly: CANCEL (err 8) error: 2782 bytes of body are still expected fetch-pack: unexpected disconnect while reading sideband packet @@ -597,7 +597,7 @@ fatal: Fetched in submodule path 'src/llvm-project', but it did not contain 5a51 If you see `(new commits, modified content)` you can run -```bash +```console $ git submodule foreach git reset --hard ``` @@ -607,7 +607,7 @@ and then try `git submodule update` again. If that doesn't work, you can try to deinit all git submodules... -``` +```console git submodule deinit -f --all ``` @@ -618,7 +618,7 @@ completely messed up for some reason. Sometimes, for some forsaken reason, you might run into -```text +```console fatal: not a git repository: src/gcc/../../.git/modules/src/gcc ``` From 2b4bd30756793a86d1aaf401070998c43c54bf70 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 26 Apr 2025 15:18:36 +0200 Subject: [PATCH 222/447] copy-paste ease --- src/git.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/git.md b/src/git.md index 1f010e48f..5a6986185 100644 --- a/src/git.md +++ b/src/git.md @@ -598,7 +598,7 @@ fatal: Fetched in submodule path 'src/llvm-project', but it did not contain 5a51 If you see `(new commits, modified content)` you can run ```console -$ git submodule foreach git reset --hard +git submodule foreach git reset --hard ``` and then try `git submodule update` again. From e36f9af1cd4b39c5111522e4794f84564cac55e1 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 26 Apr 2025 15:34:43 +0200 Subject: [PATCH 223/447] replace command that does not work --- src/git.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/git.md b/src/git.md index 5a6986185..8118ddff1 100644 --- a/src/git.md +++ b/src/git.md @@ -256,9 +256,12 @@ Changes not staged for commit: no changes added to commit (use "git add" and/or "git commit -a") ``` -These changes are not changes to files: they are changes to submodules (more on this -[later](#git-submodules)). To get rid of those, run `./x --help`, which will automatically update -the submodules. +These changes are not changes to files: they are changes to submodules (more on this [later](#git-submodules)). +To get rid of those: + +```console +git submodule update +``` Some submodules are not actually needed; for example, `src/llvm-project` doesn't need to be checked out if you're using `download-ci-llvm`. To avoid having to keep fetching its history, you can use From 420aa5f9ea27338632fad055b485a656016fb06e Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Mon, 28 Apr 2025 04:02:47 +0000 Subject: [PATCH 224/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index dd333f98f..67fa25f22 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -c02a4f0852e6665cf3df3867982021383f5615df +deb947971c8748f5c6203548ce4af9022f21eaf0 From 1b150ed05cde2f847dc5e6d62b799c46e827f499 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 28 Apr 2025 06:49:13 +0200 Subject: [PATCH 225/447] use repo name in push pr title I found "Rustc dev guide subtree update awkward" --- josh-sync/src/sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/josh-sync/src/sync.rs b/josh-sync/src/sync.rs index cd64be636..41d96397f 100644 --- a/josh-sync/src/sync.rs +++ b/josh-sync/src/sync.rs @@ -194,7 +194,7 @@ impl GitSync { ); println!( // Open PR with `subtree update` title to silence the `no-merges` triagebot check - " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=Rustc+dev+guide+subtree+update&body=r?+@ghost" + " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=rustc-dev-guide+subtree+update&body=r?+@ghost" ); drop(josh); From d0998d33cb45c2cafee8eca26499b8bfce3c4cd5 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 28 Apr 2025 11:29:42 -0700 Subject: [PATCH 226/447] Add an example of the example of an edition migration lint It was observed that some people were missing the `edition20xx` rustdoc attribute. Although this probably won't solve that problem, I'd still like to highlight it as something to be aware of. --- src/guides/editions.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/guides/editions.md b/src/guides/editions.md index ea2071677..750631dfe 100644 --- a/src/guides/editions.md +++ b/src/guides/editions.md @@ -193,6 +193,23 @@ When a user runs `cargo fix --edition`, cargo will pass the `--force-warn rust-2 flag to force all of these lints to appear during the edition migration. Cargo also passes `--cap-lints=allow` so that no other lints interfere with the edition migration. +Make sure that the example code sets the correct edition. The example should illustrate the previous edition, and show what the migration warning would look like. For example, this lint for a 2024 migration shows an example in 2021: + +```rust,ignore +declare_lint! { + /// The `keyword_idents_2024` lint detects ... + /// + /// ### Example + /// + /// ```rust,edition2021 + /// #![warn(keyword_idents_2024)] + /// fn gen() {} + /// ``` + /// + /// {{produces}} +} +``` + Migration lints can be either `Allow` or `Warn` by default. If it is `Allow`, users usually won't see this warning unless they are doing an edition migration manually or there is a problem during the migration. From 4ba34d12fb65e9b267271b5c0fdb8ec25c58ccdd Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 28 Apr 2025 11:30:33 -0700 Subject: [PATCH 227/447] Add documentation on how to migration the edition of the standard library Based on lessons learned from 2024. There's probably still more details to say here since it was a ton of work. These are the major points that I remember. --- src/guides/editions.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/guides/editions.md b/src/guides/editions.md index 750631dfe..99a61d29a 100644 --- a/src/guides/editions.md +++ b/src/guides/editions.md @@ -351,3 +351,21 @@ In general it is recommended to avoid these special cases except for very high v [into-iter]: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html [panic-macro]: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html [`non_fmt_panics`]: https://doc.rust-lang.org/nightly/rustc/lints/listing/warn-by-default.html#non-fmt-panics + +### Migrating the standard library edition + +Updating the edition of the standard library itself roughly involves the following process: + +- Wait until the newly stabilized edition has reached beta and the bootstrap compiler has been updated. +- Apply migration lints. This can be an involved process since some code is in external submodules[^std-submodules], and the standard library makes heavy use of conditional compilation. Also, running `cargo fix --edition` can be impractical on the standard library itself. One approach is to individually add `#![warn(...)]` at the top of each crate for each lint, run `./x check library`, apply the migrations, remove the `#![warn(...)]` and commit each migration separately. You'll likely need to run `./x check` with `--target` for many different targets to get full coverage (otherwise you'll likely spend days or weeks getting CI to pass)[^ed-docker]. See also the [advanced migration guide] for more tips. + - Apply migrations to [`backtrace-rs`]. [Example for 2024](https://github.com/rust-lang/backtrace-rs/pull/700). Note that this doesn't update the edition of the crate itself because that is published independently on crates.io, and that would otherwise restrict the minimum Rust version. Consider adding some `#![deny()]` attributes to avoid regressions until its edition gets updated. + - Apply migrations to [`stdarch`], and update its edition, and formatting. [Example for 2024](https://github.com/rust-lang/stdarch/pull/1710). + - Post PRs to update the backtrace and stdarch submodules, and wait for those to land. + - Apply migration lints to the standard library crates, and update their edition. I recommend working one crate at a time starting with `core`. [Example for 2024](https://github.com/rust-lang/rust/pull/138162). + +[^std-submodules]: This will hopefully change in the future to pull these submodules into `rust-lang/rust`. +[^ed-docker]: You'll also likely need to do a lot of testing for different targets, and this is where [docker testing](../tests/docker.md) comes in handy. + +[advanced migration guide]: https://doc.rust-lang.org/nightly/edition-guide/editions/advanced-migrations.html +[`backtrace-rs`]: https://github.com/rust-lang/backtrace-rs/ +[`stdarch`]: https://github.com/rust-lang/stdarch/ From 5df71be99d61bf9f28a0aecf12155b1ddcd67fc0 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 28 Apr 2025 11:41:17 -0700 Subject: [PATCH 228/447] Update mdbook to 0.4.48 This updates to the latest version of mdbook which has had a variety of fixes of new features since the last update. Changelog: https://github.com/rust-lang/mdBook/blob/master/CHANGELOG.md#mdbook-0448 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 415d0dc39..daf5223cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: if: github.repository == 'rust-lang/rustc-dev-guide' runs-on: ubuntu-latest env: - MDBOOK_VERSION: 0.4.21 + MDBOOK_VERSION: 0.4.48 MDBOOK_LINKCHECK2_VERSION: 0.9.1 MDBOOK_MERMAID_VERSION: 0.12.6 MDBOOK_TOC_VERSION: 0.11.2 From fb49fb6ba0be720f6ceadec63dda08cabf93fc74 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 28 Apr 2025 11:31:09 -0700 Subject: [PATCH 229/447] Add documentation on how to stabilize the compiler edition This adds documentation on how to stabilize the edition in the compiler. --- src/guides/editions.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/guides/editions.md b/src/guides/editions.md index 99a61d29a..9a92d4ebc 100644 --- a/src/guides/editions.md +++ b/src/guides/editions.md @@ -369,3 +369,22 @@ Updating the edition of the standard library itself roughly involves the followi [advanced migration guide]: https://doc.rust-lang.org/nightly/edition-guide/editions/advanced-migrations.html [`backtrace-rs`]: https://github.com/rust-lang/backtrace-rs/ [`stdarch`]: https://github.com/rust-lang/stdarch/ + +## Stabilizing an edition + +After the edition team has given the go-ahead, the process for stabilizing an edition is roughly: + +- Update [`LATEST_STABLE_EDITION`]. +- Update [`Edition::is_stable`]. +- Hunt and find any document that refers to edition by number, and update it: + - [`--edition` flag](https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/command-line-arguments.md#--edition-specify-the-edition-to-use) + - [Rustdoc attributes](https://github.com/rust-lang/rust/blob/master/src/doc/rustdoc/src/write-documentation/documentation-tests.md#attributes) +- Clean up any tests that use the `//@ edition` header to remove the `-Zunstable-options` flag to ensure they are indeed stable. Note: Ideally this should be automated, see [#133582]. +- Bless any tests that change. +- Update `lint-docs` to default to the new edition. + +See [example for 2024](https://github.com/rust-lang/rust/pull/133349). + +[`LATEST_STABLE_EDITION`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/edition/constant.LATEST_STABLE_EDITION.html +[`Edition::is_stable`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/edition/enum.Edition.html#method.is_stable +[#133582]: https://github.com/rust-lang/rust/issues/133582 From 7700fb5dc8db4ec8e93109bff73e73739cdf94e9 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Tue, 29 Apr 2025 16:39:54 +0300 Subject: [PATCH 230/447] Update compiler-src.md Refactor the dependency structure from a nested unordered list to a single-level ordered list. IMO, this is clearer, but happy to close this PR without merging, if the change is not desired. --- src/compiler-src.md | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/compiler-src.md b/src/compiler-src.md index c538fc8b7..0d3cbebb4 100644 --- a/src/compiler-src.md +++ b/src/compiler-src.md @@ -62,21 +62,20 @@ huge. There is also the `rustc` crate which is the actual binary (i.e. the [`rustc_driver`] crate, which drives the various parts of compilation in other crates. -The dependency structure of these crates is complex, but roughly it is +The dependency order of these crates is complex, but roughly it is something like this: -- `rustc` (the binary) calls [`rustc_driver::main`][main]. - - [`rustc_driver`] depends on a lot of other crates, but the main one is - [`rustc_interface`]. - - [`rustc_interface`] depends on most of the other compiler crates. It - is a fairly generic interface for driving the whole compilation. - - Most of the other `rustc_*` crates depend on [`rustc_middle`], - which defines a lot of central data structures in the compiler. - - [`rustc_middle`] and most of the other crates depend on a - handful of crates representing the early parts of the - compiler (e.g. the parser), fundamental data structures (e.g. - [`Span`]), or error reporting: [`rustc_data_structures`], - [`rustc_span`], [`rustc_errors`], etc. +1. `rustc` (the binary) calls [`rustc_driver::main`][main]. +1. [`rustc_driver`] depends on a lot of other crates, but the main one is + [`rustc_interface`]. +1. [`rustc_interface`] depends on most of the other compiler crates. It is a + fairly generic interface for driving the whole compilation. +1. Most of the other `rustc_*` crates depend on [`rustc_middle`], which defines + a lot of central data structures in the compiler. +1. [`rustc_middle`] and most of the other crates depend on a handful of crates + representing the early parts of the compiler (e.g. the parser), fundamental + data structures (e.g. [`Span`]), or error reporting: + [`rustc_data_structures`], [`rustc_span`], [`rustc_errors`], etc. [`rustc_data_structures`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/index.html [`rustc_driver`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/index.html From 38a5e54ccd8ff5671d16ecaa84662575916d14d5 Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 29 Apr 2025 15:28:04 +0100 Subject: [PATCH 231/447] Introduce a normalization chapter --- src/SUMMARY.md | 2 +- src/normalization.md | 309 +++++++++++++++++++++++++++++++ src/solve/normalization.md | 127 ------------- src/solve/significant-changes.md | 2 +- 4 files changed, 311 insertions(+), 129 deletions(-) create mode 100644 src/normalization.md delete mode 100644 src/solve/normalization.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 68112d061..6aa37fa9e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -156,6 +156,7 @@ - [ADTs and Generic Arguments](./ty_module/generic_arguments.md) - [Parameter types/consts/regions](./ty_module/param_ty_const_regions.md) - [`TypeFolder` and `TypeFoldable`](./ty-fold.md) +- [Aliases and Normalization](./normalization.md) - [Typing/Param Envs](./typing_parameter_envs.md) - [Type inference](./type-inference.md) - [Trait solving](./traits/resolution.md) @@ -175,7 +176,6 @@ - [Coinduction](./solve/coinduction.md) - [Caching](./solve/caching.md) - [Proof trees](./solve/proof-trees.md) - - [Normalization](./solve/normalization.md) - [Opaque types](./solve/opaque-types.md) - [Significant changes and quirks](./solve/significant-changes.md) - [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md) diff --git a/src/normalization.md b/src/normalization.md new file mode 100644 index 000000000..43ee05b8b --- /dev/null +++ b/src/normalization.md @@ -0,0 +1,309 @@ +# Aliases and Normalization + + + +## 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. + +Normalization is the process of taking these alias types and replacing them with the underlying type that they are equal to. For example given some type alias `type Foo = u32`, normalizing `Foo` would give `u32`. + +The concept of an alias is not unique to *types* and the concept also applies to constants/const generics. However, right now in the compiler we don't really treat const aliases as a "first class concept" so this chapter mostly discusses things in the context of types (even though the concepts transfer just fine). + +[tykind_alias]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/enum.TyKind.html#variant.Alias +[aliaskind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/enum.AliasTyKind.html + +### Rigid, Ambiguous and Unnormalized Aliases + +Aliases can either be "rigid", "ambiguous", or simply unnormalized. + +We consider types to be rigid if their "shape" isn't going to change, for example `Box` is rigid as no amount of normalization can turn a `Box` into a `u32`, whereas ` as Iterator>::Item` is not rigid as it can be normalized to `u32`. + +Aliases are rigid when we will never be able to normalize them further. A concrete example of a *rigid* alias would be `::Item` in an environment where there is no `T: Iterator` bound, only a `T: Iterator` bound: +```rust +fn foo() { + // This alias is *rigid* + let _: ::Item; +} + +fn bar>() { + // This alias is *not* rigid as it can be normalized to `u32` + let _: ::Item; +} +``` + +When an alias can't yet be normalized but may wind up normalizable in the [current environment](./typing_parameter_envs.md), we consider it to be an "ambiguous" alias. This can occur when an alias contains inference variables which prevent being able to determine how the trait is implemented: +```rust +fn foo() { + // This alias is considered to be "ambiguous" + let _: <_ as Iterator>::Item; +} +``` + +The reason we call them "ambiguous" aliases is because its *ambiguous* whether this is a rigid alias or not. + +The source of the `_: Iterator` trait impl is *ambiguous* (i.e. unknown), it could be some `impl Iterator for u32` or it could be some `T: Iterator` trait bound, we don't know yet. Depending on why `_: Iterator` holds the alias could be an unnormalized alias or it could be a rigid alias; it's *ambiguous* what kind of alias this is. + +Finally, an alias can just be unnormalized, ` as IntoIterator>::Iter` is an unnormalized alias as it can already be normalized to `std::vec::IntoIter`, it just hasn't been done yet. + +--- + +It is worth noting that Free and Inherent aliases cannot be rigid or ambiguous as naming them also implies having resolved the definition of the alias, which specifies the underlying type of the alias. + +### Diverging Aliases + +An alias is considered to "diverge" if its definition does not specify an underlying non-alias type to normalize to. A concrete example of diverging aliases: +```rust +type Diverges = Diverges; + +trait Trait { + type DivergingAssoc; +} +impl Trait for () { + type DivergingAssoc = <() as Trait>::DivergingAssoc; +} +``` +In this example both `Diverges` and `DivergingAssoc` are "trivial" cases of diverging type aliases where they have been defined as being equal to themselves. There is no underlying type that `Diverges` can ever be normalized to. + +We generally try to error when diverging aliases are defined, but this is entirely a "best effort" check. In the previous example the definitions are "simple enough" to be detected and so errors are emitted. However, in more complex cases, or cases where only some instantiations of generic parameters would result in a diverging alias, we don't emit an error: +```rust +trait Trait { + type DivergingAssoc; +} +impl Trait for T { + // This alias always diverges but we don't emit an error because + // the compiler can't "see" that. + type DivergingAssoc = ::DivergingAssoc; +} +``` + +Ultimately this means that we have no guarantee that aliases in the type system are non-diverging. As aliases may only diverge for some specific generic arguments, it also means that we only know whether an alias diverges once it is fully concrete. This means that codegen/const-evaluation also has to handle diverging aliases: +```rust +trait Trait { + type Diverges; +} +impl Trait for T { + type Diverges = ::Diverges; +} + +fn foo() { + let a: T::Diverges; +} + +fn main() { + foo::<()>(); +} +``` +In this example we only encounter an error from the diverging alias during codegen of `foo::<()>`, if the call to `foo` is removed then no compilation error will be emitted. + +### Opaque Types + +Opaque types are a relatively special kind of alias, and are covered in their own chapter: [Opaque types](./opaque-types-type-alias-impl-trait.md). + +### Const Aliases + +Unlike type aliases, const aliases are not represented directly in the type system, instead const aliases are always an anonymous body containing a path expression to a const item. This means that the only "const alias" in the type system is an anonymous unevaluated const body. + +As such there is no `ConstKind::Alias(AliasCtKind::Projection/Inherent/Free, _)`, instead we only have `ConstKind::Unevaluated` which is used for representing anonymous constants. + +```rust +fn foo() {} + +const FREE_CONST: usize = 1 + 1; + +fn bar() { + foo::<{ FREE_CONST }>(); + // The const arg is represented with some anonymous constant: + // ```pseudo-rust + // const ANON: usize = FREE_CONST; + // foo::(); + // ``` +} +``` + +This is likely to change as const generics functionality is improved, for example `feature(associated_const_equality)` and `feature(min_generic_const_args)` both require handling const aliases similarly to types (without an anonymous constant wrapping all const args). + +## What is Normalization + +### Structural vs Deep normalization + +There are two forms of normalization, structural (sometimes called *shallow*) and deep. Structural normalization should be thought of as only normalizing the "outermost" part of a type. On the other hand deep normalization will normalize *all* aliases in a type. + +In practice structural normalization can result in more than just the outer layer of the type being normalized[^1], but this behaviour should not be relied upon. Unnormalizable non-rigid aliases making use of bound variables (`for<'a>`) cannot be normalized by either kind of normalization. + +As an example: conceptually, structurally normalizing the type `Vec<::Assoc>` would be a no-op, whereas deeply normalizing would give `Vec`. In practice even structural normalization would give `Vec`, though, again, this should not be relied upon. + +Changing the alias to use bound variables will result in different behaviour; `Vec fn(<&'a u8 as Identity>::Assoc)>` would result in no change when structurally normalized, but would result in `Vec fn(&'a u8)>` when deeply normalized. + +### Core normalization logic + +Structurally normalizing aliases is a little bit more nuanced than replacing the alias with whatever it is defined as being equal to in its definition; the result of normalizing an alias should either be a rigid type or an inference variable (which will later be inferred to a rigid type). To accomplish this we do two things: + +First, when normalizing an ambiguous alias it is normalized to an inference variable instead of leaving it as-is, this has two main effects: +- Even though an inference variable is not a rigid type, it will always wind up inferred *to* a rigid type so we ensure that the result of normalization will not need to be normalized again +- Inference variables are used in all cases where a type is non-rigid, allowing the rest of the compiler to not have to deal with *both* ambiguous aliases *and* inference variables + +Secondly, instead of having normalization directly return the type specified in the definition of the alias, we normalize the type first before returning it[^1]. We do this so that normalization is idempotent/callers do not need to run it in a loop. + +```rust +#![feature(lazy_type_alias)] + +type Foo = Bar; +type Bar = ::Item; + +fn foo() { + let a_: Foo<_>; +} +``` + +In this example: +- Normalizing `Foo` would result in `Bar`, except we want to normalize aliases in the type `Foo` is defined as equal to +- Normalizing `Bar` would result in `::Item`, except, again, we want to normalize aliases in the type `Bar` is defined as equal to +- Normalizing `::Item` results in some new inference variable `?y`, as `::Item` is an ambiguous alias +- The final result is that normalizing `Foo` results in `?y` + +[^1]: In the new solver this is done implicitly + +## How to normalize + +When interfacing with the type system it will often be the case that it's necessary to request a type be normalized. There are a number of different entry points to the underlying normalization logic and each entry point should only be used in specific parts of the compiler. + +An additional complication is that the compiler is currently undergoing a transition from the old trait solver to the new trait solver. As part of this transition our approach to normalization in the compiler has changed somewhat significantly, resulting in some normalization entry points being "old solver only" slated for removal in the long-term once the new solver has stabilized. + +Here is a rough overview of the different entry points to normalization in the compiler: +- `infcx.at.structurally_normalize` +- `infcx.at.(deeply_)?normalize` +- `infcx.query_normalize` +- `tcx.normalize_erasing_regions` +- `traits::normalize_with_depth(_to)` +- `EvalCtxt::structurally_normalize` + +### Outside of the trait solver + +The [`InferCtxt`][infcx] type exposes the "main" ways to normalize during analysis: [`normalize`][normalize], [`deeply_normalize`][deeply_normalize] and [`structurally_normalize`][structurally_normalize]. These functions are often wrapped and re-exposed on various `InferCtxt` wrapper types, such as [`FnCtxt`][fcx] or [`ObligationCtxt`][ocx] with minor API tweaks to handle some arguments or parts of the return type automatically. + +#### Structural `InferCtxt` normalization + +[`infcx.at.structurally_normalize`][structurally_normalize] exposes structural normalization that is able to handle inference variables and regions. It should generally be used whenever inspecting the kind of a type. + +Inside of HIR Typeck there is a related method of normalization- [`fcx.structurally_resolve`][structurally_resolve], which will error if the type being resolved is an unresolved inference variable. When the new solver is enabled it will also attempt to structurally normalize the type. + +Due to this there is a pattern in HIR typeck where a type is first normalized via `normalize` (only normalizing in the old solver), and then `structurally_resolve`'d (only normalizing in the new solver). This pattern should be preferred over calling `structurally_normalize` during HIR typeck as `structurally_resolve` will attempt to make inference progress by evaluating goals whereas `structurally_normalize` does not. + +#### Deep `InferCtxt` normalization + +##### `infcx.at.(deeply_)?normalize` + +There are two ways to deeply normalize with an `InferCtxt`, `normalize` and `deeply_normalize`. The reason for this is that `normalize` is a "legacy" normalization entry point used only by the old solver, whereas `deeply_normalize` is intended to be the long term way to deeply normalize. Both of these methods can handle regions. + +When the new solver is stabilized the `infcx.at.normalize` function will be removed and everything will have been migrated to the new deep or structural normalization methods. For this reason the `normalize` function is a no-op under the new solver, making it suitable only when the old solver needs normalization but the new solver does not. + +Using `deeply_normalize` will result in errors being emitted when encountering ambiguous aliases[^1] as it is not possible to support normalizing *all* ambiguous aliases to inference variables[^2]. `deeply_normalize` should generally only be used in cases where we do not expect to encounter ambiguous aliases, for example when working with types from item signatures. + +[^1]: There is a subtle difference in how ambiguous aliases in binders are handled between old and new solver. In the old solver we fail to error on some ambiguous aliases inside of higher ranked types whereas the new solver correctly errors. + +[^2]: Ambiguous aliases inside of binders cannot be normalized to inference variables, this will be covered more later. + +##### `infcx.query_normalize` + +[`infcx.query_normalize`][query_norm] is very rarely used, it has almost all the same restrictions as `normalize_erasing_regions` (cannot handle inference variables, no diagnostics support) with the main difference being that it retains lifetime information. For this reason `normalize_erasing_regions` is the better choice in almost all circumstances as it is more efficient due to caching lifetime-erased queries. + +In practice `query_normalize` is used for normalization in the borrow checker, and elsewhere as a performance optimization over `infcx.normalize`. Once the new solver is stabilized it is expected that `query_normalize` can be removed from the compiler as the new solvers normalization implementation should be performant enough for it to not be a performance regression. + +##### `tcx.normalize_erasing_regions` + +[`normalize_erasing_regions`][norm_erasing_regions] is generally used by parts of the compiler that are not doing type system analysis. This normalization entry point does not handle inference variables, lifetimes, or any diagnostics. Lints and codegen make heavy use of this entry point as they typically are working with fully inferred aliases that can be assumed to be well formed (or at least, are not responsible for erroring on). + +[query_norm]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/infer/at/struct.At.html#method.query_normalize +[norm_erasing_regions]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.normalize_erasing_regions +[normalize]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/infer/at/struct.At.html#method.normalize +[deeply_normalize]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/normalize/trait.NormalizeExt.html#tymethod.deeply_normalize +[structurally_normalize]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/trait.StructurallyNormalizeExt.html#tymethod.structurally_normalize_ty +[infcx]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/infer/struct.InferCtxt.html +[fcx]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html +[ocx]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/struct.ObligationCtxt.html +[structurally_resolve]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#method.structurally_resolve_type + +### Inside of the trait solver + +[`traits::normalize_with_depth(_to)`][norm_with_depth] and [`EvalCtxt::structurally_normalize`][eval_ctxt_structural_norm] are only used by the internals of the trait solvers (old and new respectively). It is effectively a raw entry point to the internals of how normalization is implemented by each trait solver. Other normalization entry points cannot be used from within the internals of trait solving as it wouldn't handle goal cycles and recursion depth correctly. + +[norm_with_depth]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/normalize/fn.normalize_with_depth.html +[eval_ctxt_structural_norm]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/struct.EvalCtxt.html#method.structurally_normalize_term + +## When/Where to normalize (Old vs New solver) + +One of the big changes between the old and new solver is our approach to when we expect aliases to be normalized. + +### Old solver + +All types are expected to be normalized as soon as possible, so that all types encountered in the type system are either rigid or an inference variable (which will later be inferred to a rigid term). + +As a concrete example: equality of aliases is implemented by assuming they're rigid and recursively equating the generic arguments of the alias. + +### New solver + +It's expected that all types potentially contain ambiguous or unnormalized aliases. Whenever an operation is performed that requires aliases to be normalized, it's the responsibility of that logic to normalize the alias (this means that matching on `ty.kind()` pretty much always has to structurally normalize first). + +As a concrete example: equality of aliases is implemented by a custom goal kind ([`PredicateKind::AliasRelate`][aliasrelate]) so that it can handle normalization of the aliases itself instead of assuming all alias types being equated are rigid. + +Despite this approach we still deeply normalize during [writeback][writeback] for performance/simplicity, so that types in the MIR can still be assumed to have been deeply normalized. + +[aliasrelate]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.PredicateKind.html#variant.AliasRelate +[writeback]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/writeback/index.html + +--- + +There were a few main issues with the old solver's approach to normalization that motivated changing things in the new solver: + +### Missing normalization calls + +It was a frequent occurrence that normalization calls would be missing, resulting in passing unnormalized types to APIs expecting everything to already be normalized. Treating ambiguous or unnormalized aliases as rigid would result in all sorts of weird errors from aliases not being considered equal to one another, or surprising inference guidance from equating unnormalized aliases' generic arguments. + +### Normalizing parameter environments + +Another problem was that it was not possible to normalize `ParamEnv`s correctly in the old solver as normalization itself would expect a normalized `ParamEnv` in order to give correct results. See the chapter on `ParamEnv`s for more information: [`Typing/ParamEnv`s: Normalizing all bounds](./typing_parameter_envs.md#normalizing-all-bounds) + +### Unnormalizable non-rigid aliases in higher ranked types + +Given a type such as `for<'a> fn(::Assoc>)`, it is not possible to correctly handle this with the old solver's approach to normalization. + +If we were to normalize it to `for<'a> fn(?y)` and register a goal to normalize `for<'a> >::Assoc -> ?y`, this would result in errors in cases where `>::Assoc` normalized to `&'a u32`. The inference variable `?y` would be in a lower [universe][universes] than the placeholders made when instantiating the `for<'a>` binder. + +Leaving the alias unnormalized would also be wrong as the old solver expects all aliases to be rigid. This was a soundness bug before the new solver was stabilized in coherence: [relating projection substs is unsound during coherence](https://github.com/rust-lang/rust/issues/102048). + +Ultimately this means that it is not always possible to ensure all aliases inside of a value are rigid. + +[universes]: https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference/placeholders_and_universes.html#what-is-a-universe +[deeply_normalize]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/normalize/trait.NormalizeExt.html#tymethod.deeply_normalize + +## Handling uses of diverging aliases + +Diverging aliases, like ambiguous aliases, are normalized to inference variables. As normalizing diverging aliases results in trait solver cycles, it always results in an error in the old solver. In the new solver it only results in an error if we wind up requiring all goals to hold in the current context. E.g. normalizing diverging aliases during HIR typeck will result in an error in both solvers. + +Alias well formedness doesn't require that the alias doesn't diverge[^1], this means that checking an alias is well formed isn't sufficient to cause an error to be emitted for diverging aliases; actually attempting to normalize the alias is required. + +Erroring on diverging aliases being a side effect of normalization means that it is very *arbitrary* whether we actually emit an error, it also differs between the old and new solver as we now normalize in less places. + +An example of the ad-hoc nature of erroring on diverging aliases causing "problems": +```rust +trait Trait { + type Diverges; +} + +impl Trait for T { + type Diverges = D::Diverges; +} + +struct Bar::Diverges>(Box); +``` + +In this example a diverging alias is used but we happen to not emit an error as we never explicitly normalize the defaults of generic parameters. If the `?Sized` opt out is removed then an error is emitted because we wind up happening to normalize a `::Diverges: Sized` goal which as a side effect results in erroring about the diverging alias. + +Const aliases differ from type aliases a bit here; well formedness of const aliases requires that they can be successfully evaluated (via [`ConstEvaluatable`][const_evaluatable] goals). This means that simply checking well formedness of const arguments is sufficient to error if they would fail to evaluate. It is somewhat unclear whether it would make sense to adopt this for type aliases too or if const aliases should stop requiring this for well formedness[^2]. + +[^1]: As checking aliases are non-diverging cannot be done until they are fully concrete, this would either imply that we cant check aliases are well formed before codegen/const-evaluation or that aliases would go from being well-formed to not well-formed after monomorphization. + +[^2]: Const aliases certainly wouldn't be *less* sound than type aliases if we stopped doing this + +[const_evaluatable]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ClauseKind.html#variant.ConstEvaluatable \ No newline at end of file diff --git a/src/solve/normalization.md b/src/solve/normalization.md deleted file mode 100644 index 99dc20c46..000000000 --- a/src/solve/normalization.md +++ /dev/null @@ -1,127 +0,0 @@ -# Normalization in the new solver - -> FIXME: Normalization has been changed significantly since this chapter was written. - -With the new solver we've made some fairly significant changes to normalization when compared -to the existing implementation. - -We now differentiate between "one-step normalization", "structural normalization" and -"deep normalization". - -## One-step normalization - -One-step normalization is implemented via `NormalizesTo` goals. Unlike other goals -in the trait solver, `NormalizesTo` always expects the term to be an unconstrained -inference variable[^opaques]. Think of it as a function, taking an alias as input -and returning its underlying value. If the alias is rigid, `NormalizesTo` fails and -returns `NoSolution`. This is the case for `::Assoc` if there's a `T: Trait` -where-bound and for opaque types with `Reveal::UserFacing` unless they are in the -defining scope. We must not treat any aliases as rigid in coherence. - -The underlying value may itself be an unnormalized alias, e.g. -`NormalizesTo(<<() as Id>::This as Id>::This)` only returns `<() as Id>::This`, -even though that alias can be further normalized to `()`. As the term is -always an unconstrained inference variable, the expected term cannot influence -normalization, see [trait-system-refactor-initiative#22] for more. - -Only ever computing `NormalizesTo` goals with an unconstrained inference variable -requires special solver support. It is only used by `AliasRelate` goals and pending -`NormalizesTo` goals are tracked separately from other goals: [source][try-eval-norm]. -As the expected term is always erased in `NormalizesTo`, we have to return its -ambiguous nested goals to its caller as not doing so weakens inference. See -[#122687] for more details. - -[trait-system-refactor-initiative#22]: https://github.com/rust-lang/trait-system-refactor-initiative/issues/22 -[try-eval-norm]: https://github.com/rust-lang/rust/blob/2627e9f3012a97d3136b3e11bf6bd0853c38a534/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs#L523-L537 -[#122687]: https://github.com/rust-lang/rust/pull/122687 - -## `AliasRelate` and structural normalization - -We structurally normalize an alias by applying one-step normalization until -we end up with a rigid alias, ambiguity, or overflow. This is done by repeatedly -evaluating `NormalizesTo` goals inside of a snapshot: [source][structural_norm]. - -`AliasRelate(lhs, rhs)` is implemented by first structurally normalizing both the -`lhs` and the `rhs` and then relating the resulting rigid types (or inference -variables). Importantly, if `lhs` or `rhs` ends up as an alias, this alias can -now be treated as rigid and gets unified without emitting a nested `AliasRelate` -goal: [source][structural-relate]. - -This means that `AliasRelate` with an unconstrained `rhs` ends up functioning -similar to `NormalizesTo`, acting as a function which fully normalizes `lhs` -before assigning the resulting rigid type to an inference variable. This is used by -`fn structurally_normalize_ty` both [inside] and [outside] of the trait solver. -This has to be used whenever we match on the value of some type, both inside -and outside of the trait solver. - - - -[structural_norm]: https://github.com/rust-lang/rust/blob/2627e9f3012a97d3136b3e11bf6bd0853c38a534/compiler/rustc_trait_selection/src/solve/alias_relate.rs#L140-L175 -[structural-relate]: https://github.com/rust-lang/rust/blob/a0569fa8f91b5271e92d2f73fd252de7d3d05b9c/compiler/rustc_trait_selection/src/solve/alias_relate.rs#L88-L107 -[inside]: https://github.com/rust-lang/rust/blob/a0569fa8f91b5271e92d2f73fd252de7d3d05b9c/compiler/rustc_trait_selection/src/solve/mod.rs#L278-L299 -[outside]: https://github.com/rust-lang/rust/blob/a0569fa8f91b5271e92d2f73fd252de7d3d05b9c/compiler/rustc_trait_selection/src/traits/structural_normalize.rs#L17-L48 - -## Deep normalization - -By walking over a type, and using `fn structurally_normalize_ty` for each encountered -alias, it is possible to deeply normalize a type, normalizing all aliases as much as -possible. However, this only works for aliases referencing bound variables if they are -not ambiguous as we're unable to replace the alias with a corresponding inference -variable without leaking universes. - - - -[generalize-no-alias]: https://github.com/rust-lang/rust/blob/a0569fa8f91b5271e92d2f73fd252de7d3d05b9c/compiler/rustc_infer/src/infer/relate/generalize.rs#L353-L358 - -## Outside of the trait solver - -The core type system - relating types and trait solving - will not need deep -normalization with the new solver. There are still some areas which depend on it. -For these areas there is the function `At::deeply_normalize`. Without additional -trait solver support deep normalization does not always work in case of ambiguity. -Luckily deep normalization is currently only necessary in places where there is no ambiguity. -`At::deeply_normalize` immediately fails if there's ambiguity. - -If we only care about the outermost layer of types, we instead use -`At::structurally_normalize` or `FnCtxt::(try_)structurally_resolve_type`. -Unlike `At::deeply_normalize`, structural normalization is also used in cases where we -have to handle ambiguity. - -Because this may result in behavior changes depending on how the trait solver handles -ambiguity, it is safer to also require full normalization there. This happens in -`FnCtxt::structurally_resolve_type` which always emits a hard error if the self type ends -up as an inference variable. There are some existing places which have a fallback for -inference variables instead. These places use `try_structurally_resolve_type` instead. - -## Why deep normalization with ambiguity is hard - -Fully correct deep normalization is very challenging, especially with the new solver -given that we do not want to deeply normalize inside of the solver. Mostly deeply normalizing -but sometimes failing to do so is bound to cause very hard to minimize and understand bugs. -If possible, avoiding any reliance on deep normalization entirely therefore feels preferable. - -If the solver itself does not deeply normalize, any inference constraints returned by the -solver would require normalization. Handling this correctly is ugly. This also means that -we change goals we provide to the trait solver by "normalizing away" some projections. - -The way we (mostly) guarantee deep normalization with the old solver is by eagerly replacing -the projection with an inference variable and emitting a nested `Projection` goal. This works -as `Projection` goals in the old solver deeply normalize. Unless we add another `PredicateKind` -for deep normalization to the new solver we cannot emulate this behavior. This does not work -for projections with bound variables, sometimes leaving them unnormalized. An approach which -also supports projections with bound variables will be even more involved. - -[^opaques]: opaque types are currently handled a bit differently. this may change in the future diff --git a/src/solve/significant-changes.md b/src/solve/significant-changes.md index c82b5d468..eac8f0318 100644 --- a/src/solve/significant-changes.md +++ b/src/solve/significant-changes.md @@ -106,4 +106,4 @@ their ambiguous nested goals are returned to the caller which then evaluates the See [#122687] for more details. [#122687]: https://github.com/rust-lang/rust/pull/122687 -[normalization]: ./normalization.md +[normalization]: ../normalization.md From 2eae1c6f998e596b276dc2cfa4276d8c71447e6d Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 29 Apr 2025 19:35:26 +0100 Subject: [PATCH 232/447] Fix footnotes --- src/normalization.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/normalization.md b/src/normalization.md index 43ee05b8b..ef530ccc5 100644 --- a/src/normalization.md +++ b/src/normalization.md @@ -129,7 +129,7 @@ This is likely to change as const generics functionality is improved, for exampl There are two forms of normalization, structural (sometimes called *shallow*) and deep. Structural normalization should be thought of as only normalizing the "outermost" part of a type. On the other hand deep normalization will normalize *all* aliases in a type. -In practice structural normalization can result in more than just the outer layer of the type being normalized[^1], but this behaviour should not be relied upon. Unnormalizable non-rigid aliases making use of bound variables (`for<'a>`) cannot be normalized by either kind of normalization. +In practice structural normalization can result in more than just the outer layer of the type being normalized, but this behaviour should not be relied upon. Unnormalizable non-rigid aliases making use of bound variables (`for<'a>`) cannot be normalized by either kind of normalization. As an example: conceptually, structurally normalizing the type `Vec<::Assoc>` would be a no-op, whereas deeply normalizing would give `Vec`. In practice even structural normalization would give `Vec`, though, again, this should not be relied upon. @@ -162,8 +162,6 @@ In this example: - Normalizing `::Item` results in some new inference variable `?y`, as `::Item` is an ambiguous alias - The final result is that normalizing `Foo` results in `?y` -[^1]: In the new solver this is done implicitly - ## How to normalize When interfacing with the type system it will often be the case that it's necessary to request a type be normalized. There are a number of different entry points to the underlying normalization logic and each entry point should only be used in specific parts of the compiler. @@ -198,11 +196,7 @@ There are two ways to deeply normalize with an `InferCtxt`, `normalize` and `dee When the new solver is stabilized the `infcx.at.normalize` function will be removed and everything will have been migrated to the new deep or structural normalization methods. For this reason the `normalize` function is a no-op under the new solver, making it suitable only when the old solver needs normalization but the new solver does not. -Using `deeply_normalize` will result in errors being emitted when encountering ambiguous aliases[^1] as it is not possible to support normalizing *all* ambiguous aliases to inference variables[^2]. `deeply_normalize` should generally only be used in cases where we do not expect to encounter ambiguous aliases, for example when working with types from item signatures. - -[^1]: There is a subtle difference in how ambiguous aliases in binders are handled between old and new solver. In the old solver we fail to error on some ambiguous aliases inside of higher ranked types whereas the new solver correctly errors. - -[^2]: Ambiguous aliases inside of binders cannot be normalized to inference variables, this will be covered more later. +Using `deeply_normalize` will result in errors being emitted when encountering ambiguous aliases[^2] as it is not possible to support normalizing *all* ambiguous aliases to inference variables[^3]. `deeply_normalize` should generally only be used in cases where we do not expect to encounter ambiguous aliases, for example when working with types from item signatures. ##### `infcx.query_normalize` @@ -281,7 +275,7 @@ Ultimately this means that it is not always possible to ensure all aliases insid Diverging aliases, like ambiguous aliases, are normalized to inference variables. As normalizing diverging aliases results in trait solver cycles, it always results in an error in the old solver. In the new solver it only results in an error if we wind up requiring all goals to hold in the current context. E.g. normalizing diverging aliases during HIR typeck will result in an error in both solvers. -Alias well formedness doesn't require that the alias doesn't diverge[^1], this means that checking an alias is well formed isn't sufficient to cause an error to be emitted for diverging aliases; actually attempting to normalize the alias is required. +Alias well formedness doesn't require that the alias doesn't diverge[^4], this means that checking an alias is well formed isn't sufficient to cause an error to be emitted for diverging aliases; actually attempting to normalize the alias is required. Erroring on diverging aliases being a side effect of normalization means that it is very *arbitrary* whether we actually emit an error, it also differs between the old and new solver as we now normalize in less places. @@ -300,10 +294,16 @@ struct Bar::Diverges>(Box); In this example a diverging alias is used but we happen to not emit an error as we never explicitly normalize the defaults of generic parameters. If the `?Sized` opt out is removed then an error is emitted because we wind up happening to normalize a `::Diverges: Sized` goal which as a side effect results in erroring about the diverging alias. -Const aliases differ from type aliases a bit here; well formedness of const aliases requires that they can be successfully evaluated (via [`ConstEvaluatable`][const_evaluatable] goals). This means that simply checking well formedness of const arguments is sufficient to error if they would fail to evaluate. It is somewhat unclear whether it would make sense to adopt this for type aliases too or if const aliases should stop requiring this for well formedness[^2]. +Const aliases differ from type aliases a bit here; well formedness of const aliases requires that they can be successfully evaluated (via [`ConstEvaluatable`][const_evaluatable] goals). This means that simply checking well formedness of const arguments is sufficient to error if they would fail to evaluate. It is somewhat unclear whether it would make sense to adopt this for type aliases too or if const aliases should stop requiring this for well formedness[^5]. + +[^1]: In the new solver this is done implicitly + +[^2]: There is a subtle difference in how ambiguous aliases in binders are handled between old and new solver. In the old solver we fail to error on some ambiguous aliases inside of higher ranked types whereas the new solver correctly errors. + +[^3]: Ambiguous aliases inside of binders cannot be normalized to inference variables, this will be covered more later. -[^1]: As checking aliases are non-diverging cannot be done until they are fully concrete, this would either imply that we cant check aliases are well formed before codegen/const-evaluation or that aliases would go from being well-formed to not well-formed after monomorphization. +[^4]: As checking aliases are non-diverging cannot be done until they are fully concrete, this would either imply that we cant check aliases are well formed before codegen/const-evaluation or that aliases would go from being well-formed to not well-formed after monomorphization. -[^2]: Const aliases certainly wouldn't be *less* sound than type aliases if we stopped doing this +[^5]: Const aliases certainly wouldn't be *less* sound than type aliases if we stopped doing this [const_evaluatable]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ClauseKind.html#variant.ConstEvaluatable \ No newline at end of file From 1b2f1c30d9d3a9056ef2bba2903f11c0b90c8338 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 29 Apr 2025 23:39:06 +0200 Subject: [PATCH 233/447] for a more friendly output Also, these are normal Rust things (crates/packages), so remove the word *normal*. --- src/compiler-src.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/compiler-src.md b/src/compiler-src.md index 0d3cbebb4..00aa96226 100644 --- a/src/compiler-src.md +++ b/src/compiler-src.md @@ -86,8 +86,12 @@ something like this: [`Span`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html [main]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/fn.main.html -You can see the exact dependencies by reading the [`Cargo.toml`] for the various -crates, just like a normal Rust crate. +You can see the exact dependencies by running `cargo tree`, +just like you would for any other Rust package: + +```console +cargo tree --package rustc_driver +``` One final thing: [`src/llvm-project`] is a submodule for our fork of LLVM. During bootstrapping, LLVM is built and the [`compiler/rustc_llvm`] crate From d41f1f421960fc31878ab83b755064ab643b4643 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 5 Apr 2025 19:19:56 +0300 Subject: [PATCH 234/447] compiletest: Make diagnostic kind mandatory on line annotations --- src/tests/ui.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index 6232c8bcc..b31c861c9 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -372,9 +372,9 @@ E.g. use `//@ dont-require-annotations: NOTE` to annotate notes selectively. Avoid using this directive for `ERROR`s and `WARN`ings, unless there's a serious reason, like target-dependent compiler output. -Missing diagnostic kinds (`//~ message`) are currently accepted, but are being phased away. -They will match any compiler output kind, but will not force exhaustive annotations for that kind. -Prefer explicit kind and `//@ dont-require-annotations` to achieve the same effect. +Some diagnostics are never required to be line-annotated, regardless of their kind or directives, +for example secondary lines of multiline diagnostics, +or ubiquitous diagnostics like `aborting due to N previous errors`. UI tests use the `-A unused` flag by default to ignore all unused warnings, as unused warnings are usually not the focus of a test. However, simple code From 9c4b43357581b1f1af6f0d48ef0db70d10363349 Mon Sep 17 00:00:00 2001 From: "Martin Ombura Jr." <8682597+martinomburajr@users.noreply.github.com> Date: Thu, 1 May 2025 04:01:42 +0000 Subject: [PATCH 235/447] adds 'with' to help clarify how to build a new compiler --- src/building/bootstrapping/intro.md | 2 +- src/building/bootstrapping/what-bootstrapping-does.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/building/bootstrapping/intro.md b/src/building/bootstrapping/intro.md index f72918c83..bb7dd8dd4 100644 --- a/src/building/bootstrapping/intro.md +++ b/src/building/bootstrapping/intro.md @@ -7,7 +7,7 @@ of the same compiler. This raises a chicken-and-egg paradox: where did the first compiler come from? It must have been written in a different language. In Rust's case it was [written in OCaml][ocaml-compiler]. However it was abandoned long ago and the -only way to build a modern version of rustc is a slightly less modern +only way to build a modern version of rustc is with a slightly less modern version. This is exactly how `x.py` works: it downloads the current beta release of diff --git a/src/building/bootstrapping/what-bootstrapping-does.md b/src/building/bootstrapping/what-bootstrapping-does.md index ffcfe2596..ac1fa51e3 100644 --- a/src/building/bootstrapping/what-bootstrapping-does.md +++ b/src/building/bootstrapping/what-bootstrapping-does.md @@ -9,7 +9,7 @@ the same compiler. This raises a chicken-and-egg paradox: where did the first compiler come from? It must have been written in a different language. In Rust's case it was [written in OCaml][ocaml-compiler]. However it was abandoned long ago and the -only way to build a modern version of `rustc` is a slightly less modern version. +only way to build a modern version of `rustc` is with a slightly less modern version. This is exactly how [`./x.py`] works: it downloads the current beta release of `rustc`, then uses it to compile the new compiler. From 8fe288a2f4c9a0adda55be49f29d36e2a1b45868 Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Thu, 1 May 2025 04:05:40 +0000 Subject: [PATCH 236/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 67fa25f22..66b4fe2bf 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -deb947971c8748f5c6203548ce4af9022f21eaf0 +0c33fe2c3d3eecadd17a84b110bb067288a64f1c From 7f939765c4c46d7cef71b051e9aa0683a91e519d Mon Sep 17 00:00:00 2001 From: "Martin Ombura Jr." <8682597+martinomburajr@users.noreply.github.com> Date: Thu, 1 May 2025 04:07:27 +0000 Subject: [PATCH 237/447] adds commas --- src/building/bootstrapping/intro.md | 2 +- src/building/bootstrapping/what-bootstrapping-does.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/building/bootstrapping/intro.md b/src/building/bootstrapping/intro.md index bb7dd8dd4..7f5309782 100644 --- a/src/building/bootstrapping/intro.md +++ b/src/building/bootstrapping/intro.md @@ -6,7 +6,7 @@ of the same compiler. This raises a chicken-and-egg paradox: where did the first compiler come from? It must have been written in a different language. In Rust's case it was -[written in OCaml][ocaml-compiler]. However it was abandoned long ago and the +[written in OCaml][ocaml-compiler]. However, it was abandoned long ago, and the only way to build a modern version of rustc is with a slightly less modern version. diff --git a/src/building/bootstrapping/what-bootstrapping-does.md b/src/building/bootstrapping/what-bootstrapping-does.md index ac1fa51e3..a2930b3e4 100644 --- a/src/building/bootstrapping/what-bootstrapping-does.md +++ b/src/building/bootstrapping/what-bootstrapping-does.md @@ -8,7 +8,7 @@ the same compiler. This raises a chicken-and-egg paradox: where did the first compiler come from? It must have been written in a different language. In Rust's case it was -[written in OCaml][ocaml-compiler]. However it was abandoned long ago and the +[written in OCaml][ocaml-compiler]. However, it was abandoned long ago, and the only way to build a modern version of `rustc` is with a slightly less modern version. This is exactly how [`./x.py`] works: it downloads the current beta release of From 8e8bc1d9993ba1aef4cc5ce2a6ac781686b54e33 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 1 May 2025 07:38:29 +0200 Subject: [PATCH 238/447] add rdg push git config entry for git protocol pushers --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 081588017..0425c15f8 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,16 @@ Older versions of `josh-proxy` may not round trip commits losslessly so it is im 3) Push the branch to your fork and create a PR into `rustc-dev-guide` ### Push changes from this repository into `rust-lang/rust` + +NOTE: If you use Git protocol to push to your fork of `rust-lang/rust`, +ensure that you have this entry in your Git config, +else the 2 steps that follow would prompt for a username and password: + +``` +[url "git@github.com:"] +insteadOf = "https://github.com/" +``` + 1) Run the push command to create a branch named `` in a `rustc` fork under the `` account ``` cargo run --manifest-path josh-sync/Cargo.toml rustc-push From 0d29d41413fa435566b5c2d365b29c2a5871e1ec Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 2 May 2025 17:56:07 +0300 Subject: [PATCH 239/447] compiletest: Support matching on non-json lines in compiler output and migrate most of remaining `error-pattern`s to it. --- src/tests/ui.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index b31c861c9..721d20b65 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -344,8 +344,7 @@ For checking runtime output, `//@ check-run-results` may be preferable. Only use `error-pattern` if none of the above works. -Line annotations `//~` are still checked in tests using `error-pattern`. -In exceptional cases, use `//@ compile-flags: --error-format=human` to opt out of these checks. +Line annotations `//~` and `error-pattern` are compatible and can be used in the same test. ### Diagnostic kinds (error levels) @@ -356,9 +355,12 @@ The diagnostic kinds that you can have are: - `NOTE` - `HELP` - `SUGGESTION` +- `RAW` The `SUGGESTION` kind is used for specifying what the expected replacement text should be for a diagnostic suggestion. +The `RAW` kind can be used for matching on lines from non-structured output sometimes emitted +by the compiler instead of or in addition to structured json. `ERROR` and `WARN` kinds are required to be exhaustively covered by line annotations `//~` by default. From 6813f5f9b6644931bd17d4c61d41e10d9b7cbe1d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 6 May 2025 14:56:51 +0200 Subject: [PATCH 240/447] avoid duplicating commands The 2 commands do the same thing. Also, follow style used elsewhere in the guide. --- src/tests/intro.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/tests/intro.md b/src/tests/intro.md index 7bf30b106..c55d60f4a 100644 --- a/src/tests/intro.md +++ b/src/tests/intro.md @@ -102,11 +102,12 @@ by passing a path to a book to `./x test`. ### Documentation link checker -Links across all documentation is validated with a link checker tool. +Links across all documentation is validated with a link checker tool, +and it can be invoked so: -> Example: `./x test src/tools/linkchecker` - -> Example: `./x test linkchecker` +```console +./x test linkchecker +``` This requires building all of the documentation, which might take a while. From acd63b2a5225f98145a88383db0435b27f770cc7 Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Thu, 8 May 2025 07:16:18 +0000 Subject: [PATCH 241/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 66b4fe2bf..ec1602280 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -0c33fe2c3d3eecadd17a84b110bb067288a64f1c +7e552b46af72df390ed233b58a7f51650515b2a8 From 0e630fb60d8a86c32117330ae634bdc4bf387775 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Thu, 8 May 2025 11:13:50 +0300 Subject: [PATCH 242/447] Fix minor typo in serialization.md --- src/serialization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/serialization.md b/src/serialization.md index 670a37ffb..47667061e 100644 --- a/src/serialization.md +++ b/src/serialization.md @@ -169,7 +169,7 @@ The `LazyArray<[T]>` and `LazyTable` types provide some functionality over than the one being read. **note**: `LazyValue` does not cache its value after being deserialized the -first time. Instead the query system its self is the main way of caching these +first time. Instead the query system itself is the main way of caching these results. [`LazyArray`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/struct.LazyValue.html From 7434026e134cfb40f5483a7101fe8b2acafd9533 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Thu, 8 May 2025 14:03:14 +0300 Subject: [PATCH 243/447] Remark test naming exception --- src/tests/best-practices.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tests/best-practices.md b/src/tests/best-practices.md index 2bdc7f3a2..be00207e3 100644 --- a/src/tests/best-practices.md +++ b/src/tests/best-practices.md @@ -70,6 +70,11 @@ related tests. > //! > //! Regression test for . > ``` +> +> One exception to this rule is [crashes tests]: there it is canonical that +> tests are named only after issue numbers because its purpose is to track +> snippets from which issues no longer ICE/crash, and they would either be +> removed or converted into proper ui/other tests in the fix PRs. ## Test organization @@ -194,3 +199,4 @@ See [LLVM FileCheck guide][FileCheck] for details. [compiletest directives]: ./directives.md [`run-make`]: ./compiletest.md#run-make-tests [FileCheck]: https://llvm.org/docs/CommandGuide/FileCheck.html +[crashes tests]: ./compiletest.md#crashes-tests From e1c08547a19bc50b4d9542aab4e4fb2139052249 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Thu, 8 May 2025 16:36:53 +0300 Subject: [PATCH 244/447] Fix minor typo in installation.md --- src/autodiff/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/autodiff/installation.md b/src/autodiff/installation.md index f3c113955..971d07bfa 100644 --- a/src/autodiff/installation.md +++ b/src/autodiff/installation.md @@ -1,6 +1,6 @@ # Installation -In the near future, `std::autodiff` should become available in nightly builds for users. As a contribute however, you will still need to build rustc from source. Please be aware that the msvc target is not supported at the moment, all other tier 1 targets should work. Please open an issue if you encounter any problems on a supported tier 1 target, or if you succesfully build this project on a tier2/tier3 target. +In the near future, `std::autodiff` should become available in nightly builds for users. As a contributor however, you will still need to build rustc from source. Please be aware that the msvc target is not supported at the moment, all other tier 1 targets should work. Please open an issue if you encounter any problems on a supported tier 1 target, or if you succesfully build this project on a tier2/tier3 target. ## Build instructions From ff2b6fd0cb43c123e43f68673d2a82bbe6671595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 8 May 2025 16:00:48 +0200 Subject: [PATCH 245/447] Mention fast try builds in the rustc-dev-guide --- src/tests/ci.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/tests/ci.md b/src/tests/ci.md index c04f296ba..825be11c8 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -135,12 +135,16 @@ There are several use-cases for try builds: - Run a specific CI job (e.g. Windows tests) on a PR, to quickly test if it passes the test suite executed by that job. -You can select which CI jobs will -be executed in the try build by adding lines containing `try-job: -` to the PR description. All such specified jobs will be executed -in the try build once the `@bors try` command is used on the PR. If no try -jobs are specified in this way, the jobs defined in the `try` section of -[`jobs.yml`] will be executed by default. +By default, if you send a comment with `@bors try`, the jobs defined in the `try` section of +[`jobs.yml`] will be executed. We call this mode a "fast try build". Such a try build +will not execute any tests, and it will allow compilation warnings. It is useful when you want to +get an optimized toolchain as fast as possible, for a crater run or performance benchmarks, +even if it might not be working fully correctly. + +If you want to run a custom CI job in a try build and make sure that it passes all tests and does +not produce any compilation warnings, you can select CI jobs to be executed by adding lines +containing `try-job: ` to the PR description. All such specified jobs will be executed +in the try build once the `@bors try` command is used on the PR. Each pattern can either be an exact name of a job or a glob pattern that matches multiple jobs, for example `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. When using From b82a852640e3514b3e64a141d56198b4fc92e62b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 9 May 2025 10:36:07 +0200 Subject: [PATCH 246/447] Remove mono item collection strategy override from -Zprint-mono-items Previously `-Zprint-mono-items` would override the mono item collection strategy. When debugging one doesn't want to change the behaviour, so this was counter productive. Additionally, the produced behaviour was artificial and might never arise without using the option in the first place (`-Zprint-mono-items=eager` without `-Clink-dead-code`). Finally, the option was incorrectly marked as `UNTRACKED`. Resolve those issues, by turning `-Zprint-mono-items` into a boolean flag that prints results of mono item collection without changing the behaviour of mono item collection. For codegen-units test incorporate `-Zprint-mono-items` flag directly into compiletest tool. Test changes are mechanical. `-Zprint-mono-items=lazy` was removed without additional changes, and `-Zprint-mono-items=eager` was turned into `-Clink-dead-code`. Linking dead code disables internalization, so tests have been updated accordingly. --- src/tests/compiletest.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index 2c35381ea..0ba078f0b 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -325,12 +325,8 @@ The tests in [`tests/codegen-units`] test the [monomorphization](../backend/monomorph.md) collector and CGU partitioning. These tests work by running `rustc` with a flag to print the result of the -monomorphization collection pass, and then special annotations in the file are -used to compare against that. - -Each test should be annotated with the `//@ -compile-flags:-Zprint-mono-items=VAL` directive with the appropriate `VAL` to -instruct `rustc` to print the monomorphization information. +monomorphization collection pass, i.e., `-Zprint-mono-items`, and then special +annotations in the file are used to compare against that. Then, the test should be annotated with comments of the form `//~ MONO_ITEM name` where `name` is the monomorphized string printed by rustc like `fn Date: Thu, 8 May 2025 14:39:30 +0300 Subject: [PATCH 247/447] Fix minor typo in rustdoc-internals.md --- src/rustdoc-internals.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rustdoc-internals.md b/src/rustdoc-internals.md index 7f1c83e00..80421b85b 100644 --- a/src/rustdoc-internals.md +++ b/src/rustdoc-internals.md @@ -55,8 +55,8 @@ The first step in [`clean::utils::krate`][ck1] is to invoke * inlining public `use` exports of private items, or showing a "Reexport" line in the module page * inlining items with `#[doc(hidden)]` if the base item is hidden but the - * showing `#[macro_export]`-ed macros at the crate root, regardless of where - they're defined reexport is not + * showing `#[macro_export]`-ed macros at the crate root, regardless of whether + they're defined as a reexport or not After this step, `clean::krate` invokes [`clean_doc_module`], which actually converts the `HIR` items to the cleaned [`AST`][ast]. This is also the step where cross- From fde7c94e0decda71edd3aaa0f7be4666159b825b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 12:21:56 +0200 Subject: [PATCH 248/447] link to chapter referred to This made it look the the topic was covered in the chapter just before the current one. --- src/ty-fold.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ty-fold.md b/src/ty-fold.md index d4d0952fc..ecb961cf1 100644 --- a/src/ty-fold.md +++ b/src/ty-fold.md @@ -1,6 +1,6 @@ # `TypeFoldable` and `TypeFolder` -In the previous chapter we discussed instantiating binders. This must involves looking at everything inside of a `Early/Binder` +In [a previous chapter], we discussed instantiating binders. This must involves looking at everything inside of a `Early/Binder` to find any usages of the bound vars in order to replace them. Binders can wrap an arbitrary rust type `T` not just a `Ty` so how do we implement the `instantiate` methods on the `Early/Binder` types. @@ -102,3 +102,4 @@ calls [ty_for_param](https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L552-L587) and all that does is index into the list of substitutions with the index of the `Param`. +[a previous chapter]: ty_module/instantiating_binders.md From ac44773f069802e083d365f862627224f4d95f6d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 12:32:59 +0200 Subject: [PATCH 249/447] use the right case --- src/ty-fold.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ty-fold.md b/src/ty-fold.md index ecb961cf1..da9564d40 100644 --- a/src/ty-fold.md +++ b/src/ty-fold.md @@ -1,7 +1,7 @@ # `TypeFoldable` and `TypeFolder` -In [a previous chapter], we discussed instantiating binders. This must involves looking at everything inside of a `Early/Binder` -to find any usages of the bound vars in order to replace them. Binders can wrap an arbitrary rust type `T` not just a `Ty` so +In [a previous chapter], we discussed instantiating binders. This involves looking at everything inside of a `Early/Binder` +to find any usages of the bound vars in order to replace them. Binders can wrap an arbitrary Rust type `T` not just a `Ty` so how do we implement the `instantiate` methods on the `Early/Binder` types. The answer is a couple of traits: @@ -20,7 +20,7 @@ that takes a type as input and returns a new type as a result. `TypeFoldable` in `TypeFolder` `fold_foo` methods on itself, giving the `TypeFolder` access to its contents (the types, regions, etc that are contained within). -You can think of it with this analogy to the iterator combinators we have come to love in rust: +You can think of it with this analogy to the iterator combinators we have come to love in Rust: ```rust,ignore vec.iter().map(|e1| foo(e2)).collect() From 1d1a050dcdf0cd18e5cf2a69b1776fa1f298856a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 12:33:45 +0200 Subject: [PATCH 250/447] make more clear what is meant --- src/ty-fold.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ty-fold.md b/src/ty-fold.md index da9564d40..dcc565b31 100644 --- a/src/ty-fold.md +++ b/src/ty-fold.md @@ -1,6 +1,6 @@ # `TypeFoldable` and `TypeFolder` -In [a previous chapter], we discussed instantiating binders. This involves looking at everything inside of a `Early/Binder` +In [a previous chapter], we discussed instantiating binders. This involves looking at everything inside of a `Early(Binder)` to find any usages of the bound vars in order to replace them. Binders can wrap an arbitrary Rust type `T` not just a `Ty` so how do we implement the `instantiate` methods on the `Early/Binder` types. From ff1e1d1bcc5311b546e8c3e8e96e3dbd872a4ca5 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 12:34:43 +0200 Subject: [PATCH 251/447] make more readable --- src/ty-fold.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ty-fold.md b/src/ty-fold.md index dcc565b31..f659612e8 100644 --- a/src/ty-fold.md +++ b/src/ty-fold.md @@ -1,7 +1,7 @@ # `TypeFoldable` and `TypeFolder` In [a previous chapter], we discussed instantiating binders. This involves looking at everything inside of a `Early(Binder)` -to find any usages of the bound vars in order to replace them. Binders can wrap an arbitrary Rust type `T` not just a `Ty` so +to find any usages of the bound vars in order to replace them. Binders can wrap an arbitrary Rust type `T`, not just a `Ty`. So, how do we implement the `instantiate` methods on the `Early/Binder` types. The answer is a couple of traits: From 39c758c3af952a58266088beff6777255bb00219 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 12:35:40 +0200 Subject: [PATCH 252/447] sembr --- src/ty-fold.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ty-fold.md b/src/ty-fold.md index f659612e8..d413e5038 100644 --- a/src/ty-fold.md +++ b/src/ty-fold.md @@ -1,8 +1,10 @@ # `TypeFoldable` and `TypeFolder` -In [a previous chapter], we discussed instantiating binders. This involves looking at everything inside of a `Early(Binder)` -to find any usages of the bound vars in order to replace them. Binders can wrap an arbitrary Rust type `T`, not just a `Ty`. So, -how do we implement the `instantiate` methods on the `Early/Binder` types. +In [a previous chapter], we discussed instantiating binders. +This involves looking at everything inside of a `Early(Binder)` +to find any usages of the bound vars in order to replace them. +Binders can wrap an arbitrary Rust type `T`, not just a `Ty`. +So, how do we implement the `instantiate` methods on the `Early/Binder` types. The answer is a couple of traits: [`TypeFoldable`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFoldable.html) From e2171b97e77823b2bd9395a86e7e360f81f05623 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 12:35:50 +0200 Subject: [PATCH 253/447] is a question --- src/ty-fold.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ty-fold.md b/src/ty-fold.md index d413e5038..a1a9dcf77 100644 --- a/src/ty-fold.md +++ b/src/ty-fold.md @@ -4,7 +4,7 @@ In [a previous chapter], we discussed instantiating binders. This involves looking at everything inside of a `Early(Binder)` to find any usages of the bound vars in order to replace them. Binders can wrap an arbitrary Rust type `T`, not just a `Ty`. -So, how do we implement the `instantiate` methods on the `Early/Binder` types. +So, how do we implement the `instantiate` methods on the `Early/Binder` types? The answer is a couple of traits: [`TypeFoldable`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFoldable.html) From 6b12439a07ac80e2552b83d7dd279f40ff8563ec Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 12:43:59 +0200 Subject: [PATCH 254/447] fix broken links --- src/ty-fold.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ty-fold.md b/src/ty-fold.md index a1a9dcf77..6de9b96a1 100644 --- a/src/ty-fold.md +++ b/src/ty-fold.md @@ -7,9 +7,9 @@ Binders can wrap an arbitrary Rust type `T`, not just a `Ty`. So, how do we implement the `instantiate` methods on the `Early/Binder` types? The answer is a couple of traits: -[`TypeFoldable`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFoldable.html) +[`TypeFoldable`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFoldable.html) and -[`TypeFolder`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFolder.html). +[`TypeFolder`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFolder.html). - `TypeFoldable` is implemented by types that embed type information. It allows you to recursively process the contents of the `TypeFoldable` and do stuff to them. @@ -17,7 +17,7 @@ and `TypeFoldable`. For example, the `TypeFolder` trait has a method -[`fold_ty`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFolder.html#method.fold_ty) +[`fold_ty`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFolder.html#method.fold_ty) that takes a type as input and returns a new type as a result. `TypeFoldable` invokes the `TypeFolder` `fold_foo` methods on itself, giving the `TypeFolder` access to its contents (the types, regions, etc that are contained within). From 1dff715902c8d1f9dbb66fc3c66c8e7aed09652e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 12:56:03 +0200 Subject: [PATCH 255/447] reduce clutter when reading source --- src/ty-fold.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/ty-fold.md b/src/ty-fold.md index 6de9b96a1..c43523cac 100644 --- a/src/ty-fold.md +++ b/src/ty-fold.md @@ -7,9 +7,9 @@ Binders can wrap an arbitrary Rust type `T`, not just a `Ty`. So, how do we implement the `instantiate` methods on the `Early/Binder` types? The answer is a couple of traits: -[`TypeFoldable`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFoldable.html) +[`TypeFoldable`] and -[`TypeFolder`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFolder.html). +[`TypeFolder`]. - `TypeFoldable` is implemented by types that embed type information. It allows you to recursively process the contents of the `TypeFoldable` and do stuff to them. @@ -17,7 +17,7 @@ and `TypeFoldable`. For example, the `TypeFolder` trait has a method -[`fold_ty`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFolder.html#method.fold_ty) +[`fold_ty`] that takes a type as input and returns a new type as a result. `TypeFoldable` invokes the `TypeFolder` `fold_foo` methods on itself, giving the `TypeFolder` access to its contents (the types, regions, etc that are contained within). @@ -36,7 +36,7 @@ So to reiterate: - `TypeFoldable` is a trait that is implemented by things that embed types. In the case of `subst`, we can see that it is implemented as a `TypeFolder`: -[`ArgFolder`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/binder/struct.ArgFolder.html). +[`ArgFolder`]. Looking at its implementation, we see where the actual substitutions are happening. However, you might also notice that the implementation calls this `super_fold_with` method. What is @@ -91,17 +91,25 @@ things. We only want to do something when we reach a type. That means there may implementations. Such implementations of `TypeFoldable` tend to be pretty tedious to write by hand. For this reason, there is a `derive` macro that allows you to `#![derive(TypeFoldable)]`. It is defined -[here](https://github.com/rust-lang/rust/blob/master/compiler/rustc_macros/src/type_foldable.rs). +[here]. **`subst`** In the case of substitutions the [actual -folder](https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L440-L451) +folder] is going to be doing the indexing we’ve already mentioned. There we define a `Folder` and call `fold_with` on the `TypeFoldable` to process yourself. Then -[fold_ty](https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L512-L536) +[fold_ty] the method that process each type it looks for a `ty::Param` and for those it replaces it for something from the list of substitutions, otherwise recursively process the type. To replace it, calls -[ty_for_param](https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L552-L587) +[ty_for_param] and all that does is index into the list of substitutions with the index of the `Param`. [a previous chapter]: ty_module/instantiating_binders.md +[`TypeFoldable`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFoldable.html +[`TypeFolder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFolder.html +[`fold_ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFolder.html#method.fold_ty +[`ArgFolder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/binder/struct.ArgFolder.html +[here]: https://github.com/rust-lang/rust/blob/master/compiler/rustc_macros/src/type_foldable.rs +[actual folder]: https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L440-L451 +[fold_ty]: https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L512-L536 +[ty_for_param]: https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L552-L587 From 919836d9f20e4c510ea505138d317965aa3ba32d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 12:59:37 +0200 Subject: [PATCH 256/447] sembr --- src/ty-fold.md | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/ty-fold.md b/src/ty-fold.md index c43523cac..8e5fe6ccb 100644 --- a/src/ty-fold.md +++ b/src/ty-fold.md @@ -16,11 +16,10 @@ and - `TypeFolder` defines what you want to do with the types you encounter while processing the `TypeFoldable`. -For example, the `TypeFolder` trait has a method -[`fold_ty`] -that takes a type as input and returns a new type as a result. `TypeFoldable` invokes the -`TypeFolder` `fold_foo` methods on itself, giving the `TypeFolder` access to its contents (the -types, regions, etc that are contained within). +For example, the `TypeFolder` trait has a method [`fold_ty`] +that takes a type as input and returns a new type as a result. +`TypeFoldable` invokes the `TypeFolder` `fold_foo` methods on itself, +giving the `TypeFolder` access to its contents (the types, regions, etc that are contained within). You can think of it with this analogy to the iterator combinators we have come to love in Rust: @@ -35,8 +34,7 @@ So to reiterate: - `TypeFolder` is a trait that defines a “map” operation. - `TypeFoldable` is a trait that is implemented by things that embed types. -In the case of `subst`, we can see that it is implemented as a `TypeFolder`: -[`ArgFolder`]. +In the case of `subst`, we can see that it is implemented as a `TypeFolder`: [`ArgFolder`]. Looking at its implementation, we see where the actual substitutions are happening. However, you might also notice that the implementation calls this `super_fold_with` method. What is @@ -90,18 +88,14 @@ things. We only want to do something when we reach a type. That means there may `TypeFoldable` types whose implementations basically just forward to their fields’ `TypeFoldable` implementations. Such implementations of `TypeFoldable` tend to be pretty tedious to write by hand. For this reason, there is a `derive` macro that allows you to `#![derive(TypeFoldable)]`. It is -defined -[here]. - -**`subst`** In the case of substitutions the [actual -folder] -is going to be doing the indexing we’ve already mentioned. There we define a `Folder` and call -`fold_with` on the `TypeFoldable` to process yourself. Then -[fold_ty] -the method that process each type it looks for a `ty::Param` and for those it replaces it for -something from the list of substitutions, otherwise recursively process the type. To replace it, -calls -[ty_for_param] +defined [here]. + +**`subst`** In the case of substitutions the [actual folder] +is going to be doing the indexing we’ve already mentioned. +There we define a `Folder` and call `fold_with` on the `TypeFoldable` to process yourself. +Then [fold_ty] the method that process each type it looks for a `ty::Param` and for those +it replaces it for something from the list of substitutions, otherwise recursively process the type. +To replace it, calls [ty_for_param] and all that does is index into the list of substitutions with the index of the `Param`. [a previous chapter]: ty_module/instantiating_binders.md From 7f333c0cd21a469bdc9077231aaffc11a9e56d4c Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 13:07:34 +0200 Subject: [PATCH 257/447] last updated a year ago --- src/ty-fold.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ty-fold.md b/src/ty-fold.md index 8e5fe6ccb..23253022f 100644 --- a/src/ty-fold.md +++ b/src/ty-fold.md @@ -1,3 +1,4 @@ + # `TypeFoldable` and `TypeFolder` In [a previous chapter], we discussed instantiating binders. From 7fa4f19ab430f1a2ae5e5795ea0395dcca19abf9 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 13:14:38 +0200 Subject: [PATCH 258/447] add missing word --- ci/date-check/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/date-check/src/main.rs b/ci/date-check/src/main.rs index 9af69dbbf..0a32f4e9b 100644 --- a/ci/date-check/src/main.rs +++ b/ci/date-check/src/main.rs @@ -114,7 +114,7 @@ fn filter_dates( fn main() { let mut args = env::args(); if args.len() == 1 { - eprintln!("error: expected root Markdown directory as CLI argument"); + eprintln!("error: expected root of Markdown directory as CLI argument"); process::exit(1); } let root_dir = args.nth(1).unwrap(); From f99df9199fc617b622d0c1f9578bd456f13fa244 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 13:15:12 +0200 Subject: [PATCH 259/447] no point versioning these They are internal tools. --- ci/date-check/Cargo.lock | 207 ++++++++++++++++++++------------------- ci/date-check/Cargo.toml | 1 - josh-sync/Cargo.lock | 2 +- josh-sync/Cargo.toml | 1 - 4 files changed, 108 insertions(+), 103 deletions(-) diff --git a/ci/date-check/Cargo.lock b/ci/date-check/Cargo.lock index 6326b2daf..710754733 100644 --- a/ci/date-check/Cargo.lock +++ b/ci/date-check/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -28,21 +28,24 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "cc" -version = "1.0.106" +version = "1.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066fce287b1d4eafef758e89e09d724a24808a9196fe9756b8ca90e86d0719a2" +checksum = "32db95edf998450acc7881c932f94cd9b05c87b4b2599e8bab064753da4acfd1" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -52,27 +55,27 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets", + "windows-link", ] [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "date-check" -version = "0.1.0" +version = "0.0.0" dependencies = [ "chrono", "glob", @@ -81,20 +84,21 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core", ] @@ -110,24 +114,25 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] name = "libc" -version = "0.2.155" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "memchr" @@ -146,33 +151,33 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] name = "regex" -version = "1.10.5" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -182,9 +187,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -193,15 +198,27 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "syn" -version = "2.0.70" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -210,29 +227,30 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn", @@ -241,9 +259,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -251,9 +269,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -264,79 +282,68 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "windows-core" -version = "0.52.0" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ - "windows-targets", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] -name = "windows-targets" -version = "0.52.6" +name = "windows-implement" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" +name = "windows-interface" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" +name = "windows-link" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" +name = "windows-result" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] [[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" +name = "windows-strings" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +dependencies = [ + "windows-link", +] diff --git a/ci/date-check/Cargo.toml b/ci/date-check/Cargo.toml index 472529511..9a28087ac 100644 --- a/ci/date-check/Cargo.toml +++ b/ci/date-check/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "date-check" -version = "0.1.0" authors = ["Noah Lev "] edition = "2021" diff --git a/josh-sync/Cargo.lock b/josh-sync/Cargo.lock index 844518628..a8183a740 100644 --- a/josh-sync/Cargo.lock +++ b/josh-sync/Cargo.lock @@ -161,7 +161,7 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "josh-sync" -version = "0.1.0" +version = "0.0.0" dependencies = [ "anyhow", "clap", diff --git a/josh-sync/Cargo.toml b/josh-sync/Cargo.toml index 81d0d1ebd..7cfa4a14c 100644 --- a/josh-sync/Cargo.toml +++ b/josh-sync/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "josh-sync" -version = "0.1.0" edition = "2021" [dependencies] From 9f710fd775c152534599b11575998db06cb5bdc2 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 13:29:41 +0200 Subject: [PATCH 260/447] bump edition --- ci/date-check/Cargo.toml | 2 +- josh-sync/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/date-check/Cargo.toml b/ci/date-check/Cargo.toml index 9a28087ac..6101a4bcf 100644 --- a/ci/date-check/Cargo.toml +++ b/ci/date-check/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "date-check" authors = ["Noah Lev "] -edition = "2021" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/josh-sync/Cargo.toml b/josh-sync/Cargo.toml index 7cfa4a14c..1f8bf2a00 100644 --- a/josh-sync/Cargo.toml +++ b/josh-sync/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "josh-sync" -edition = "2021" +edition = "2024" [dependencies] anyhow = "1.0.95" From 5e2a659b1d30cd0c546066c01fdb33ddca97b865 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 13:35:33 +0200 Subject: [PATCH 261/447] "cargo fmt" --- josh-sync/src/main.rs | 6 ++---- josh-sync/src/sync.rs | 40 ++++++++++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/josh-sync/src/main.rs b/josh-sync/src/main.rs index 175f016f7..aeedee5be 100644 --- a/josh-sync/src/main.rs +++ b/josh-sync/src/main.rs @@ -1,4 +1,5 @@ use clap::Parser; + use crate::sync::{GitSync, RustcPullError}; mod sync; @@ -11,10 +12,7 @@ enum Args { /// Push changes from `rustc-dev-guide` to the given `branch` of a `rustc` fork under the given /// GitHub `username`. /// The pushed branch should then be merged into the `rustc` repository. - RustcPush { - branch: String, - github_username: String - } + RustcPush { branch: String, github_username: String }, } fn main() -> anyhow::Result<()> { diff --git a/josh-sync/src/sync.rs b/josh-sync/src/sync.rs index 41d96397f..ed38d1403 100644 --- a/josh-sync/src/sync.rs +++ b/josh-sync/src/sync.rs @@ -1,10 +1,11 @@ +use std::io::Write; use std::ops::Not; use std::path::PathBuf; -use std::{env, net, process}; -use std::io::Write; use std::time::Duration; -use anyhow::{anyhow, bail, Context}; -use xshell::{cmd, Shell}; +use std::{env, net, process}; + +use anyhow::{Context, anyhow, bail}; +use xshell::{Shell, cmd}; /// Used for rustc syncs. const JOSH_FILTER: &str = ":/src/doc/rustc-dev-guide"; @@ -15,10 +16,13 @@ pub enum RustcPullError { /// No changes are available to be pulled. NothingToPull, /// A rustc-pull has failed, probably a git operation error has occurred. - PullFailed(anyhow::Error) + PullFailed(anyhow::Error), } -impl From for RustcPullError where E: Into { +impl From for RustcPullError +where + E: Into, +{ fn from(error: E) -> Self { Self::PullFailed(error.into()) } @@ -32,9 +36,7 @@ pub struct GitSync { /// (https://github.com/rust-lang/miri/blob/6a68a79f38064c3bc30617cca4bdbfb2c336b140/miri-script/src/commands.rs#L236). impl GitSync { pub fn from_current_dir() -> anyhow::Result { - Ok(Self { - dir: std::env::current_dir()? - }) + Ok(Self { dir: std::env::current_dir()? }) } pub fn rustc_pull(&self, commit: Option) -> Result<(), RustcPullError> { @@ -51,7 +53,10 @@ impl GitSync { })?; // Make sure the repo is clean. if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() { - return Err(anyhow::anyhow!("working directory must be clean before performing rustc pull").into()); + return Err(anyhow::anyhow!( + "working directory must be clean before performing rustc pull" + ) + .into()); } // Make sure josh is running. let josh = Self::start_josh()?; @@ -94,7 +99,8 @@ impl GitSync { }; let num_roots_before = num_roots()?; - let sha = cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout; + let sha = + cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout; // Merge the fetched commit. const MERGE_COMMIT_MESSAGE: &str = "Merge from rustc"; @@ -102,18 +108,24 @@ impl GitSync { .run() .context("FAILED to merge new commits, something went wrong")?; - let current_sha = cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout; + let current_sha = + cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout; if current_sha == sha { cmd!(sh, "git reset --hard HEAD^") .run() .expect("FAILED to clean up after creating the preparation commit"); - eprintln!("No merge was performed, no changes to pull were found. Rolled back the preparation commit."); + eprintln!( + "No merge was performed, no changes to pull were found. Rolled back the preparation commit." + ); return Err(RustcPullError::NothingToPull); } // Check that the number of roots did not increase. if num_roots()? != num_roots_before { - return Err(anyhow::anyhow!("Josh created a new root commit. This is probably not the history you want.").into()); + return Err(anyhow::anyhow!( + "Josh created a new root commit. This is probably not the history you want." + ) + .into()); } drop(josh); From 330cb46b36020ffc80792bef51d8ec4b5cd3fd20 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 13:48:35 +0200 Subject: [PATCH 262/447] we are a collective --- ci/date-check/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/ci/date-check/Cargo.toml b/ci/date-check/Cargo.toml index 6101a4bcf..1ffa13bc0 100644 --- a/ci/date-check/Cargo.toml +++ b/ci/date-check/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "date-check" -authors = ["Noah Lev "] edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From a1603f1859c65ba8685b0b1f769a7853d4479a3b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 10 May 2025 13:48:45 +0200 Subject: [PATCH 263/447] noise --- ci/date-check/Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/ci/date-check/Cargo.toml b/ci/date-check/Cargo.toml index 1ffa13bc0..f49e6d0db 100644 --- a/ci/date-check/Cargo.toml +++ b/ci/date-check/Cargo.toml @@ -2,8 +2,6 @@ name = "date-check" edition = "2024" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] glob = "0.3" regex = "1" From 90d8951b3a5d9bde4201da7071a3e8f003874632 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 10 May 2025 12:42:21 -0700 Subject: [PATCH 264/447] Add an issue template for future-incompatible lints --- src/bug-fix-procedure.md | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/src/bug-fix-procedure.md b/src/bug-fix-procedure.md index 8e6725c54..55436261f 100644 --- a/src/bug-fix-procedure.md +++ b/src/bug-fix-procedure.md @@ -80,41 +80,11 @@ approachable and practical; it may make sense to direct users to an RFC or some other issue for the full details. The issue also serves as a place where users can comment with questions or other concerns. -A template for these breaking-change tracking issues can be found below. An -example of how such an issue should look can be [found +A template for these breaking-change tracking issues can be found +[here][template]. An example of how such an issue should look can be [found here][breaking-change-issue]. -The issue should be tagged with (at least) `B-unstable` and `T-compiler`. - -### Tracking issue template - -This is a template to use for tracking issues: - -``` -This is the **summary issue** for the `YOUR_LINT_NAME_HERE` -future-compatibility warning and other related errors. The goal of -this page is describe why this change was made and how you can fix -code that is affected by it. It also provides a place to ask questions -or register a complaint if you feel the change should not be made. For -more information on the policy around future-compatibility warnings, -see our [breaking change policy guidelines][guidelines]. - -[guidelines]: LINK_TO_THIS_RFC - -#### What is the warning for? - -*Describe the conditions that trigger the warning and how they can be -fixed. Also explain why the change was made.** - -#### When will this warning become a hard error? - -At the beginning of each 6-week release cycle, the Rust compiler team -will review the set of outstanding future compatibility warnings and -nominate some of them for **Final Comment Period**. Toward the end of -the cycle, we will review any comments and make a final determination -whether to convert the warning into a hard error or remove it -entirely. -``` +[template]: https://github.com/rust-lang/rust/issues/new?template=tracking_issue_future.md ### Issuing future compatibility warnings From 8ebe4672cb29988fce7b2a69cc3fc508302f18d9 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 12 May 2025 18:08:15 +1000 Subject: [PATCH 265/447] Remove obsolete reference to `unsized_tuple_coercion` --- src/traits/unsize.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/traits/unsize.md b/src/traits/unsize.md index dd57a1b07..98a445257 100644 --- a/src/traits/unsize.md +++ b/src/traits/unsize.md @@ -32,21 +32,21 @@ Built-in implementations are provided for: ## Structural implementations -There are two implementations of `Unsize` which can be thought of as +There is one implementation of `Unsize` which can be thought of as structural: -* `(A1, A2, .., An): Unsize<(A1, A2, .., U)>` given `An: Unsize`, which - allows the tail field of a tuple to be unsized. This is gated behind the - [`unsized_tuple_coercion`] feature. * `Struct<.., Pi, .., Pj, ..>: Unsize>` given `TailField: Unsize`, which allows the tail field of a struct to be unsized if it is the only field that mentions generic parameters `Pi`, .., `Pj` (which don't need to be contiguous). -The rules for the latter implementation are slightly complicated, since they +The rules for struct unsizing are slightly complicated, since they may allow more than one parameter to be changed (not necessarily unsized) and are best stated in terms of the tail field of the struct. -[`unsized_tuple_coercion`]: https://doc.rust-lang.org/beta/unstable-book/language-features/unsized-tuple-coercion.html +(Tuple unsizing was previously implemented behind the feature gate +`unsized_tuple_coercion`, but the implementation was removed by [#137728].) + +[#137728]: https://github.com/rust-lang/rust/pull/137728 ## Upcasting implementations From e96bd9bfc08f260f786ea090c62a37db2cb97626 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Fri, 9 May 2025 16:42:35 +0300 Subject: [PATCH 266/447] Remove n.b. about parser refactoring Discussed in PR 2378; the note was outdated. --- src/macro-expansion.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/macro-expansion.md b/src/macro-expansion.md index ebab56ad2..76b4f2c61 100644 --- a/src/macro-expansion.md +++ b/src/macro-expansion.md @@ -2,9 +2,6 @@ -> N.B. [`rustc_ast`], [`rustc_expand`], and [`rustc_builtin_macros`] are all -> undergoing refactoring, so some of the links in this chapter may be broken. - 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 From 5a04183ad2d01772499b0283473e93b07da4da83 Mon Sep 17 00:00:00 2001 From: omahs <73983677+omahs@users.noreply.github.com> Date: Mon, 12 May 2025 11:15:46 +0200 Subject: [PATCH 267/447] Fix typos --- src/autodiff/installation.md | 2 +- src/rustdoc-internals/rustdoc-test-suite.md | 8 ++++---- src/type-checking.md | 2 +- src/type-inference.md | 2 +- src/typing_parameter_envs.md | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/autodiff/installation.md b/src/autodiff/installation.md index f3c113955..c9b28dc43 100644 --- a/src/autodiff/installation.md +++ b/src/autodiff/installation.md @@ -1,6 +1,6 @@ # Installation -In the near future, `std::autodiff` should become available in nightly builds for users. As a contribute however, you will still need to build rustc from source. Please be aware that the msvc target is not supported at the moment, all other tier 1 targets should work. Please open an issue if you encounter any problems on a supported tier 1 target, or if you succesfully build this project on a tier2/tier3 target. +In the near future, `std::autodiff` should become available in nightly builds for users. As a contributor however, you will still need to build rustc from source. Please be aware that the msvc target is not supported at the moment, all other tier 1 targets should work. Please open an issue if you encounter any problems on a supported tier 1 target, or if you successfully build this project on a tier2/tier3 target. ## Build instructions diff --git a/src/rustdoc-internals/rustdoc-test-suite.md b/src/rustdoc-internals/rustdoc-test-suite.md index 169b95a7e..bad7ac19d 100644 --- a/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/rustdoc-internals/rustdoc-test-suite.md @@ -16,10 +16,10 @@ In addition to the directives listed here, `rustdoc` tests also support most [compiletest directives](../tests/directives.html). -All `PATH`s in directives are relative to the the rustdoc output directory (`build/TARGET/test/rustdoc/TESTNAME`), +All `PATH`s in directives are relative to the rustdoc output directory (`build/TARGET/test/rustdoc/TESTNAME`), so it is conventional to use a `#![crate_name = "foo"]` attribute to avoid having to write a long crate name multiple times. -To avoid repetion, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument. +To avoid repetition, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument. All arguments take the form of quoted strings (both single and double quotes are supported), @@ -87,7 +87,7 @@ compiletest's `--bless` flag is forwarded to htmldocck. Usage: `//@ has-dir PATH` -Checks for the existance of directory `PATH`. +Checks for the existence of directory `PATH`. ### `files` @@ -106,7 +106,7 @@ Example: `//@ files "foo/bar" '["index.html", "sidebar-items.js"]'` ## Limitations `htmldocck.py` uses the xpath implementation from the standard library. This leads to several limitations: -* All `XPATH` arguments must start with `//` due to a flaw in the implemention. +* All `XPATH` arguments must start with `//` due to a flaw in the implementation. * Many XPath features (functions, axies, etc.) are not supported. * Only well-formed HTML can be parsed (hopefully rustdoc doesn't output mismatched tags). diff --git a/src/type-checking.md b/src/type-checking.md index b60694201..4e8b30b19 100644 --- a/src/type-checking.md +++ b/src/type-checking.md @@ -17,7 +17,7 @@ Type "collection" is the process of converting the types found in the HIR **internal representation** used by the compiler (`Ty<'tcx>`) – we also do similar conversions for where-clauses and other bits of the function signature. -To try and get a sense for the difference, consider this function: +To try and get a sense of the difference, consider this function: ```rust,ignore struct Foo { } diff --git a/src/type-inference.md b/src/type-inference.md index c03fa36d7..888eb2439 100644 --- a/src/type-inference.md +++ b/src/type-inference.md @@ -19,7 +19,7 @@ Here, the type of `things` is *inferred* to be `Vec<&str>` because of the value we push into `things`. The type inference is based on the standard Hindley-Milner (HM) type inference -algorithm, but extended in various way to accommodate subtyping, region +algorithm, but extended in various ways to accommodate subtyping, region inference, and higher-ranked types. ## A note on terminology diff --git a/src/typing_parameter_envs.md b/src/typing_parameter_envs.md index 757296d1f..67eaf51bf 100644 --- a/src/typing_parameter_envs.md +++ b/src/typing_parameter_envs.md @@ -4,7 +4,7 @@ ## Typing Environments -When interacting with the type system there are a few variables to consider that can affect the results of trait solving. The 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). +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). When an environment to perform type system operations in has not yet been created, the [`TypingEnv`][tenv] can be used to bundle all of the external context required into a single type. @@ -13,11 +13,11 @@ Once a context to perform type system operations in has been created (e.g. an [` [ocx]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/struct.ObligationCtxt.html [fnctxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html -## Parameter Environemnts +## Parameter Environments ### What is a `ParamEnv` -The [`ParamEnv`][penv] is a list of in-scope where-clauses, it typically corresponds to a specific item's where clauses. Some clauses are not explicitly written but are instead are implicitly added in the [`predicates_of`][predicates_of] query, such as `ConstArgHasType` or (some) implied bounds. +The [`ParamEnv`][penv] is a list of in-scope where-clauses, it typically corresponds to a specific item's where clauses. Some clauses are not explicitly written but are instead implicitly added in the [`predicates_of`][predicates_of] query, such as `ConstArgHasType` or (some) implied bounds. In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses. A `ParamEnv` can also be created with arbitrary sets of clauses that are not derived from a specific item, such as in [`compare_method_predicate_entailment`][method_pred_entailment] where we create a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. @@ -73,7 +73,7 @@ fn foo2(a: T) { ### Acquiring a `ParamEnv` -Using the wrong [`ParamEnv`][penv] when interacting with the type system can lead to ICEs, illformed programs compiling, or erroing when we shouldn't. See [#82159](https://github.com/rust-lang/rust/pull/82159) and [#82067](https://github.com/rust-lang/rust/pull/82067) as examples of PRs that modified the compiler to use the correct param env and in the process fixed ICEs. +Using the wrong [`ParamEnv`][penv] when interacting with the type system can lead to ICEs, illformed programs compiling, or erroring when we shouldn't. See [#82159](https://github.com/rust-lang/rust/pull/82159) and [#82067](https://github.com/rust-lang/rust/pull/82067) as examples of PRs that modified the compiler to use the correct param env and in the process fixed ICEs. In the large majority of cases, when a `ParamEnv` is required it either already exists somewhere in scope, or above in the call stack and should be passed down. A non exhaustive list of places where you might find an existing `ParamEnv`: - During typeck `FnCtxt` has a [`param_env` field][fnctxt_param_env] From 45107c759a680d0035a0bc41ab8cff91ba2d43a2 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 12 May 2025 23:59:55 +0200 Subject: [PATCH 268/447] remove dangling references --- src/macro-expansion.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/macro-expansion.md b/src/macro-expansion.md index 76b4f2c61..a90f71700 100644 --- a/src/macro-expansion.md +++ b/src/macro-expansion.md @@ -9,9 +9,6 @@ we have a complete [*Abstract Syntax Tree* (AST)][ast] for our crate with no unexpanded macros (or a compile error). [ast]: ./ast-validation.md -[`rustc_ast`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/index.html -[`rustc_expand`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/index.html -[`rustc_builtin_macros`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_builtin_macros/index.html [placeholders]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/placeholders/index.html First, we discuss the algorithm that expands and integrates macro output into From d47c2b442320308011d3b0a5e671a950af8f89c2 Mon Sep 17 00:00:00 2001 From: Li-yao Xia Date: Wed, 14 May 2025 11:36:00 +0200 Subject: [PATCH 269/447] Fix link to GatherBorrows --- src/borrow_check/two_phase_borrows.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/borrow_check/two_phase_borrows.md b/src/borrow_check/two_phase_borrows.md index bcd487821..b77ae0946 100644 --- a/src/borrow_check/two_phase_borrows.md +++ b/src/borrow_check/two_phase_borrows.md @@ -76,7 +76,7 @@ borrow. [`AutoBorrow`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/adjustment/enum.AutoBorrow.html [converted]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/thir/cx/expr/trait.ToBorrowKind.html#method.to_borrow_kind [`BorrowKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.BorrowKind.html -[`GatherBorrows`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/visit/trait.Visitor.html#method.visit_local +[`GatherBorrows`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/borrow_set/struct.GatherBorrows.html [`BorrowData`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/borrow_set/struct.BorrowData.html ## Checking two-phase borrows From ea21da3dac63e3c2acf2e5b2d93457ded4043092 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 15 May 2025 11:38:18 +0200 Subject: [PATCH 270/447] avoid upstream pull conflict We changed this line and have not pushed it upstream yet, and upstream changed it in the meanwhile. --- src/autodiff/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/autodiff/installation.md b/src/autodiff/installation.md index 971d07bfa..c9b28dc43 100644 --- a/src/autodiff/installation.md +++ b/src/autodiff/installation.md @@ -1,6 +1,6 @@ # Installation -In the near future, `std::autodiff` should become available in nightly builds for users. As a contributor however, you will still need to build rustc from source. Please be aware that the msvc target is not supported at the moment, all other tier 1 targets should work. Please open an issue if you encounter any problems on a supported tier 1 target, or if you succesfully build this project on a tier2/tier3 target. +In the near future, `std::autodiff` should become available in nightly builds for users. As a contributor however, you will still need to build rustc from source. Please be aware that the msvc target is not supported at the moment, all other tier 1 targets should work. Please open an issue if you encounter any problems on a supported tier 1 target, or if you successfully build this project on a tier2/tier3 target. ## Build instructions From 5012fc30165d4c28ec6ade4c342d1f54aa2700af Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Thu, 15 May 2025 09:46:15 +0000 Subject: [PATCH 271/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index ec1602280..5e4266f61 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -7e552b46af72df390ed233b58a7f51650515b2a8 +414482f6a0d4e7290f614300581a0b55442552a3 From 2ef17aa39b8933ef859d9c5d46964c0e0b82f1d7 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sat, 17 May 2025 23:51:00 +0800 Subject: [PATCH 272/447] rustc-dev-guide: fix Rust for Linux rust-lang/rust label --- src/notification-groups/rust-for-linux.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/notification-groups/rust-for-linux.md b/src/notification-groups/rust-for-linux.md index 9ba4eff62..696f2038e 100644 --- a/src/notification-groups/rust-for-linux.md +++ b/src/notification-groups/rust-for-linux.md @@ -1,9 +1,9 @@ # Rust for Linux notification group -**Github Label:** [O-rfl]
+**Github Label:** [A-rust-for-linux]
**Ping command:** `@rustbot ping rfl` -[O-rfl]: https://github.com/rust-lang/rust/labels/O-rfl +[A-rust-for-linux]: https://github.com/rust-lang/rust/labels/A-rust-for-linux This list will be used to notify [Rust for Linux (RfL)][rfl] maintainers when the compiler or the standard library changes in a way that would From ef032e8c8d5ae1dc85bff052ffc614ede1f17f51 Mon Sep 17 00:00:00 2001 From: Mahmoud Mazouz Date: Sun, 18 May 2025 15:37:18 +0200 Subject: [PATCH 273/447] Fix typos in "Libraries and Metadata" --- src/backend/libs-and-metadata.md | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/backend/libs-and-metadata.md b/src/backend/libs-and-metadata.md index 513df1650..eeb2af5e6 100644 --- a/src/backend/libs-and-metadata.md +++ b/src/backend/libs-and-metadata.md @@ -28,8 +28,8 @@ format is specific to `rustc`, and may change over time. This file contains: [`-C embed-bitcode=no`][embed-bitcode] CLI option to improve compile times and reduce disk space if LTO is not needed. * `rustc` [metadata], in a file named `lib.rmeta`. -* A symbol table, which is generally a list of symbols with offsets to the - object file that contain that symbol. This is pretty standard for archive +* A symbol table, which is essentially a list of symbols with offsets to the + object files that contain that symbol. This is pretty standard for archive files. [archive file]: https://en.wikipedia.org/wiki/Ar_(Unix) @@ -46,12 +46,11 @@ A `dylib` is a platform-specific shared library. It includes the `rustc` ### rmeta -An `rmeta` file is custom binary format that contains the [metadata] for the -crate. This file can be used for fast "checks" of a project by skipping all -code generation (as is done with `cargo check`), collecting enough information -for documentation (as is done with `cargo doc`), or for -[pipelining](#pipelining). This file is created if the -[`--emit=metadata`][emit] CLI option is used. +An `rmeta` file is a custom binary format that contains the [metadata] for the +crate. This file can be used for fast "checks" of a project by skipping all code +generation (as is done with `cargo check`), collecting enough information for +documentation (as is done with `cargo doc`), or for [pipelining](#pipelining). +This file is created if the [`--emit=metadata`][emit] CLI option is used. `rmeta` files do not support linking, since they do not contain compiled object files. @@ -60,8 +59,8 @@ object files. ## Metadata -The metadata contains a wide swath of different elements. This guide will not -go into detail of every field it contains. You are encouraged to browse the +The metadata contains a wide swath of different elements. This guide will not go +into detail about every field it contains. You are encouraged to browse the [`CrateRoot`] definition to get a sense of the different elements it contains. Everything about metadata encoding and decoding is in the [`rustc_metadata`] package. @@ -122,9 +121,9 @@ much more. By default, all Rust symbols are mangled and incorporate the stable crate id. This allows multiple versions of the same crate to be included together. Cargo -automatically generates `-C metadata` hashes based on a variety of factors, -like the package version, source, and the target kind (a lib and test can have -the same crate name, so they need to be disambiguated). +automatically generates `-C metadata` hashes based on a variety of factors, like +the package version, source, and target kind (a lib and test can have the same +crate name, so they need to be disambiguated). [`StableCrateId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/def_id/struct.StableCrateId.html [`StableCrateId::new`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/def_id/struct.StableCrateId.html#method.new @@ -154,7 +153,7 @@ will also look at the [sysroot] to find dependencies. As crates are loaded, they are kept in the [`CStore`] with the crate metadata wrapped in the [`CrateMetadata`] struct. After resolution and expansion, the -`CStore` will make its way into the [`GlobalCtxt`] for the rest of +`CStore` will make its way into the [`GlobalCtxt`] for the rest of the compilation. [name resolution]: ../name-resolution.md From 4123a275beb2061eaa948da93a315a68e46d22b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 18 May 2025 20:01:47 +0200 Subject: [PATCH 274/447] Exclude issues with an associated PR from the "What should I work on" GH query --- src/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/getting-started.md b/src/getting-started.md index 8bf14bef2..0e5b32a06 100644 --- a/src/getting-started.md +++ b/src/getting-started.md @@ -89,7 +89,7 @@ filtering the search to areas you're interested in. For example: Not all important or beginner work has issue labels. See below for how to find work that isn't labelled. -[help-wanted-search]: https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Arust-lang+no%3Aassignee+label%3AE-easy%2C%22good+first+issue%22%2Cgood-first-issue%2CE-medium%2CEasy%2CE-help-wanted%2CE-mentor+-label%3AS-blocked+ +[help-wanted-search]: https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Arust-lang+no%3Aassignee+label%3AE-easy%2C%22good+first+issue%22%2Cgood-first-issue%2CE-medium%2CEasy%2CE-help-wanted%2CE-mentor+-label%3AS-blocked+-linked:pr+ [Triage]: ./contributing.md#issue-triage ### Recurring work From 1962be7988285975077237e0a614176282625aa8 Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Mon, 19 May 2025 04:10:52 +0000 Subject: [PATCH 275/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 5e4266f61..0d889a5d5 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -414482f6a0d4e7290f614300581a0b55442552a3 +e42bbfe1f7c26f8760a99c4b1f27d33aba1040bb From eae6f4ce66b6bd4083c89903a10ed1d7b9167479 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Mon, 19 May 2025 14:41:19 +0300 Subject: [PATCH 276/447] Remove unused references and simplify one --- src/rustc-driver/intro.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/rustc-driver/intro.md b/src/rustc-driver/intro.md index 40500e6bc..a3684397b 100644 --- a/src/rustc-driver/intro.md +++ b/src/rustc-driver/intro.md @@ -7,8 +7,8 @@ It acts as the glue for running the various phases of the compiler in the correc using the interface defined in the [`rustc_interface`] crate. Where possible, using [`rustc_driver`] rather than [`rustc_interface`] is recommended. The main entry point of [`rustc_driver`] is [`rustc_driver::run_compiler`][rd_rc]. -This builder accepts the same command-line args as rustc as well as an implementation of [`Callbacks`][cb] and a couple of other optional options. -[`Callbacks`][cb] is a `trait` that allows for custom compiler configuration, +This builder accepts the same command-line args as rustc as well as an implementation of [`Callbacks`] and a couple of other optional options. +[`Callbacks`] is a `trait` that allows for custom compiler configuration, as well as allowing custom code to run after different phases of the compilation. ## `rustc_interface` @@ -33,14 +33,8 @@ specifically [`rustc_driver_impl::run_compiler`][rdi_rc] [`Compiler`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Compiler.html [`rustc_driver`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/ [`rustc_interface`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/index.html -[`Session`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html -[`SourceMap`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/source_map/struct.SourceMap.html -[`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html -[Appendix A]: appendix/stupid-stats.html -[cb]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/trait.Callbacks.html +[`Callbacks`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/trait.Callbacks.html [example]: https://github.com/rust-lang/rustc-dev-guide/blob/master/examples/rustc-interface-example.rs [i_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/fn.run_compiler.html [rd_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/fn.run_compiler.html [rdi_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver_impl/fn.run_compiler.html -[stupid-stats]: https://github.com/nrc/stupid-stats -[`nightly-rustc`]: https://doc.rust-lang.org/nightly/nightly-rustc/ From 007a7a109c1507f4195be02c23b183fcc00e7924 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Mon, 19 May 2025 14:44:36 +0300 Subject: [PATCH 277/447] Make run instructions first Better, because then one knows how to run the examples. --- src/SUMMARY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 31119496e..a7b76233d 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -134,9 +134,9 @@ - [Command-line arguments](./cli.md) - [rustc_driver and rustc_interface](./rustc-driver/intro.md) + - [Remarks on perma-unstable features](./rustc-driver/remarks-on-perma-unstable-features.md) - [Example: Type checking](./rustc-driver/interacting-with-the-ast.md) - [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.md) - - [Remarks on perma-unstable features](./rustc-driver/remarks-on-perma-unstable-features.md) - [Errors and lints](diagnostics.md) - [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md) - [Translation](./diagnostics/translation.md) From 6ec183f9bc9afdc7874146b7ea082dffdb3c5ae0 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Mon, 19 May 2025 17:32:29 +0300 Subject: [PATCH 278/447] Update link to Forge guide on new flags --- src/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli.md b/src/cli.md index 408ae2070..4c77007ea 100644 --- a/src/cli.md +++ b/src/cli.md @@ -28,6 +28,6 @@ adding a new command-line argument. unstable-options` flag. [cli-docs]: https://doc.rust-lang.org/rustc/command-line-arguments.html -[forge guide for new options]: https://forge.rust-lang.org/compiler/new_option.html +[forge guide for new options]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#compiler-flags [unstable book]: https://doc.rust-lang.org/nightly/unstable-book/ [`parse_bool`]: https://github.com/rust-lang/rust/blob/e5335592e78354e33d798d20c04bcd677c1df62d/src/librustc_session/options.rs#L307-L313 From 3a949427fdbf9fd0440c1c0d90865eab799c6ea0 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Tue, 20 May 2025 11:41:55 +0300 Subject: [PATCH 279/447] Small typo and style fixes in binders.md Normally I refrain from nit picking, but this seamed worth it. --- src/ty_module/binders.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ty_module/binders.md b/src/ty_module/binders.md index 71157eca9..7fd9eeed5 100644 --- a/src/ty_module/binders.md +++ b/src/ty_module/binders.md @@ -1,6 +1,6 @@ # `Binder` and Higher ranked regions -Sometimes we define generic parameters not on an item but as part of a type or a where clauses. As an example the type `for<'a> fn(&'a u32)` or the where clause `for<'a> T: Trait<'a>` both introduce a generic lifetime named `'a`. Currently there is no stable syntax for `for` or `for` but on nightly `feature(non_lifetime_binders)` feature can be used to write where clauses (but not types) using `for`/`for`. +Sometimes we define generic parameters not on an item but as part of a type or a where clause. As an example the type `for<'a> fn(&'a u32)` or the where clause `for<'a> T: Trait<'a>` both introduce a generic lifetime named `'a`. Currently there is no stable syntax for `for` or `for` but on nightly `feature(non_lifetime_binders)` can be used to write where clauses (but not types) using `for`/`for`. The `for` is referred to as a "binder" because it brings new names into scope. In rustc we use the `Binder` type to track where these parameters are introduced and what the parameters are (i.e. how many and whether the parameter is a type/const/region). A type such as `for<'a> fn(&'a u32)` would be represented in rustc as: @@ -13,8 +13,9 @@ Binder( Usages of these parameters is represented by the `RegionKind::Bound` (or `TyKind::Bound`/`ConstKind::Bound` variants). These bound regions/types/consts are composed of two main pieces of data: - A [DebruijnIndex](../appendix/background.md#what-is-a-de-bruijn-index) to specify which binder we are referring to. -- A [`BoundVar`] which specifies which of the parameters the `Binder` introduces we are referring to. -- We also sometimes store some extra information for diagnostics reasons via the [`BoundTyKind`]/[`BoundRegionKind`] but this is not important for type equality or more generally the semantics of `Ty`. (omitted from the above example) +- A [`BoundVar`] which specifies which of the parameters that the `Binder` introduces we are referring to. + +We also sometimes store some extra information for diagnostics reasons via the [`BoundTyKind`]/[`BoundRegionKind`] but this is not important for type equality or more generally the semantics of `Ty`. (omitted from the above example) In debug output (and also informally when talking to each other) we tend to write these bound variables in the format of `^DebruijnIndex_BoundVar`. The above example would instead be written as `Binder(fn(&'^0_0), &[BoundVariableKind::Region])`. Sometimes when the `DebruijnIndex` is `0` we just omit it and would write `^0`. @@ -43,7 +44,7 @@ Binder( &[BoundVariableKind::Region(...)], ) ``` -This would cause all kinds of issues as the region `'^1_0` refers to a binder at a higher level than the outermost binder i.e. it is an escaping bound var. The `'^1` region (also writeable as `'^0_1`) is also ill formed as the binder it refers to does not introduce a second parameter. Modern day rustc will ICE when constructing this binder due to both of those regions, in the past we would have simply allowed this to work and then ran into issues in other parts of the codebase. +This would cause all kinds of issues as the region `'^1_0` refers to a binder at a higher level than the outermost binder i.e. it is an escaping bound var. The `'^1` region (also writeable as `'^0_1`) is also ill formed as the binder it refers to does not introduce a second parameter. Modern day rustc will ICE when constructing this binder due to both of those reasons, in the past we would have simply allowed this to work and then ran into issues in other parts of the codebase. [`Binder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Binder.html [`BoundVar`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.BoundVar.html From 05a7dc42d47ec61f3c71851d81bc05935d90d769 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Tue, 20 May 2025 13:46:04 +0300 Subject: [PATCH 280/447] Update links between ty-module and binders The order might have been reversed at some point, leading to the two chapters talking about each other in the wrong order. --- src/ty_module/instantiating_binders.md | 4 +++- src/ty_module/param_ty_const_regions.md | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/ty_module/instantiating_binders.md b/src/ty_module/instantiating_binders.md index 04d56ccbc..e3f091ca4 100644 --- a/src/ty_module/instantiating_binders.md +++ b/src/ty_module/instantiating_binders.md @@ -105,7 +105,8 @@ the `RePlaceholder` for the `'b` parameter is in a higher universe to track the ## Instantiating with `ReLateParam` -As discussed in a previous chapter, `RegionKind` has two variants for representing generic parameters, `ReLateParam` and `ReEarlyParam`. `ReLateParam` is conceptually a `Placeholder` that is always in the root universe (`U0`). It is used when instantiating late bound parameters of functions/closures while inside of them. Its actual representation is relatively different from both `ReEarlyParam` and `RePlaceholder`: +As discussed in [the chapter about representing types][representing-types], `RegionKind` has two variants for representing generic parameters, `ReLateParam` and `ReEarlyParam`. +`ReLateParam` is conceptually a `Placeholder` that is always in the root universe (`U0`). It is used when instantiating late bound parameters of functions/closures while inside of them. Its actual representation is relatively different from both `ReEarlyParam` and `RePlaceholder`: - A `DefId` for the item that introduced the late bound generic parameter - A [`BoundRegionKind`] which either specifies the `DefId` of the generic parameter and its name (via a `Symbol`), or that this placeholder is representing the anonymous lifetime of a `Fn`/`FnMut` closure's self borrow. There is also a variant for `BrAnon` but this is not used for `ReLateParam`. @@ -133,6 +134,7 @@ Generally whenever we have a `Binder` for late bound parameters on a function/cl As a concrete example, accessing the signature of a function we are type checking will be represented as `EarlyBinder>`. As we are already "inside" of these binders, we would call `instantiate_identity` followed by `liberate_late_bound_regions`. [`liberate_late_bound_regions`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.liberate_late_bound_regions +[representing-types]: param_ty_const_regions.md [`BoundRegionKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.BoundRegionKind.html [`enter_forall`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/infer/struct.InferCtxt.html#method.enter_forall [ch_placeholders_universes]: ../borrow_check/region_inference/placeholders_and_universes.md diff --git a/src/ty_module/param_ty_const_regions.md b/src/ty_module/param_ty_const_regions.md index c52f0c0df..493693c9a 100644 --- a/src/ty_module/param_ty_const_regions.md +++ b/src/ty_module/param_ty_const_regions.md @@ -11,15 +11,15 @@ TyKind::Ref( There are three separate ways we represent usages of generic parameters: - [`TyKind::Param`]/[`ConstKind::Param`]/[`RegionKind::EarlyParam`] for early bound generic parameters (note: all type and const parameters are considered early bound, see the [chapter on early vs late bound parameters][ch_early_late_bound] for more information) -- [`TyKind::Bound`]/[`ConstKind::Bound`]/[`RegionKind::Bound`] for references to parameters introduced via higher ranked bounds or higher ranked types i.e. `for<'a> fn(&'a u32)` or `for<'a> T: Trait<'a>`. This will be discussed in the [chapter on `Binder`s][ch_binders]. -- [`RegionKind::LateParam`] for late bound lifetime parameters, `LateParam` will be discussed in the [chapter on instantiating `Binder`s][ch_instantiating_binders]. +- [`TyKind::Bound`]/[`ConstKind::Bound`]/[`RegionKind::Bound`] for references to parameters introduced via higher ranked bounds or higher ranked types i.e. `for<'a> fn(&'a u32)` or `for<'a> T: Trait<'a>`. This is discussed in the [chapter on `Binder`s][ch_binders]. +- [`RegionKind::LateParam`] for late bound lifetime parameters, `LateParam` is discussed in the [chapter on instantiating `Binder`s][ch_instantiating_binders]. -This chapter will only cover `TyKind::Param` `ConstKind::Param` and `RegionKind::EarlyParam`. +This chapter only covers `TyKind::Param` `ConstKind::Param` and `RegionKind::EarlyParam`. ## Ty/Const Parameters -As `TyKind::Param` and `ConstKind::Param` are implemented identically this section will only refer to `TyKind::Param` for simplicity. However -you should keep in mind that everything here also is true of `ConstKind::Param` +As `TyKind::Param` and `ConstKind::Param` are implemented identically this section only refers to `TyKind::Param` for simplicity. +However you should keep in mind that everything here also is true of `ConstKind::Param` Each `TyKind::Param` contains two things: the name of the parameter and an index. @@ -83,7 +83,7 @@ fn foo<'a, 'b, T: 'a>(one: T, two: &'a &'b u32) -> &'b u32 { } ``` -`RegionKind::LateParam` will be discussed more in the chapter on [instantiating binders][ch_instantiating_binders]. +`RegionKind::LateParam` is discussed more in the chapter on [instantiating binders][ch_instantiating_binders]. [ch_early_late_bound]: ../early_late_parameters.md [ch_binders]: ./binders.md From 011f51231e90e5f58d934c7364ddf9b8f4f97973 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Tue, 20 May 2025 13:26:22 +0200 Subject: [PATCH 281/447] Fix misdirected link for `TypingEnv` --- src/typing_parameter_envs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/typing_parameter_envs.md b/src/typing_parameter_envs.md index 67eaf51bf..a8f405982 100644 --- a/src/typing_parameter_envs.md +++ b/src/typing_parameter_envs.md @@ -199,8 +199,8 @@ In the next-gen trait solver the requirement for all where clauses in the `Param Depending on what context we are performing type system operations in, different behaviour may be required. For example during coherence there are stronger requirements about when we can consider goals to not hold or when we can consider types to be unequal. -Tracking which "phase" of the compiler type system operations are being performed in is done by the [`TypingMode`][tenv] enum. The documentation on the `TypingMode` enum is quite good so instead of repeating it here verbatim we would recommend reading the API documentation directly. +Tracking which "phase" of the compiler type system operations are being performed in is done by the [`TypingMode`][tmode] enum. The documentation on the `TypingMode` enum is quite good so instead of repeating it here verbatim we would recommend reading the API documentation directly. [penv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html -[tenv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/infer_ctxt/enum.TypingMode.html +[tenv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypingEnv.html [tmode]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.TypingMode.html From 731daeed50b00014adb9da3e7235443d897fa237 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Tue, 20 May 2025 16:25:11 +0300 Subject: [PATCH 282/447] Make it clear we talk about early bound params --- src/early_late_parameters.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/early_late_parameters.md b/src/early_late_parameters.md index 3b2a5e8a1..3f94b0905 100644 --- a/src/early_late_parameters.md +++ b/src/early_late_parameters.md @@ -174,7 +174,8 @@ As mentioned previously, the distinction between early and late bound parameters - When naming a function (early) - When calling a function (late) -There currently is no syntax for explicitly specifying generic arguments for late bound parameters as part of the call step, only specifying generic arguments when naming a function. The syntax `foo::<'static>();`, despite being part of a function call, behaves as `(foo::<'static>)();` and instantiates the early bound generic parameters on the function item type. +There is currently no syntax for explicitly specifying generic arguments for late bound parameters during the call step; generic arguments can only be specified for early bound parameters when naming a function. +The syntax `foo::<'static>();`, despite being part of a function call, behaves as `(foo::<'static>)();` and instantiates the early bound generic parameters on the function item type. See the following example: ```rust From eeafdb1de67b5742295679b2680d01dda4e81f1d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 22 May 2025 19:37:29 +0200 Subject: [PATCH 283/447] ~? annotation type is special It does not do any line matching, so it should be separated from the other types. --- src/tests/ui.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index 721d20b65..3402838da 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -192,7 +192,7 @@ They have several forms, but generally are a comment with the diagnostic level to write out the entire message, just make sure to include the important part of the message to make it self-documenting. -The error annotation needs to match with the line of the diagnostic. There are +Most error annotations need to match with the line of the diagnostic. There are several ways to match the message with the line (see the examples below): * `~`: Associates the error level and message with the *current* line @@ -205,9 +205,6 @@ several ways to match the message with the line (see the examples below): * `~v`: Associates the error level and message with the *next* error annotation line. Each symbol (`v`) that you add adds a line to this, so `~vvv` is three lines below the error annotation line. -* `~?`: Used to match error levels and messages with errors not having line - information. These can be placed on any line in the test file, but are - conventionally placed at the end. Example: @@ -222,6 +219,10 @@ The space character between `//~` (or other variants) and the subsequent text is negligible (i.e. there is no semantic difference between `//~ ERROR` and `//~ERROR` although the former is more common in the codebase). +`~? ` (example being `~? ERROR`) +is used to match diagnostics without line information. +These can be placed on any line in the test file, but are conventionally placed at the end. + ### Error annotation examples Here are examples of error annotations on different lines of UI test source. From 677577571ea4049dc238b8411d03093983bd4d19 Mon Sep 17 00:00:00 2001 From: lolbinarycat Date: Thu, 22 May 2025 17:31:36 -0500 Subject: [PATCH 284/447] rustdoc.md: reorder list so test suites are not split up --- src/rustdoc.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rustdoc.md b/src/rustdoc.md index e36d6a388..78e17ba1e 100644 --- a/src/rustdoc.md +++ b/src/rustdoc.md @@ -93,13 +93,13 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) interactivity. For information on how to write this form of test, see [`tests/rustdoc-gui/README.md`][rustdoc-gui-readme] as well as [the description of the `.goml` format][goml-script] -* Additionally, JavaScript type annotations are written using [TypeScript-flavored JSDoc] - comments and an external d.ts file. The code itself is plain, valid JavaScript; we only - use tsc as a linter. -* The tests on the structure of rustdoc HTML output are located in `tests/rustdoc`, +* Tests on the structure of rustdoc HTML output are located in `tests/rustdoc`, where they're handled by the test runner of bootstrap and the supplementary script `src/etc/htmldocck.py`. [These tests have several extra directives available to them](./rustdoc-internals/rustdoc-test-suite.md). +* Additionally, JavaScript type annotations are written using [TypeScript-flavored JSDoc] + comments and an external d.ts file. The code itself is plain, valid JavaScript; we only + use tsc as a linter. [TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html [rustdoc-gui-readme]: https://github.com/rust-lang/rust/blob/master/tests/rustdoc-gui/README.md From 316e392131e685b868bae7d9fe6579e4292b16be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 23 May 2025 13:27:17 +0200 Subject: [PATCH 285/447] Remove mentions of rust-lang-ci/rust Now that CI has been finally migrated to `rust-lang/rust`. --- src/tests/ci.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/tests/ci.md b/src/tests/ci.md index 825be11c8..d8be8224d 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -100,8 +100,8 @@ Most platforms only run the build steps, some run a restricted set of tests, only a subset run the full suite of tests (see Rust's [platform tiers]). Auto jobs are defined in the `auto` section of [`jobs.yml`]. They are executed -on the `auto` branch under the `rust-lang-ci/rust` repository[^rust-lang-ci] and -their results can be seen [here](https://github.com/rust-lang-ci/rust/actions), +on the `auto` branch under the `rust-lang/rust` repository and +their results can be seen [here](https://github.com/rust-lang/rust/actions), although usually you will be notified of the result by a comment made by bors on the corresponding PR. @@ -110,9 +110,6 @@ more [here](#merging-prs-serially-with-bors). [platform tiers]: https://forge.rust-lang.org/release/platform-support.html#rust-platform-support -[^rust-lang-ci]: The `auto` and `try` jobs run under the `rust-lang-ci` fork for - historical reasons. This may change in the future. - ### Try builds Sometimes we want to run a subset of the test suite on CI for a given PR, or @@ -179,8 +176,8 @@ the pattern as Markdown. > that are exercised this way. Try jobs are defined in the `try` section of [`jobs.yml`]. They are executed on -the `try` branch under the `rust-lang-ci/rust` repository[^rust-lang-ci] and -their results can be seen [here](https://github.com/rust-lang-ci/rust/actions), +the `try` branch under the `rust-lang/rust` repository and +their results can be seen [here](https://github.com/rust-lang/rust/actions), although usually you will be notified of the result by a comment made by bors on the corresponding PR. @@ -355,7 +352,7 @@ invalidated if one of the following changes: - Files copied into the Docker image in the Dockerfile - The architecture of the GitHub runner (x86 or ARM) -[ghcr.io]: https://github.com/rust-lang-ci/rust/pkgs/container/rust-ci +[ghcr.io]: https://github.com/rust-lang/rust/pkgs/container/rust-ci [Docker registry caching]: https://docs.docker.com/build/cache/backends/registry/ ### LLVM caching with sccache @@ -446,7 +443,7 @@ particular job, it is probably easiest to just look at the build log. To do this: 1. Go to - + to find the most recently successful build, and click on it. 2. Choose the job you are interested in on the left-hand side. 3. Click on the gear icon and choose "View raw logs" @@ -458,7 +455,6 @@ this: [`jobs.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/jobs.yml [`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/master/.github/workflows/ci.yml [`src/ci/citool`]: https://github.com/rust-lang/rust/blob/master/src/ci/citool -[rust-lang-ci]: https://github.com/rust-lang-ci/rust/actions [bors]: https://github.com/bors [homu]: https://github.com/rust-lang/homu [merge queue]: https://bors.rust-lang.org/queue/rust From b9f639a01a0108add550cddf292bd8526de4ddd9 Mon Sep 17 00:00:00 2001 From: jyn Date: Fri, 23 May 2025 10:41:44 -0400 Subject: [PATCH 286/447] document why rustdoc cannot look at function bodies --- src/rustdoc.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/rustdoc.md b/src/rustdoc.md index e36d6a388..3139dfc63 100644 --- a/src/rustdoc.md +++ b/src/rustdoc.md @@ -116,6 +116,28 @@ Certain browser features that require secure origins, like `localStorage` and Service Workers, don't work reliably. We can still use such features but we should make sure pages are still usable without them. +Rustdoc [does not type-check function bodies][platform-specific docs]. +This works by [overriding the built-in queries for typeck][override queries], +by [silencing name resolution errors], and by [not resolving opaque types]. +This comes with several caveats: in particular, rustdoc *cannot* run any parts of the compiler that +require type-checking bodies; for example it cannot generate `.rlib` files or run most lints. +We want to move away from this model eventually, but we need some alternative for +[the people using it][async-std]; see [various][zulip stop accepting broken code] +[previous][rustdoc meeting 2024-07-08] [zulip][compiler meeting 2023-01-26] [discussion][notriddle rfc]. +For examples of code that breaks if this hack is removed, see +[`tests/rustdoc-ui/error-in-impl-trait`]. + +[platform-specific docs]: https://doc.rust-lang.org/rustdoc/advanced-features.html#interactions-between-platform-specific-docs +[override queries]: https://github.com/rust-lang/rust/blob/52bf0cf795dfecc8b929ebb1c1e2545c3f41d4c9/src/librustdoc/core.rs#L299-L323 +[silencing name resolution errors]: https://github.com/rust-lang/rust/blob/52bf0cf795dfecc8b929ebb1c1e2545c3f41d4c9/compiler/rustc_resolve/src/late.rs#L4517 +[not resolving opaque types]: https://github.com/rust-lang/rust/blob/52bf0cf795dfecc8b929ebb1c1e2545c3f41d4c9/compiler/rustc_hir_analysis/src/check/check.rs#L188-L194 +[async-std]: https://github.com/rust-lang/rust/issues/75100 +[rustdoc meeting 2024-07-08]: https://rust-lang.zulipchat.com/#narrow/channel/393423-t-rustdoc.2Fmeetings/topic/meeting.202024-07-08/near/449969836 +[compiler meeting 2023-01-26]: https://rust-lang.zulipchat.com/#narrow/channel/238009-t-compiler.2Fmeetings/topic/.5Bweekly.5D.202023-01-26/near/323755789 +[zulip stop accepting broken code]: https://rust-lang.zulipchat.com/#narrow/stream/266220-rustdoc/topic/stop.20accepting.20broken.20code +[notriddle rfc]: https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/Pre-RFC.3A.20stop.20accepting.20broken.20code +[`tests/rustdoc-ui/error-in-impl-trait`]: https://github.com/rust-lang/rust/tree/163cb4ea3f0ae3bc7921cc259a08a7bf92e73ee6/tests/rustdoc-ui/error-in-impl-trait + ## Multiple runs, same output directory Rustdoc can be run multiple times for varying inputs, with its output set to the From c6f2047a55b73852636366538f39436c4b3ae38d Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 24 May 2025 02:30:23 +0800 Subject: [PATCH 287/447] Add LLVM link in appendix --- src/appendix/compiler-lecture.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/appendix/compiler-lecture.md b/src/appendix/compiler-lecture.md index dabd2f087..90c4097cc 100644 --- a/src/appendix/compiler-lecture.md +++ b/src/appendix/compiler-lecture.md @@ -46,3 +46,4 @@ These are videos where various experts explain different parts of the compiler: ## Code Generation - [January 2019: Cranelift](https://www.youtube.com/watch?v=9OIA7DTFQWU) +- [December 2024: LLVM Developers' Meeting - Rust ❤️ LLVM](https://www.youtube.com/watch?v=Kqz-umsAnk8) \ No newline at end of file From f640f46968bb8b495bfb0b5fbdf1c3fd42593d55 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 24 May 2025 01:38:43 +0200 Subject: [PATCH 288/447] typo --- src/tests/compiletest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index 0ba078f0b..50982f3bb 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -549,7 +549,7 @@ compiler to ICE, panic or crash in some other way, so that accidental fixes are tracked. This was formally done at but doing it inside the rust-lang/rust testsuite is more convenient. -It is imperative that a test in the suite causes rustc to ICE, panic or crash +It is imperative that a test in the suite causes rustc to ICE, panic, or crash in some other way. A test will "pass" if rustc exits with an exit status other than 1 or 0. From 0ca84c1313c234face9e791ffb0fbbd2cb25b0ed Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Sat, 24 May 2025 19:16:01 +0200 Subject: [PATCH 289/447] Update `rustc_on_unimplemented` docs --- src/diagnostics.md | 162 ++++++++++++++++++++++++++++----------------- 1 file changed, 101 insertions(+), 61 deletions(-) diff --git a/src/diagnostics.md b/src/diagnostics.md index 2f8f4b0ab..01e59c919 100644 --- a/src/diagnostics.md +++ b/src/diagnostics.md @@ -866,19 +866,17 @@ struct](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/json/struct (and sub-structs) for the JSON serialization. Don't confuse this with [`errors::Diag`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html)! -## `#[rustc_on_unimplemented(...)]` +## `#[rustc_on_unimplemented]` -The `#[rustc_on_unimplemented]` attribute allows trait definitions to add specialized -notes to error messages when an implementation was expected but not found. -You can refer to the trait's generic arguments by name and to the resolved type using `Self`. - -For example: +This attribute allows trait definitions to modify error messages when an implementation was +expected but not found. The string literals in the attribute are format strings and can be +formatted with named parameters. See the Formatting +section below for what parameters are permitted. ```rust,ignore -#![feature(rustc_attrs)] - -#[rustc_on_unimplemented="an iterator over elements of type `{A}` \ - cannot be built from a collection of type `{Self}`"] +#[rustc_on_unimplemented(message = "an iterator over \ + elements of type `{A}` cannot be built from a \ + collection of type `{Self}`")] trait MyIterator { fn next(&mut self) -> A; } @@ -895,32 +893,26 @@ fn main() { When the user compiles this, they will see the following; ```txt -error[E0277]: the trait bound `&[{integer}]: MyIterator` is not satisfied - --> :14:5 +error[E0277]: an iterator over elements of type `char` cannot be built from a collection of type `&[{integer}]` + --> src/main.rs:13:19 | -14 | iterate_chars(&[1, 2, 3][..]); - | ^^^^^^^^^^^^^ an iterator over elements of type `char` cannot be built from a collection of type `&[{integer}]` +13 | iterate_chars(&[1, 2, 3][..]); + | ------------- ^^^^^^^^^^^^^^ the trait `MyIterator` is not implemented for `&[{integer}]` + | | + | required by a bound introduced by this call | - = help: the trait `MyIterator` is not implemented for `&[{integer}]` - = note: required by `iterate_chars` +note: required by a bound in `iterate_chars` ``` -`rustc_on_unimplemented` also supports advanced filtering for better targeting -of messages, as well as modifying specific parts of the error message. You -target the text of: - +You can modify the contents of: - the main error message (`message`) - the label (`label`) - - an extra note (`note`) + - the note(s) (`note`) For example, the following attribute ```rust,ignore -#[rustc_on_unimplemented( - message="message", - label="label", - note="note" -)] +#[rustc_on_unimplemented(message = "message", label = "label", note = "note")] trait MyIterator { fn next(&mut self) -> A; } @@ -930,45 +922,61 @@ Would generate the following output: ```text error[E0277]: message - --> :14:5 + --> :10:19 | -14 | iterate_chars(&[1, 2, 3][..]); - | ^^^^^^^^^^^^^ label +10 | iterate_chars(&[1, 2, 3][..]); + | ------------- ^^^^^^^^^^^^^^ label + | | + | required by a bound introduced by this call | - = note: note = help: the trait `MyIterator` is not implemented for `&[{integer}]` - = note: required by `iterate_chars` + = note: note +note: required by a bound in `iterate_chars` ``` +The functionality discussed so far is also available with +[`#[diagnostic::on_unimplemented]`](https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnosticon_unimplemented-attribute). +If you can, you should use that instead. + +### Filtering + To allow more targeted error messages, it is possible to filter the -application of these fields based on a variety of attributes when using -`on`: +application of these fields with `on`. +You can filter on the following boolean flags: - `crate_local`: whether the code causing the trait bound to not be fulfilled is part of the user's crate. This is used to avoid suggesting code changes that would require modifying a dependency. - - Any of the generic arguments that can be substituted in the text can be - referred by name as well for filtering, like `Rhs="i32"`, except for - `Self`. - - `_Self`: to filter only on a particular calculated trait resolution, like - `Self="std::iter::Iterator"`. This is needed because `Self` is a - keyword which cannot appear in attributes. - - `direct`: user-specified rather than derived obligation. - - `from_desugaring`: usable both as boolean (whether the flag is present) - or matching against a particular desugaring. The desugaring is identified - with its variant name in the `DesugaringKind` enum. - -For example, the `Iterator` trait can be annotated in the following way: + - `direct`: whether this is an user-specified rather than derived obligation. + - `from_desugaring`: whether we are in some kind of desugaring, like `?` + or a `try` block for example. This flag can also be matched on, see below. + +You can match on the following names and values, using `name = "value"`: + - `cause`: Match against one variant of the `ObligationCauseCode` + enum. Only `"MainFunctionType"` is supported. + - `from_desugaring`: Match against a particular variant of the `DesugaringKind` + enum. The desugaring is identified by its variant name, for example + `"QuestionMark"` for `?` desugaring or `"TryBlock"` for `try` blocks. + - `Self` and any generic arguments of the trait, like `Self = "alloc::string::String"` + or `Rhs="i32"`. + +The compiler can provide several values to match on, for example: + - the self_ty, pretty printed with and without type arguments resolved. + - `"{integral}"`, if self_ty is an integral of which the type is known. + - `"[]"`, `"[{ty}]"`, `"[{ty}; _]"`, `"[{ty}; $N]"` when applicable. + - references to said slices and arrays. + - `"fn"`, `"unsafe fn"` or `"#[target_feature] fn"` when self is a function. + - `"{integer}"` and `"{float}"` if the type is a number but we haven't inferred it yet. + - combinations of the above, like `"[{integral}; _]"`. + +For example, the `Iterator` trait can be filtered in the following way: ```rust,ignore #[rustc_on_unimplemented( - on( - _Self="&str", - note="call `.chars()` or `.as_bytes()` on `{Self}`" - ), - message="`{Self}` is not an iterator", - label="`{Self}` is not an iterator", - note="maybe try calling `.iter()` or a similar method" + on(Self = "&str", note = "call `.chars()` or `.as_bytes()` on `{Self}`"), + message = "`{Self}` is not an iterator", + label = "`{Self}` is not an iterator", + note = "maybe try calling `.iter()` or a similar method" )] pub trait Iterator {} ``` @@ -997,15 +1005,47 @@ error[E0277]: `&str` is not an iterator = note: required by `std::iter::IntoIterator::into_iter` ``` -If you need to filter on multiple attributes, you can use `all`, `any` or -`not` in the following way: +The `on` filter accepts `all`, `any` and `not` predicates similar to the `cfg` attribute: ```rust,ignore -#[rustc_on_unimplemented( - on( - all(_Self="&str", T="std::string::String"), - note="you can coerce a `{T}` into a `{Self}` by writing `&*variable`" - ) -)] -pub trait From: Sized { /* ... */ } +#[rustc_on_unimplemented(on( + all(Self = "&str", T = "alloc::string::String"), + note = "you can coerce a `{T}` into a `{Self}` by writing `&*variable`" +))] +pub trait From: Sized { + /* ... */ +} +``` + +### Formatting + +The string literals are format strings that accept parameters wrapped in braces +but positional and listed parameters and format specifiers are not accepted. +The following parameter names are valid: +- `Self` and all generic parameters of the trait. +- `This`: the name of the trait the attribute is on, without generics. +- `Trait`: the name of the "sugared" trait. See `TraitRefPrintSugared`. +- `ItemContext`: the kind of `hir::Node` we're in, things like `"an async block"`, + `"a function"`, `"an async function"`, etc. + +Something like: + +```rust,ignore +#![feature(rustc_attrs)] + +#[rustc_on_unimplemented(message = "Self = `{Self}`, \ + T = `{T}`, this = `{This}`, trait = `{Trait}`, \ + context = `{ItemContext}`")] +pub trait From: Sized { + fn from(x: T) -> Self; +} + +fn main() { + let x: i8 = From::from(42_i32); +} +``` + +Will format the message into +```text +"Self = `i8`, T = `i32`, this = `From`, trait = `From`, context = `a function`" ``` From 290bacb73e02435fddba202312bf744dde919524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 26 May 2025 13:47:28 +0200 Subject: [PATCH 290/447] Flesh out sections about crashes tests and update mentions of glacier --- src/fuzzing.md | 22 ++++++++++++++++------ src/getting-started.md | 2 +- src/tests/compiletest.md | 13 +++++++++---- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/fuzzing.md b/src/fuzzing.md index b588ca104..66c50ce25 100644 --- a/src/fuzzing.md +++ b/src/fuzzing.md @@ -74,20 +74,31 @@ To build a corpus, you may want to use: - The rustc/rust-analyzer/clippy test suites (or even source code) --- though avoid tests that are already known to cause failures, which often begin with comments like `// failure-status: 101` or `// known-bug: #NNN`. -- The already-fixed ICEs in [Glacier][glacier] --- though avoid the unfixed - ones in `ices/`! +- The already-fixed ICEs in the archived [Glacier][glacier] repository --- though + avoid the unfixed ones in `ices/`! + +[glacier]: https://github.com/rust-lang/glacier ## Extra credit Here are a few things you can do to help the Rust project after filing an ICE. -- [Bisect][bisect] the bug to figure out when it was introduced +- [Bisect][bisect] the bug to figure out when it was introduced. + If you find the regressing PR / commit, you can mark the issue with the label + `S-has-bisection`. If not, consider applying `E-needs-bisection` instead. - Fix "distractions": problems with the test case that don't contribute to triggering the ICE, such as syntax errors or borrow-checking errors -- Minimize the test case (see below) -- Add the minimal test case to [Glacier][glacier] +- Minimize the test case (see below). If successful, you can label the + issue with `S-has-mcve`. Otherwise, you can apply `E-needs-mcve`. +- Add the minimal test case to the rust-lang/rust repo as a [crashes test]. + While you're at it, consider including other "untracked" crashes in your PR. + Please don't forget to mark your issue with `S-bug-has-test` afterwards. + +See also [applying and removing labels][labeling]. [bisect]: https://rust-lang.github.io/cargo-bisect-rustc/ +[crashes test]: tests/compiletest.html#crashes-tests +[labeling]: https://forge.rust-lang.org/release/issue-triaging.html#applying-and-removing-labels ## Minimization @@ -143,7 +154,6 @@ ICEs that require debug assertions to reproduce should be tagged - [tree-splicer][tree-splicer] generates new source files by combining existing ones while maintaining correct syntax -[glacier]: https://github.com/rust-lang/glacier [fuzz-rustc]: https://github.com/dwrensha/fuzz-rustc [icemaker]: https://github.com/matthiaskrgr/icemaker/ [tree-splicer]: https://github.com/langston-barrett/tree-splicer/ diff --git a/src/getting-started.md b/src/getting-started.md index 0e5b32a06..4ee269263 100644 --- a/src/getting-started.md +++ b/src/getting-started.md @@ -89,7 +89,7 @@ filtering the search to areas you're interested in. For example: Not all important or beginner work has issue labels. See below for how to find work that isn't labelled. -[help-wanted-search]: https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Arust-lang+no%3Aassignee+label%3AE-easy%2C%22good+first+issue%22%2Cgood-first-issue%2CE-medium%2CEasy%2CE-help-wanted%2CE-mentor+-label%3AS-blocked+-linked:pr+ +[help-wanted-search]: https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Arust-lang+no%3Aassignee+label%3AE-easy%2C%22good+first+issue%22%2Cgood-first-issue%2CE-medium%2CEasy%2CE-help-wanted%2CE-mentor+-label%3AS-blocked+-linked%3Apr+ [Triage]: ./contributing.md#issue-triage ### Recurring work diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index 50982f3bb..b68ec036d 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -546,7 +546,7 @@ only running the main `coverage` suite. [`tests/crashes`] serve as a collection of tests that are expected to cause the compiler to ICE, panic or crash in some other way, so that accidental fixes are -tracked. This was formally done at but +tracked. Formerly, this was done at but doing it inside the rust-lang/rust testsuite is more convenient. It is imperative that a test in the suite causes rustc to ICE, panic, or @@ -560,9 +560,12 @@ If you want to see verbose stdout/stderr, you need to set $ COMPILETEST_VERBOSE_CRASHES=1 ./x test tests/crashes/999999.rs --stage 1 ``` -When adding crashes from , the issue -number should be noted in the file name (`12345.rs` should suffice) and also -inside the file include a `//@ known-bug: #4321` directive. +Anyone can add ["untracked" crashes] from the issue tracker. It's strongly +recommended to include test cases from several issues in a single PR. +When you do so, each issue number should be noted in the file name (`12345.rs` +should suffice) and also inside the file by means of a `//@ known-bug: #12345` +directive. Please [label][labeling] the relevant issues with `S-bug-has-test` +afterwards. If you happen to fix one of the crashes, please move it to a fitting subdirectory in `tests/ui` and give it a meaningful name. Please add a doc @@ -585,6 +588,8 @@ a subset first. The issue numbers can be found in the file name or the `//@ known-bug` directive inside the test file. [`tests/crashes`]: https://github.com/rust-lang/rust/tree/master/tests/crashes +["untracked" crashes]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+state%3Aopen+label%3AI-ICE%2CI-crash+label%3AT-compiler+label%3AS-has-mcve+-label%3AS-bug-has-test +[labeling]: https://forge.rust-lang.org/release/issue-triaging.html#applying-and-removing-labels ## Building auxiliary crates From a863290b9a1c6d1ed20cea867831c09b3a370e4f Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Mon, 26 May 2025 15:39:25 +0300 Subject: [PATCH 291/447] Link normalization chapter --- src/typing_parameter_envs.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/typing_parameter_envs.md b/src/typing_parameter_envs.md index a8f405982..e21bc5155 100644 --- a/src/typing_parameter_envs.md +++ b/src/typing_parameter_envs.md @@ -32,7 +32,7 @@ where ::Assoc: Clone, {} ``` -If we were conceptually inside of `foo` (for example, type-checking or linting it) we would use this `ParamEnv` everywhere that we interact with the type system. This would allow things such as normalization (TODO: write a chapter about normalization and link it), evaluating generic constants, and proving where clauses/goals, to rely on `T` being sized, implementing `Trait`, etc. +If we were conceptually inside of `foo` (for example, type-checking or linting it) we would use this `ParamEnv` everywhere that we interact with the type system. This would allow things such as [normalization], evaluating generic constants, and proving where clauses/goals, to rely on `T` being sized, implementing `Trait`, etc. A more concrete example: ```rust @@ -70,6 +70,7 @@ fn foo2(a: T) { [predicates_of]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/collect/predicates_of/fn.predicates_of.html [method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html [query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env +[normalization]: normalization.md ### Acquiring a `ParamEnv` From 03a857ec7902c9e17b96a7e32a9c2e47b3ee7e35 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Fri, 23 May 2025 18:28:40 +0300 Subject: [PATCH 292/447] Add time reference and tracking info for trait system refactor --- src/normalization.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/normalization.md b/src/normalization.md index ef530ccc5..9705b1a24 100644 --- a/src/normalization.md +++ b/src/normalization.md @@ -166,7 +166,10 @@ In this example: When interfacing with the type system it will often be the case that it's necessary to request a type be normalized. There are a number of different entry points to the underlying normalization logic and each entry point should only be used in specific parts of the compiler. -An additional complication is that the compiler is currently undergoing a transition from the old trait solver to the new trait solver. As part of this transition our approach to normalization in the compiler has changed somewhat significantly, resulting in some normalization entry points being "old solver only" slated for removal in the long-term once the new solver has stabilized. + +An additional complication is that the compiler is currently undergoing a transition from the old trait solver to the new trait solver. +As part of this transition our approach to normalization in the compiler has changed somewhat significantly, resulting in some normalization entry points being "old solver only" slated for removal in the long-term once the new solver has stabilized. +The transition can be tracked via the [WG-trait-system-refactor](https://github.com/rust-lang/rust/labels/WG-trait-system-refactor) label in Github. Here is a rough overview of the different entry points to normalization in the compiler: - `infcx.at.structurally_normalize` @@ -306,4 +309,4 @@ Const aliases differ from type aliases a bit here; well formedness of const alia [^5]: Const aliases certainly wouldn't be *less* sound than type aliases if we stopped doing this -[const_evaluatable]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ClauseKind.html#variant.ConstEvaluatable \ No newline at end of file +[const_evaluatable]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ClauseKind.html#variant.ConstEvaluatable From 482f61ad8587dd52227527fa51cd4f3cc9714063 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Mon, 26 May 2025 20:56:14 +0100 Subject: [PATCH 293/447] Remove rustdoc askama migration from getting started This effort is blocked, so pointing new contributors here would be setting them up for failure. https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/about.3A.20status.20of.20askama.20migration/with/497389045 --- src/getting-started.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/getting-started.md b/src/getting-started.md index 4ee269263..a330c2a52 100644 --- a/src/getting-started.md +++ b/src/getting-started.md @@ -98,7 +98,6 @@ Some work is too large to be done by a single person. In this case, it's common issues" to co-ordinate the work between contributors. Here are some example tracking issues where it's easy to pick up work without a large time commitment: -- [Rustdoc Askama Migration](https://github.com/rust-lang/rust/issues/108868) - [Diagnostic Translation](https://github.com/rust-lang/rust/issues/100717) - [Move UI tests to subdirectories](https://github.com/rust-lang/rust/issues/73494) From d90b7d7ac1cb2362d98f1d2a1c55090dd5ce9bed Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 26 May 2025 22:09:35 +0200 Subject: [PATCH 294/447] diagnostic translations work is on pause --- src/getting-started.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/getting-started.md b/src/getting-started.md index a330c2a52..435202ca6 100644 --- a/src/getting-started.md +++ b/src/getting-started.md @@ -98,7 +98,6 @@ Some work is too large to be done by a single person. In this case, it's common issues" to co-ordinate the work between contributors. Here are some example tracking issues where it's easy to pick up work without a large time commitment: -- [Diagnostic Translation](https://github.com/rust-lang/rust/issues/100717) - [Move UI tests to subdirectories](https://github.com/rust-lang/rust/issues/73494) If you find more recurring work, please feel free to add it here! From 01f8aee93bb2c14af2ce8a1d08e5ee433a192d10 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Tue, 27 May 2025 18:47:35 +0300 Subject: [PATCH 295/447] Link to description of opaque types --- src/solve/opaque-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solve/opaque-types.md b/src/solve/opaque-types.md index 509c34a4d..1136e7a45 100644 --- a/src/solve/opaque-types.md +++ b/src/solve/opaque-types.md @@ -1,6 +1,6 @@ # Opaque types in the new solver -The way opaque types are handled in the new solver differs from the old implementation. +The way [opaque types](../opaque-types-type-alias-impl-trait.md) are handled in the new solver differs from the old implementation. This should be a self-contained explanation of the behavior in the new solver. ## opaques are alias types From e93a924d196e2ed001fb60386758884bc9d1f0f5 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Tue, 27 May 2025 17:43:51 +0300 Subject: [PATCH 296/447] Make links in coinduction.md clickable Although they are clickable in the github preview, they aren't in the actual rendered HTML on https://rustc-dev-guide.rust-lang.org/. This commit fixes that. --- src/solve/coinduction.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solve/coinduction.md b/src/solve/coinduction.md index c682e002d..9753f7539 100644 --- a/src/solve/coinduction.md +++ b/src/solve/coinduction.md @@ -237,14 +237,14 @@ Alternatively, we could simply always treat the equate branch of `normalizes_to` Any cycles should result in infinite types, which aren't supported anyways and would only result in overflow when deeply normalizing for codegen. -experimentation and examples: https://hackmd.io/-8p0AHnzSq2VAE6HE_wX-w?view +experimentation and examples: Another attempt at a summary. - in projection eq, we must make progress with constraining the rhs - a cycle is only ok if while equating we have a rigid ty on the lhs after norm at least once - cycles outside of the recursive `eq` call of `normalizes_to` are always fine -[^1]: related: https://coq.inria.fr/refman/language/core/coinductive.html#top-level-definitions-of-corecursive-functions +[^1]: related: [perfect derive]: https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive [ex1]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0a9c3830b93a2380e6978d6328df8f72 From 6da83f69ceffa602b05d395acd4206aab4c56c4a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 27 May 2025 21:21:18 +0200 Subject: [PATCH 297/447] make link not inline --- src/solve/opaque-types.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/solve/opaque-types.md b/src/solve/opaque-types.md index 1136e7a45..6898ef3aa 100644 --- a/src/solve/opaque-types.md +++ b/src/solve/opaque-types.md @@ -1,8 +1,10 @@ # Opaque types in the new solver -The way [opaque types](../opaque-types-type-alias-impl-trait.md) are handled in the new solver differs from the old implementation. +The way [opaque types] are handled in the new solver differs from the old implementation. This should be a self-contained explanation of the behavior in the new solver. +[opaque types]: ../opaque-types-type-alias-impl-trait.md + ## opaques are alias types Opaque types are treated the same as other aliases, most notabily associated types, From fa22636979f4d857987645174165b06996edf8ae Mon Sep 17 00:00:00 2001 From: David Klank <155117116+davidjsonn@users.noreply.github.com> Date: Wed, 28 May 2025 13:50:38 +0300 Subject: [PATCH 298/447] replace TraitRef link memory.md --- src/memory.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/memory.md b/src/memory.md index eeb4a8139..f766a5189 100644 --- a/src/memory.md +++ b/src/memory.md @@ -63,7 +63,7 @@ represented as a slice `&'tcx [tcx.types.i32, tcx.types.u32]`). [`mk_args`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.mk_args [adtdefid]: ./ty_module/generic_arguments.md#adtdef-and-defid [`Predicate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Predicate.html -[`TraitRef`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TraitRef.html +[`TraitRef`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.TraitRef.html [`ty::TyKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/sty/type.TyKind.html [traits]: ./traits/resolution.md From 812a949c111f555ae286800577a820b97cc3b6ce Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 28 May 2025 20:18:56 +0100 Subject: [PATCH 299/447] directives.md: Fix `//@ build_aux_docs` -> `//@ build-aux-docs` --- src/tests/directives.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index dae659e63..8a862417b 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -59,7 +59,7 @@ not be exhaustive. Directives can generally be found by browsing the | `aux-crate` | Like `aux-build` but makes available as extern prelude | All except `run-make` | `=` | | `aux-codegen-backend` | Similar to `aux-build` but pass the compiled dylib to `-Zcodegen-backend` when building the main file | `ui-fulldeps` | Path to codegen backend file | | `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 | All except `run-make` | N/A | +| `build-aux-docs` | Build docs for auxiliaries as well | All except `run-make` | N/A | [^pm]: please see the Auxiliary proc-macro section in the [compiletest](./compiletest.md) chapter for specifics. From 655367d8b8af4ab51e0f72d0508c8888cd804f0f Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 28 May 2025 20:32:56 +0100 Subject: [PATCH 300/447] Fix some old `// ` to `//@ ` --- src/fuzzing.md | 2 +- src/rustdoc-internals.md | 4 ++-- src/tests/compiletest.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fuzzing.md b/src/fuzzing.md index 66c50ce25..300053786 100644 --- a/src/fuzzing.md +++ b/src/fuzzing.md @@ -73,7 +73,7 @@ To build a corpus, you may want to use: - The rustc/rust-analyzer/clippy test suites (or even source code) --- though avoid tests that are already known to cause failures, which often begin with comments - like `// failure-status: 101` or `// known-bug: #NNN`. + like `//@ failure-status: 101` or `//@ known-bug: #NNN`. - The already-fixed ICEs in the archived [Glacier][glacier] repository --- though avoid the unfixed ones in `ices/`! diff --git a/src/rustdoc-internals.md b/src/rustdoc-internals.md index 80421b85b..bc91c62d8 100644 --- a/src/rustdoc-internals.md +++ b/src/rustdoc-internals.md @@ -281,10 +281,10 @@ using `XPath` notation to get a precise look at the output. The full description of all the commands available to `rustdoc` tests (e.g. [`@has`] and [`@matches`]) is in [`htmldocck.py`]. -To use multiple crates in a `rustdoc` test, add `// aux-build:filename.rs` +To use multiple crates in a `rustdoc` test, add `//@ aux-build:filename.rs` to the top of the test file. `filename.rs` should be placed in an `auxiliary` directory relative to the test file with the comment. If you need to build -docs for the auxiliary file, use `// build-aux-docs`. +docs for the auxiliary file, use `//@ build-aux-docs`. In addition, there are separate tests for the search index and `rustdoc`'s ability to query it. The files in `tests/rustdoc-js` each contain a diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index b68ec036d..e1b23748d 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -619,7 +619,7 @@ file). The `-L` flag is used to find the extern crates. `aux-crate` is very similar to `aux-build`. However, it uses the `--extern` flag to link to the extern crate to make the crate be available as an extern prelude. That allows you to specify the additional syntax of the `--extern` flag, such as -renaming a dependency. For example, `// aux-crate:foo=bar.rs` will compile +renaming a dependency. For example, `//@ aux-crate:foo=bar.rs` will compile `auxiliary/bar.rs` and make it available under then name `foo` within the test. This is similar to how Cargo does dependency renaming. From 531ef6c61098702060095cd020cbe4676b17f1f6 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 29 May 2025 16:12:35 +0800 Subject: [PATCH 301/447] triagebot: adjust `allow-unauthenticated` labels --- triagebot.toml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 53fa72469..2af55c70f 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -2,9 +2,20 @@ [relabel] allow-unauthenticated = [ - "waiting-on-review", - "waiting-on-author", - "blocked", + "-Z*", + "A-*", + "C-*", + "D-*", + "E-*", + "F-*", + "I-*", + "L-*", + "O-*", + "PG-*", + "S-*", + "T-*", + "WG-*", + "needs-triage", ] [no-mentions] @@ -15,4 +26,4 @@ allow-unauthenticated = [ [bot-pull-requests] [behind-upstream] -days-threshold = 7 \ No newline at end of file +days-threshold = 7 From 6f298ff4b7c43bf480b74b7e5ace23cd26318b7a Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 29 May 2025 16:13:03 +0800 Subject: [PATCH 302/447] triagebot: apply `needs-triage` label for new issues --- triagebot.toml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 2af55c70f..53038aece 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1,5 +1,15 @@ +# This file's format is documented at +# https://forge.rust-lang.org/triagebot/pr-assignment.html#configuration + [assign] +[autolabel."needs-triage"] +new_issue = true +exclude_labels = [ + "A-diagnostics", + "C-tracking-issue", +] + [relabel] allow-unauthenticated = [ "-Z*", From 7485ed7fbc92253065c9a348c8997830d4558eac Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 29 May 2025 16:15:04 +0800 Subject: [PATCH 303/447] triagebot: enable PR review status flipping and its shortcuts --- triagebot.toml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 53038aece..b33367664 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -10,6 +10,25 @@ exclude_labels = [ "C-tracking-issue", ] +[review-submitted] +# This label is added when a "request changes" review is submitted. +reviewed_label = "S-waiting-on-author" +# These labels are removed when a "request changes" review is submitted. +review_labels = ["S-waiting-on-review"] + +[review-requested] +# Those labels are removed when PR author requests a review from an assignee +remove_labels = ["S-waiting-on-author"] +# Those labels are added when PR author requests a review from an assignee +add_labels = ["S-waiting-on-review"] + +# Enable tracking of PR review assignment +# Documentation at: https://forge.rust-lang.org/triagebot/pr-assignment-tracking.html +[shortcut] + +[autolabel."S-waiting-on-review"] +new_pr = true + [relabel] allow-unauthenticated = [ "-Z*", From 77b0952142949915965883ff3fbd620bb18a3454 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 29 May 2025 16:17:25 +0800 Subject: [PATCH 304/447] triagebot: enable issue transfer --- triagebot.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index b33367664..c751c1eaf 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -29,6 +29,10 @@ add_labels = ["S-waiting-on-review"] [autolabel."S-waiting-on-review"] new_pr = true +# Enable issue transfers within the org +# Documentation at: https://forge.rust-lang.org/triagebot/transfer.html +[transfer] + [relabel] allow-unauthenticated = [ "-Z*", From 604343a24e8e849e47c431fdb19820b22fd00786 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 29 May 2025 16:17:52 +0800 Subject: [PATCH 305/447] triagebot: enable note functionality --- triagebot.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index c751c1eaf..480b33b86 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -51,6 +51,10 @@ allow-unauthenticated = [ "needs-triage", ] +# Enable `@rustbot note` functionality +# Documentation at: https://forge.rust-lang.org/triagebot/note.html +[note] + [no-mentions] [canonicalize-issue-links] From 02088e77916d805611caa627a8960652d16045a6 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 29 May 2025 16:18:59 +0800 Subject: [PATCH 306/447] triagebot: add doc backlink for `[no-mentions]` --- triagebot.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 480b33b86..56fab16a0 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -55,6 +55,8 @@ allow-unauthenticated = [ # Documentation at: https://forge.rust-lang.org/triagebot/note.html [note] +# Prevents mentions in commits to avoid users being spammed +# Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html [no-mentions] [canonicalize-issue-links] From afb57b1f0662a08ec5911d6b6e0bea967438b06c Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 29 May 2025 16:19:13 +0800 Subject: [PATCH 307/447] triagebot: update `[issue-links]` config --- triagebot.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 56fab16a0..d67ecbcc7 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -59,7 +59,10 @@ allow-unauthenticated = [ # Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html [no-mentions] -[canonicalize-issue-links] +# Canonicalize issue numbers to avoid closing the wrong issue +# when commits are included in subtrees, as well as warning links in commits. +# 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] From 19a333ad0fe9a892ea221aff6bb660524c777233 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 14 Mar 2025 23:08:21 +0300 Subject: [PATCH 308/447] split `mingw-check` into two Signed-off-by: onur-ozkan --- src/tests/ci.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/ci.md b/src/tests/ci.md index 825be11c8..d1bd6ac91 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -66,8 +66,8 @@ kinds of builds (sets of jobs). ### Pull Request builds After each push to a pull request, a set of `pr` jobs are executed. Currently, -these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `mingw-check` and -`mingw-check-tidy` jobs, all running on Linux. These execute a relatively short +these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `mingw-check-1`, `mingw-check-2` +and `mingw-check-tidy` jobs, all running on Linux. These execute a relatively short (~30 minutes) and lightweight test suite that should catch common issues. More specifically, they run a set of lints, they try to perform a cross-compile check build to Windows mingw (without producing any artifacts) and they test the From 09eb3b3f783db3a7d440582264c95ef8da66d533 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 14 Mar 2025 08:59:23 +0300 Subject: [PATCH 309/447] update dev guidelines Signed-off-by: onur-ozkan --- .../bootstrapping/what-bootstrapping-does.md | 86 ++++++++----------- src/building/how-to-build-and-run.md | 14 ++- src/tests/ci.md | 2 +- 3 files changed, 41 insertions(+), 61 deletions(-) diff --git a/src/building/bootstrapping/what-bootstrapping-does.md b/src/building/bootstrapping/what-bootstrapping-does.md index a2930b3e4..e5d1cd8f1 100644 --- a/src/building/bootstrapping/what-bootstrapping-does.md +++ b/src/building/bootstrapping/what-bootstrapping-does.md @@ -45,13 +45,13 @@ compiler. ```mermaid graph TD - s0c["stage0 compiler (1.63)"]:::downloaded -->|A| s0l("stage0 std (1.64)"):::with-s0c; + s0c["stage0 compiler (1.86.0-beta.1)"]:::downloaded -->|A| s0l("stage0 std (1.86.0-beta.1)"):::downloaded; s0c & s0l --- stepb[ ]:::empty; - stepb -->|B| s0ca["stage0 compiler artifacts (1.64)"]:::with-s0c; - s0ca -->|copy| s1c["stage1 compiler (1.64)"]:::with-s0c; - s1c -->|C| s1l("stage1 std (1.64)"):::with-s1c; + stepb -->|B| s0ca["stage0 compiler artifacts (1.87.0-dev)"]:::with-s0c; + s0ca -->|copy| s1c["stage1 compiler (1.87.0-dev)"]:::with-s0c; + s1c -->|C| s1l("stage1 std (1.87.0-dev)"):::with-s1c; s1c & s1l --- stepd[ ]:::empty; - stepd -->|D| s1ca["stage1 compiler artifacts (1.64)"]:::with-s1c; + stepd -->|D| s1ca["stage1 compiler artifacts (1.87.0-dev)"]:::with-s1c; s1ca -->|copy| s2c["stage2 compiler"]:::with-s1c; classDef empty width:0px,height:0px; @@ -62,19 +62,22 @@ graph TD ### Stage 0: the pre-compiled compiler -The stage0 compiler is usually the current _beta_ `rustc` compiler and its +The stage0 compiler is by default the very recent _beta_ `rustc` compiler and its associated dynamic libraries, which `./x.py` will download for you. (You can -also configure `./x.py` to use something else.) +also configure `./x.py` to change stage0 to something else.) -The stage0 compiler is then used only to compile [`src/bootstrap`], -[`library/std`], and [`compiler/rustc`]. When assembling the libraries and -binaries that will become the stage1 `rustc` compiler, the freshly compiled -`std` and `rustc` are used. There are two concepts at play here: a compiler -(with its set of dependencies) and its 'target' or 'object' libraries (`std` and -`rustc`). Both are staged, but in a staggered manner. +The stage0 compiler is then used only to compile [`src/bootstrap`] and [`compiler/rustc`]. +When assembling the libraries and binaries that will become the stage1 `rustc` compiler, +the freshly compiled `rustc` and beta `std` are used. + +Note that to build the stage1 compiler we use the precompiled beta compiler and beta std from stage0. +Therefore, to use a compiler with a std that is freshly built from the tree, you need to build the +stage2 compiler. + +There are two concepts at play here: a compiler (with its set of dependencies) and its +'target' or 'object' libraries (`std` and `rustc`). Both are staged, but in a staggered manner. [`compiler/rustc`]: https://github.com/rust-lang/rust/tree/master/compiler/rustc -[`library/std`]: https://github.com/rust-lang/rust/tree/master/library/std [`src/bootstrap`]: https://github.com/rust-lang/rust/tree/master/src/bootstrap ### Stage 1: from current code, by an earlier compiler @@ -84,16 +87,14 @@ The rustc source code is then compiled with the `stage0` compiler to produce the ### Stage 2: the truly current compiler -We then rebuild our `stage1` compiler with itself to produce the `stage2` +We then rebuild our `stage1` compiler with in-tree std to produce the `stage2` compiler. -In theory, the `stage1` compiler is functionally identical to the `stage2` -compiler, but in practice there are subtle differences. In particular, the -`stage1` compiler itself was built by `stage0` and hence not by the source in -your working directory. This means that the ABI generated by the `stage0` -compiler may not match the ABI that would have been made by the `stage1` -compiler, which can cause problems for dynamic libraries, tests, and tools using -`rustc_private`. +The `stage1` compiler itself was built by precompiled `stage0` compiler and std +and hence not by the source in your working directory. This means that the ABI +generated by the `stage0` compiler may not match the ABI that would have been made +by the `stage1` compiler, which can cause problems for dynamic libraries, tests +and tools using `rustc_private`. Note that the `proc_macro` crate avoids this issue with a `C` FFI layer called `proc_macro::bridge`, allowing it to be used with `stage1`. @@ -101,9 +102,10 @@ Note that the `proc_macro` crate avoids this issue with a `C` FFI layer called The `stage2` compiler is the one distributed with `rustup` and all other install methods. However, it takes a very long time to build because one must first build the new compiler with an older compiler and then use that to build the new -compiler with itself. For development, you usually only want the `stage1` -compiler, which you can build with `./x build library`. See [Building the -compiler](../how-to-build-and-run.html#building-the-compiler). +compiler with itself. + +For development, you usually only want to use `--stage 1` flag to build things. +See [Building the compiler](../how-to-build-and-run.html#building-the-compiler). ### Stage 3: the same-result test @@ -114,10 +116,11 @@ something has broken. ### Building the stages The script [`./x`] tries to be helpful and pick the stage you most likely meant -for each subcommand. These defaults are as follows: +for each subcommand. Here are some `x` commands with their default stages: -- `check`: `--stage 0` -- `doc`: `--stage 0` +- `check`: `--stage 1` +- `clippy`: `--stage 1` +- `doc`: `--stage 1` - `build`: `--stage 1` - `test`: `--stage 1` - `dist`: `--stage 2` @@ -208,9 +211,6 @@ include, but are not limited to: ### Building vs. running -Note that `build --stage N compiler/rustc` **does not** build the stage N -compiler: instead it builds the stage N+1 compiler _using_ the stage N compiler. - In short, _stage 0 uses the `stage0` compiler to create `stage0` artifacts which will later be uplifted to be the stage1 compiler_. @@ -268,23 +268,6 @@ However, when cross-compiling, `stage1` `std` will only run on the host. So the (See in the table how `stage2` only builds non-host `std` targets). -### Why does only libstd use `cfg(bootstrap)`? - -For docs on `cfg(bootstrap)` itself, see [Complications of -Bootstrapping](#complications-of-bootstrapping). - -The `rustc` generated by the `stage0` compiler is linked to the freshly-built -`std`, which means that for the most part only `std` needs to be `cfg`-gated, so -that `rustc` can use features added to `std` immediately after their addition, -without need for them to get into the downloaded `beta` compiler. - -Note this is different from any other Rust program: `stage1` `rustc` is built by -the _beta_ compiler, but using the _master_ version of `libstd`! - -The only time `rustc` uses `cfg(bootstrap)` is when it adds internal lints that -use diagnostic items, or when it uses unstable library features that were -recently changed. - ### What is a 'sysroot'? When you build a project with `cargo`, the build artifacts for dependencies are @@ -459,7 +442,6 @@ compiler itself uses to run. These aren't actually used by artifacts the new compiler generates. This step also copies the `rustc` and `rustdoc` binaries we generated into `build/$HOST/stage/bin`. -The `stage1/bin/rustc` is a fully functional compiler, but it doesn't yet have -any libraries to link built binaries or libraries to. The next 3 steps will -provide those libraries for it; they are mostly equivalent to constructing the -`stage1/bin` compiler so we don't go through them individually here. +The `stage1/bin/rustc` is a fully functional compiler built with the beta compiler and std. +To use a compiler built entirely from source with the in-tree compiler and std, you need to build +the stage2 compiler, which is compiled using the stage1 compiler and std. diff --git a/src/building/how-to-build-and-run.md b/src/building/how-to-build-and-run.md index c3c1c41e3..a6e9d0b73 100644 --- a/src/building/how-to-build-and-run.md +++ b/src/building/how-to-build-and-run.md @@ -217,7 +217,6 @@ probably the best "go to" command for building a local compiler: This may *look* like it only builds the standard library, but that is not the case. What this command does is the following: -- Build `std` using the stage0 compiler - Build `rustc` using the stage0 compiler - This produces the stage1 compiler - Build `std` using the stage1 compiler @@ -241,8 +240,7 @@ build. The **full** `rustc` build (what you get with `./x build --stage 2 compiler/rustc`) has quite a few more steps: - Build `rustc` with the stage1 compiler. - - The resulting compiler here is called the "stage2" compiler. -- Build `std` with stage2 compiler. + - The resulting compiler here is called the "stage2" compiler, which uses stage1 std from the previous command. - Build `librustdoc` and a bunch of other things with the stage2 compiler. You almost never need to do this. @@ -250,14 +248,14 @@ You almost never need to do this. ### Build specific components If you are working on the standard library, you probably don't need to build -the compiler unless you are planning to use a recently added nightly feature. -Instead, you can just build using the bootstrap compiler. +every other default component. Instead, you can build a specific component by +providing its name, like this: ```bash -./x build --stage 0 library +./x build --stage 1 library ``` -If you choose the `library` profile when running `x setup`, you can omit `--stage 0` (it's the +If you choose the `library` profile when running `x setup`, you can omit `--stage 1` (it's the default). ## Creating a rustup toolchain @@ -271,7 +269,7 @@ you will likely need to build at some point; for example, if you want to run the entire test suite). ```bash -rustup toolchain link stage0 build/host/stage0-sysroot # beta compiler + stage0 std +rustup toolchain link stage0 build/host/stage0-sysroot # beta compiler + beta std rustup toolchain link stage1 build/host/stage1 rustup toolchain link stage2 build/host/stage2 ``` diff --git a/src/tests/ci.md b/src/tests/ci.md index d1bd6ac91..8f259f270 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -68,7 +68,7 @@ kinds of builds (sets of jobs). After each push to a pull request, a set of `pr` jobs are executed. Currently, these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `mingw-check-1`, `mingw-check-2` and `mingw-check-tidy` jobs, all running on Linux. These execute a relatively short -(~30 minutes) and lightweight test suite that should catch common issues. More +(~40 minutes) and lightweight test suite that should catch common issues. More specifically, they run a set of lints, they try to perform a cross-compile check build to Windows mingw (without producing any artifacts) and they test the compiler using a *system* version of LLVM. Unfortunately, it would take too many From 257e73f3a30d70ef51509733258b36948a903039 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 14 Mar 2025 23:19:55 +0300 Subject: [PATCH 310/447] improve comments and docs Signed-off-by: onur-ozkan --- .../bootstrapping/what-bootstrapping-does.md | 23 ++++---- src/building/how-to-build-and-run.md | 1 - src/building/new-target.md | 2 +- src/building/suggested.md | 54 ++++--------------- 4 files changed, 21 insertions(+), 59 deletions(-) diff --git a/src/building/bootstrapping/what-bootstrapping-does.md b/src/building/bootstrapping/what-bootstrapping-does.md index e5d1cd8f1..2793ad438 100644 --- a/src/building/bootstrapping/what-bootstrapping-does.md +++ b/src/building/bootstrapping/what-bootstrapping-does.md @@ -66,13 +66,12 @@ The stage0 compiler is by default the very recent _beta_ `rustc` compiler and it associated dynamic libraries, which `./x.py` will download for you. (You can also configure `./x.py` to change stage0 to something else.) -The stage0 compiler is then used only to compile [`src/bootstrap`] and [`compiler/rustc`]. -When assembling the libraries and binaries that will become the stage1 `rustc` compiler, -the freshly compiled `rustc` and beta `std` are used. +The precompiled stage0 compiler is then used only to compile [`src/bootstrap`] and [`compiler/rustc`] +with precompiled stage0 std. -Note that to build the stage1 compiler we use the precompiled beta compiler and beta std from stage0. -Therefore, to use a compiler with a std that is freshly built from the tree, you need to build the -stage2 compiler. +Note that to build the stage1 compiler we use the precompiled stage0 compiler and std. +Therefore, to use a compiler with a std that is freshly built from the tree, you need to +build the stage2 compiler. There are two concepts at play here: a compiler (with its set of dependencies) and its 'target' or 'object' libraries (`std` and `rustc`). Both are staged, but in a staggered manner. @@ -87,7 +86,7 @@ The rustc source code is then compiled with the `stage0` compiler to produce the ### Stage 2: the truly current compiler -We then rebuild our `stage1` compiler with in-tree std to produce the `stage2` +We then rebuild the compiler using `stage1` compiler with in-tree std to produce the `stage2` compiler. The `stage1` compiler itself was built by precompiled `stage0` compiler and std @@ -194,8 +193,8 @@ include, but are not limited to: without building `rustc` from source ('build with `stage0`, then test the artifacts'). If you're working on the standard library, this is normally the test command you want. -- `./x build --stage 0` means to build with the beta `rustc`. -- `./x doc --stage 0` means to document using the beta `rustdoc`. +- `./x build --stage 0` means to build with the stage0 `rustc`. +- `./x doc --stage 0` means to document using the stage0 `rustdoc`. #### Examples of what *not* to do @@ -442,6 +441,6 @@ compiler itself uses to run. These aren't actually used by artifacts the new compiler generates. This step also copies the `rustc` and `rustdoc` binaries we generated into `build/$HOST/stage/bin`. -The `stage1/bin/rustc` is a fully functional compiler built with the beta compiler and std. -To use a compiler built entirely from source with the in-tree compiler and std, you need to build -the stage2 compiler, which is compiled using the stage1 compiler and std. +The `stage1/bin/rustc` is a fully functional compiler built with stage0 (precompiled) compiler and std. +To use a compiler built entirely from source with the in-tree compiler and std, you need to build the +stage2 compiler, which is compiled using the stage1 (in-tree) compiler and std. diff --git a/src/building/how-to-build-and-run.md b/src/building/how-to-build-and-run.md index a6e9d0b73..c4783002b 100644 --- a/src/building/how-to-build-and-run.md +++ b/src/building/how-to-build-and-run.md @@ -269,7 +269,6 @@ you will likely need to build at some point; for example, if you want to run the entire test suite). ```bash -rustup toolchain link stage0 build/host/stage0-sysroot # beta compiler + beta std rustup toolchain link stage1 build/host/stage1 rustup toolchain link stage2 build/host/stage2 ``` diff --git a/src/building/new-target.md b/src/building/new-target.md index 09ffbe8c8..8d323ba96 100644 --- a/src/building/new-target.md +++ b/src/building/new-target.md @@ -85,7 +85,7 @@ Look for existing targets to use as examples. After adding your target to the `rustc_target` crate you may want to add `core`, `std`, ... with support for your new target. In that case you will probably need access to some `target_*` cfg. Unfortunately when building with -stage0 (the beta compiler), you'll get an error that the target cfg is +stage0 (a precompiled compiler), you'll get an error that the target cfg is unexpected because stage0 doesn't know about the new target specification and we pass `--check-cfg` in order to tell it to check. diff --git a/src/building/suggested.md b/src/building/suggested.md index f8a28b7f2..333554c8a 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -310,51 +310,15 @@ lets you use `cargo fmt`. [the section on vscode]: suggested.md#configuring-rust-analyzer-for-rustc [the section on rustup]: how-to-build-and-run.md?highlight=rustup#creating-a-rustup-toolchain -## Faster builds with `--keep-stage`. - -Sometimes just checking whether the compiler builds is not enough. A common -example is that you need to add a `debug!` statement to inspect the value of -some state or better understand the problem. In that case, you don't really need -a full build. By bypassing bootstrap's cache invalidation, you can often get -these builds to complete very fast (e.g., around 30 seconds). The only catch is -this requires a bit of fudging and may produce compilers that don't work (but -that is easily detected and fixed). - -The sequence of commands you want is as follows: - -- Initial build: `./x build library` - - As [documented previously], this will build a functional stage1 compiler as - part of running all stage0 commands (which include building a `std` - compatible with the stage1 compiler) as well as the first few steps of the - "stage 1 actions" up to "stage1 (sysroot stage1) builds std". -- Subsequent builds: `./x build library --keep-stage 1` - - Note that we added the `--keep-stage 1` flag here - -[documented previously]: ./how-to-build-and-run.md#building-the-compiler - -As mentioned, the effect of `--keep-stage 1` is that we just _assume_ that the -old standard library can be re-used. If you are editing the compiler, this is -almost always true: you haven't changed the standard library, after all. But -sometimes, it's not true: for example, if you are editing the "metadata" part of -the compiler, which controls how the compiler encodes types and other states -into the `rlib` files, or if you are editing things that wind up in the metadata -(such as the definition of the MIR). - -**The TL;DR is that you might get weird behavior from a compile when using -`--keep-stage 1`** -- for example, strange [ICEs](../appendix/glossary.html#ice) -or other panics. In that case, you should simply remove the `--keep-stage 1` -from the command and rebuild. That ought to fix the problem. - -You can also use `--keep-stage 1` when running tests. Something like this: - -- Initial test run: `./x test tests/ui` -- Subsequent test run: `./x test tests/ui --keep-stage 1` - -### Iterating the standard library with `--keep-stage` - -If you are making changes to the standard library, you can use `./x build ---keep-stage 0 library` to iteratively rebuild the standard library without -rebuilding the compiler. +## Faster Builds with CI-rustc + +If you are not working on the compiler, you often don't need to build the compiler tree. +For example, you can skip building the compiler and only build the `library` tree or the +tools under `src/tools`. To achieve that, you have to enable this by setting the `download-rustc` +option in your configuration. This tells bootstrap to use the latest nightly compiler for `stage > 0` +steps, meaning it will have two precompiled compilers: stage0 compiler and `download-rustc` compiler +for `stage > 0` steps. This way, it will never need to build the in-tree compiler. As a result, your +build time will be significantly reduced by not building the in-tree compiler. ## Using incremental compilation From acb7ffd277cf7970cfb8927b1fcf1bf40af80aac Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sat, 31 May 2025 23:21:43 +0800 Subject: [PATCH 311/447] triagebot: fix incorrect link --- triagebot.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index d67ecbcc7..a51e017d6 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -22,8 +22,8 @@ remove_labels = ["S-waiting-on-author"] # Those labels are added when PR author requests a review from an assignee add_labels = ["S-waiting-on-review"] -# Enable tracking of PR review assignment -# Documentation at: https://forge.rust-lang.org/triagebot/pr-assignment-tracking.html +# Enable shortcuts like `@rustbot ready` +# Documentation at: https://forge.rust-lang.org/triagebot/shortcuts.html [shortcut] [autolabel."S-waiting-on-review"] From ae46731db63994642b3ac0310607038f403235b5 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sat, 31 May 2025 23:26:32 +0800 Subject: [PATCH 312/447] triagebot: setup `rustc-dev-guide` adhoc-group So that PR authors can opt-in to request review via `r? rustc-dev-guide`. --- triagebot.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index a51e017d6..f08a2f8af 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -69,3 +69,12 @@ allow-unauthenticated = [ [behind-upstream] days-threshold = 7 + +# Keep members alphanumerically sorted. +[assign.adhoc_groups] +rustc-dev-guide = [ + "@BoxyUwU", + "@jieyouxu", + "@jyn514", + "@tshepang", +] From b2077fb2f10fda30e79ab1381a11542ed33408b5 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sat, 31 May 2025 23:48:47 +0800 Subject: [PATCH 313/447] triagebot: add doc link to `[assign]` --- triagebot.toml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index f08a2f8af..978802edf 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1,8 +1,6 @@ # This file's format is documented at # https://forge.rust-lang.org/triagebot/pr-assignment.html#configuration -[assign] - [autolabel."needs-triage"] new_issue = true exclude_labels = [ @@ -70,6 +68,10 @@ allow-unauthenticated = [ [behind-upstream] days-threshold = 7 +# Enable triagebot (PR) assignment. +# Documentation at: https://forge.rust-lang.org/triagebot/pr-assignment.html +[assign] + # Keep members alphanumerically sorted. [assign.adhoc_groups] rustc-dev-guide = [ From eabc3827339f517f217bf7d0bb5be9e9e2ed081c Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 31 May 2025 22:21:04 +0200 Subject: [PATCH 314/447] suggest build/rust-analyzer instead of build-rust-analyzer This is better because - `./x clean` also removes it, without needing extra text to explain it - Does not need an extra .gitignore entry --- src/building/suggested.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/building/suggested.md b/src/building/suggested.md index f8a28b7f2..ff7e40770 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -91,7 +91,7 @@ for two reasons: additional rebuilds in some cases. To avoid these problems: -- Add `--build-dir=build-rust-analyzer` to all of the custom `x` commands in +- Add `--build-dir=build/rust-analyzer` to all of the custom `x` commands in your editor's rust-analyzer configuration. (Feel free to choose a different directory name if desired.) - Modify the `rust-analyzer.rustfmt.overrideCommand` setting so that it points @@ -100,10 +100,7 @@ To avoid these problems: copy of `rust-analyzer-proc-macro-srv` in that other build directory. Using separate build directories for command-line builds and rust-analyzer -requires extra disk space, and also means that running `./x clean` on the -command-line will not clean out the separate build directory. To clean the -separate build directory, run `./x clean --build-dir=build-rust-analyzer` -instead. +requires extra disk space. ### Visual Studio Code From 8cf3cc09b908f90d1e93cdd360bcd2f9cbbf3c6b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 31 May 2025 22:30:00 +0200 Subject: [PATCH 315/447] replace a broken sentence --- src/building/suggested.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/building/suggested.md b/src/building/suggested.md index f8a28b7f2..842a5d08b 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -137,7 +137,7 @@ Task] instead: ### Neovim -For Neovim users there are several options for configuring for rustc. The +For Neovim users, there are a few options. The easiest way is by using [neoconf.nvim](https://github.com/folke/neoconf.nvim/), which allows for project-local configuration files with the native LSP. The steps for how to use it are below. Note that they require rust-analyzer to From e59e6bfcaf0b897372e0b5a1d366e1c3babdf3d5 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 31 May 2025 23:06:14 +0200 Subject: [PATCH 316/447] update surname (was lekhonkhobe previously) and email --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 1a1f6ffb6..907495ed1 100644 --- a/.mailmap +++ b/.mailmap @@ -3,3 +3,4 @@ Jynn Nelson Jynn Nelson Jynn Nelson Jynn Nelson +Tshepang Mbambo From f267718a7852722498a6aa01a0a53cff1fc05e0e Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Sun, 1 Jun 2025 10:36:28 +0300 Subject: [PATCH 317/447] Add opaque type attributes This allows for the code to compile on `nightly`. --- src/opaque-types-impl-trait-inference.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/opaque-types-impl-trait-inference.md b/src/opaque-types-impl-trait-inference.md index bdf4e4cd8..42600ad87 100644 --- a/src/opaque-types-impl-trait-inference.md +++ b/src/opaque-types-impl-trait-inference.md @@ -13,13 +13,16 @@ it can work across functions and function bodies. To help explain how it works, let's consider an example. ```rust +#![feature(type_alias_impl_trait)] mod m { pub type Seq = impl IntoIterator; + #[define_opaque(Seq)] pub fn produce_singleton(t: T) -> Seq { vec![t] } + #[define_opaque(Seq)] pub fn produce_doubleton(t: T, u: T) -> Seq { vec![t, u] } From 5d7586c34448bde08597d73a8630e86a5d37100d Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Mon, 2 Jun 2025 04:08:33 +0000 Subject: [PATCH 318/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 0d889a5d5..b1e9eec52 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -e42bbfe1f7c26f8760a99c4b1f27d33aba1040bb +99e7c15e81385b38a8186b51edc4577d5d7b5bdd From 294963c0c6948963776e9028413d98d263fb575c Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Mon, 2 Jun 2025 10:52:31 +0300 Subject: [PATCH 319/447] Trivial: fix typo (change `foo` to `bar`) There is no `foo` symbol in the preceding example. I assume the method `bar` is meant. --- src/return-position-impl-trait-in-trait.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/return-position-impl-trait-in-trait.md b/src/return-position-impl-trait-in-trait.md index 5f358819c..85cece2ac 100644 --- a/src/return-position-impl-trait-in-trait.md +++ b/src/return-position-impl-trait-in-trait.md @@ -356,7 +356,7 @@ trait Foo { Failing because a down-stream impl could theoretically provide an implementation for `RPITIT` without providing an implementation of -`foo`: +`bar`: ```text error[E0308]: mismatched types From 9ad4ab9bb57c64b5e66e93d4ca9d15d7036af5bf Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 2 Jun 2025 12:30:08 +0200 Subject: [PATCH 320/447] use a relative path, so that this also works offline --- src/normalization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/normalization.md b/src/normalization.md index 9705b1a24..beeeb9e30 100644 --- a/src/normalization.md +++ b/src/normalization.md @@ -271,7 +271,7 @@ Leaving the alias unnormalized would also be wrong as the old solver expects all Ultimately this means that it is not always possible to ensure all aliases inside of a value are rigid. -[universes]: https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference/placeholders_and_universes.html#what-is-a-universe +[universes]: borrow_check/region_inference/placeholders_and_universes.md#what-is-a-universe [deeply_normalize]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/normalize/trait.NormalizeExt.html#tymethod.deeply_normalize ## Handling uses of diverging aliases From 39300c4b70526a271837cb2b8aabaa1d706aa03c Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 2 Jun 2025 12:34:19 +0200 Subject: [PATCH 321/447] distracting indirection --- src/normalization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/normalization.md b/src/normalization.md index beeeb9e30..eb0962a41 100644 --- a/src/normalization.md +++ b/src/normalization.md @@ -265,13 +265,13 @@ Another problem was that it was not possible to normalize `ParamEnv`s correctly Given a type such as `for<'a> fn(::Assoc>)`, it is not possible to correctly handle this with the old solver's approach to normalization. -If we were to normalize it to `for<'a> fn(?y)` and register a goal to normalize `for<'a> >::Assoc -> ?y`, this would result in errors in cases where `>::Assoc` normalized to `&'a u32`. The inference variable `?y` would be in a lower [universe][universes] than the placeholders made when instantiating the `for<'a>` binder. +If we were to normalize it to `for<'a> fn(?y)` and register a goal to normalize `for<'a> >::Assoc -> ?y`, this would result in errors in cases where `>::Assoc` normalized to `&'a u32`. The inference variable `?y` would be in a lower [universe] than the placeholders made when instantiating the `for<'a>` binder. Leaving the alias unnormalized would also be wrong as the old solver expects all aliases to be rigid. This was a soundness bug before the new solver was stabilized in coherence: [relating projection substs is unsound during coherence](https://github.com/rust-lang/rust/issues/102048). Ultimately this means that it is not always possible to ensure all aliases inside of a value are rigid. -[universes]: borrow_check/region_inference/placeholders_and_universes.md#what-is-a-universe +[universe]: borrow_check/region_inference/placeholders_and_universes.md#what-is-a-universe [deeply_normalize]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/normalize/trait.NormalizeExt.html#tymethod.deeply_normalize ## Handling uses of diverging aliases From 1f2bdb55269e14e50ba752ff6df45c61becb8fcf Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 22 May 2025 14:43:42 +0200 Subject: [PATCH 322/447] use consistent title capitalization --- src/SUMMARY.md | 18 +++++++++--------- src/backend/implicit-caller-location.md | 12 ++++++------ src/backend/libs-and-metadata.md | 2 +- src/llvm-coverage-instrumentation.md | 2 +- src/part-5-intro.md | 2 +- src/pat-exhaustive-checking.md | 2 +- src/profile-guided-optimization.md | 16 ++++++++-------- src/sanitizers.md | 2 +- 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index a7b76233d..60f3bf287 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -181,7 +181,7 @@ - [Significant changes and quirks](./solve/significant-changes.md) - [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md) - [Type checking](./type-checking.md) - - [Method Lookup](./method-lookup.md) + - [Method lookup](./method-lookup.md) - [Variance](./variance.md) - [Coherence checking](./coherence.md) - [Opaque types](./opaque-types-type-alias-impl-trait.md) @@ -189,7 +189,7 @@ - [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md) - [Region inference restrictions][opaque-infer] - [Const condition checking](./effects.md) -- [Pattern and Exhaustiveness Checking](./pat-exhaustive-checking.md) +- [Pattern and exhaustiveness checking](./pat-exhaustive-checking.md) - [Unsafety checking](./unsafety-checking.md) - [MIR dataflow](./mir/dataflow.md) - [Drop elaboration](./mir/drop-elaboration.md) @@ -209,7 +209,7 @@ - [Closure capture inference](./closure.md) - [Async closures/"coroutine-closures"](coroutine-closures.md) -# MIR to Binaries +# MIR to binaries - [Prologue](./part-5-intro.md) - [MIR optimizations](./mir/optimizations.md) @@ -218,15 +218,15 @@ - [Interpreter](./const-eval/interpret.md) - [Monomorphization](./backend/monomorph.md) - [Lowering MIR](./backend/lowering-mir.md) -- [Code Generation](./backend/codegen.md) +- [Code generation](./backend/codegen.md) - [Updating LLVM](./backend/updating-llvm.md) - [Debugging LLVM](./backend/debugging.md) - [Backend Agnostic Codegen](./backend/backend-agnostic.md) - - [Implicit Caller Location](./backend/implicit-caller-location.md) -- [Libraries and Metadata](./backend/libs-and-metadata.md) -- [Profile-guided Optimization](./profile-guided-optimization.md) -- [LLVM Source-Based Code Coverage](./llvm-coverage-instrumentation.md) -- [Sanitizers Support](./sanitizers.md) + - [Implicit caller location](./backend/implicit-caller-location.md) +- [Libraries and metadata](./backend/libs-and-metadata.md) +- [Profile-guided optimization](./profile-guided-optimization.md) +- [LLVM source-based code coverage](./llvm-coverage-instrumentation.md) +- [Sanitizers support](./sanitizers.md) - [Debugging support in the Rust compiler](./debugging-support-in-rustc.md) --- diff --git a/src/backend/implicit-caller-location.md b/src/backend/implicit-caller-location.md index 17158497d..c5ee00813 100644 --- a/src/backend/implicit-caller-location.md +++ b/src/backend/implicit-caller-location.md @@ -1,4 +1,4 @@ -# Implicit Caller Location +# Implicit caller location @@ -8,7 +8,7 @@ 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 +## Motivating example Take this example program: @@ -39,7 +39,7 @@ These error messages are achieved through a combination of changes to `panic!` i of `core::panic::Location::caller` and a number of `#[track_caller]` annotations in the standard library which propagate caller information. -## Reading Caller Location +## 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 @@ -51,7 +51,7 @@ was expanded. This function is itself annotated with `#[track_caller]` and wraps [`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` +## Caller location in `const` There are two main phases to returning the caller location in a const context: walking up the stack to find the right location and allocating a const value to return. @@ -138,7 +138,7 @@ fn main() { } ``` -### Dynamic Dispatch +### Dynamic dispatch In codegen contexts we have to modify the callee ABI to pass this information down the stack, but the attribute expressly does *not* modify the type of the function. The ABI change must be @@ -156,7 +156,7 @@ probably the best we can do without modifying fully-stabilized type signatures. > 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 attribute The `#[track_caller]` attribute is checked alongside other codegen attributes to ensure the function: diff --git a/src/backend/libs-and-metadata.md b/src/backend/libs-and-metadata.md index eeb2af5e6..aa1d64470 100644 --- a/src/backend/libs-and-metadata.md +++ b/src/backend/libs-and-metadata.md @@ -1,4 +1,4 @@ -# Libraries and Metadata +# Libraries and metadata When the compiler sees a reference to an external crate, it needs to load some information about that crate. This chapter gives an overview of that process, diff --git a/src/llvm-coverage-instrumentation.md b/src/llvm-coverage-instrumentation.md index 6bc21b6de..28e0e7a90 100644 --- a/src/llvm-coverage-instrumentation.md +++ b/src/llvm-coverage-instrumentation.md @@ -1,4 +1,4 @@ -# LLVM Source-Based Code Coverage +# LLVM source-based code coverage diff --git a/src/part-5-intro.md b/src/part-5-intro.md index f32508d27..a44fff1e1 100644 --- a/src/part-5-intro.md +++ b/src/part-5-intro.md @@ -1,4 +1,4 @@ -# From MIR to Binaries +# From MIR to binaries All of the preceding chapters of this guide have one thing in common: we never generated any executable machine code at all! diff --git a/src/pat-exhaustive-checking.md b/src/pat-exhaustive-checking.md index 4a796ac95..e953931aa 100644 --- a/src/pat-exhaustive-checking.md +++ b/src/pat-exhaustive-checking.md @@ -1,4 +1,4 @@ -# Pattern and Exhaustiveness Checking +# Pattern and exhaustiveness checking In Rust, pattern matching and bindings have a few very helpful properties. The compiler will check that bindings are irrefutable when made and that match arms diff --git a/src/profile-guided-optimization.md b/src/profile-guided-optimization.md index 39bc8b5e8..d279786ac 100644 --- a/src/profile-guided-optimization.md +++ b/src/profile-guided-optimization.md @@ -1,4 +1,4 @@ -# Profile Guided Optimization +# Profile-guided optimization @@ -6,7 +6,7 @@ This chapter describes what PGO is and how the support for it is implemented in `rustc`. -## What Is Profiled-Guided Optimization? +## What is profiled-guided optimization? The basic concept of PGO is to collect data about the typical execution of a program (e.g. which branches it is likely to take) and then use this data @@ -52,7 +52,7 @@ instrumentation, via the experimental option [`-C instrument-coverage`](./llvm-coverage-instrumentation.md), but using these coverage results for PGO has not been attempted at this time. -### Overall Workflow +### Overall workflow Generating a PGO-optimized program involves the following four steps: @@ -62,12 +62,12 @@ Generating a PGO-optimized program involves the following four steps: 4. Compile the program again, this time making use of the profiling data (e.g. `rustc -C profile-use=merged.profdata main.rs`) -### Compile-Time Aspects +### Compile-time aspects Depending on which step in the above workflow we are in, two different things can happen at compile time: -#### Create Binaries with Instrumentation +#### Create binaries with instrumentation As mentioned above, the profiling instrumentation is added by LLVM. `rustc` instructs LLVM to do so [by setting the appropriate][pgo-gen-passmanager] @@ -88,7 +88,7 @@ runtime are not removed [by marking the with the right export level][pgo-gen-sym [pgo-gen-symbols]:https://github.com/rust-lang/rust/blob/1.34.1/src/librustc_codegen_ssa/back/symbol_export.rs#L212-L225 -#### Compile Binaries Where Optimizations Make Use Of Profiling Data +#### Compile binaries where optimizations make use of profiling data In the final step of the workflow described above, the program is compiled again, with the compiler using the gathered profiling data in order to drive @@ -106,7 +106,7 @@ LLVM does the rest (e.g. setting branch weights, marking functions with `cold` or `inlinehint`, etc). -### Runtime Aspects +### Runtime aspects Instrumentation-based approaches always also have a runtime component, i.e. once we have an instrumented program, that program needs to be run in order @@ -134,7 +134,7 @@ instrumentation artifacts show up in LLVM IR. [rmake-tests]: https://github.com/rust-lang/rust/tree/master/tests/run-make [codegen-test]: https://github.com/rust-lang/rust/blob/master/tests/codegen/pgo-instrumentation.rs -## Additional Information +## Additional information Clang's documentation contains a good overview on [PGO in LLVM][llvm-pgo]. diff --git a/src/sanitizers.md b/src/sanitizers.md index b1654b15e..664b4feac 100644 --- a/src/sanitizers.md +++ b/src/sanitizers.md @@ -1,4 +1,4 @@ -# Sanitizers Support +# Sanitizers support The rustc compiler contains support for following sanitizers: From 64ccd09863e925fdf2c5080889a4739bfe37b3fd Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Mon, 2 Jun 2025 17:02:34 +0300 Subject: [PATCH 323/447] Trivial: dedup word --- src/coroutine-closures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coroutine-closures.md b/src/coroutine-closures.md index 04742d03c..4a708fc88 100644 --- a/src/coroutine-closures.md +++ b/src/coroutine-closures.md @@ -102,7 +102,7 @@ See the "follow-up: when do..." section below for an elaborated answer. The full When async closures are called with `AsyncFn`/`AsyncFnMut`, they return a coroutine that borrows from the closure. However, when they are called via `AsyncFnOnce`, we consume that closure, and cannot return a coroutine that borrows from data that is now dropped. -To work around around this limitation, we synthesize a separate by-move MIR body for calling `AsyncFnOnce::call_once` on a coroutine-closure that can be called by-ref. +To work around this limitation, we synthesize a separate by-move MIR body for calling `AsyncFnOnce::call_once` on a coroutine-closure that can be called by-ref. This body operates identically to the "normal" coroutine returned from calling the coroutine-closure, except for the fact that it has a different set of upvars, since we must *move* the captures from the parent coroutine-closure into the child coroutine. From f362726205ce4d9aa0d6f3b85e9d41310f86f32b Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Mon, 2 Jun 2025 17:16:29 +0300 Subject: [PATCH 324/447] Add title and toc to Async chapter This is standard for other chapters. --- src/coroutine-closures.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/coroutine-closures.md b/src/coroutine-closures.md index 04742d03c..314bd13b0 100644 --- a/src/coroutine-closures.md +++ b/src/coroutine-closures.md @@ -1,6 +1,10 @@ +# Async closures/"coroutine-closures" + + + 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 +## Coroutine-closures -- a technical deep dive Coroutine-closures are a generalization of async closures, being special syntax for closure expressions which return a coroutine, notably one that is allowed to capture from the closure's upvars. @@ -8,7 +12,7 @@ For now, the only usable kind of coroutine-closure is the async closure, and sup As a consequence of the code being somewhat general, this document may flip between calling them "async closures" and "coroutine-closures". The future that is returned by the async closure will generally be called the "coroutine" or the "child coroutine". -## HIR +### HIR Async closures (and in the future, other coroutine flavors such as `gen`) are represented in HIR as a `hir::Closure` whose closure-kind is `ClosureKind::CoroutineClosure(_)`[^k1], which wraps an async block, which is also represented in HIR as a `hir::Closure`) and whose closure-kind is `ClosureKind::Closure(CoroutineKind::Desugared(_, CoroutineSource::Closure))`[^k2]. @@ -24,7 +28,7 @@ Like `async fn`, when lowering an async closure's body, we need to unconditional [^l3]: -## `rustc_middle::ty` Representation +### `rustc_middle::ty` Representation For the purposes of keeping the implementation mostly future-compatible (i.e. with gen `|| {}` and `async gen || {}`), most of this section calls async closures "coroutine-closures". @@ -72,7 +76,7 @@ To most easily construct the `Coroutine` that a coroutine-closure returns, you c Most of the args to that function will be components that you can get out of the `CoroutineArgs`, except for the `goal_kind: ClosureKind` which controls which flavor of coroutine to return based off of the `ClosureKind` passed in -- i.e. it will prepare the by-ref coroutine if `ClosureKind::Fn | ClosureKind::FnMut`, and the by-move coroutine if `ClosureKind::FnOnce`. -## Trait Hierarchy +### Trait Hierarchy We introduce a parallel hierarchy of `Fn*` traits that are implemented for . The motivation for the introduction was covered in a blog post: [Async Closures](https://hackmd.io/@compiler-errors/async-closures). @@ -98,7 +102,7 @@ We mention above that "regular" callable types can implement `AsyncFn*`, but the See the "follow-up: when do..." section below for an elaborated answer. The full answer describes a pretty interesting and hopefully thorough heuristic that is used to ensure that most async closures "just work". -## Tale of two bodies... +### Tale of two bodies... When async closures are called with `AsyncFn`/`AsyncFnMut`, they return a coroutine that borrows from the closure. However, when they are called via `AsyncFnOnce`, we consume that closure, and cannot return a coroutine that borrows from data that is now dropped. @@ -120,7 +124,7 @@ Since we've synthesized a new def id, this query is also responsible for feeding [^b3]: -## Closure signature inference +### Closure signature inference The closure signature inference algorithm for async closures is a bit more complicated than the inference algorithm for "traditional" closures. Like closures, we iterate through all of the clauses that may be relevant (for the expectation type passed in)[^deduce1]. @@ -173,7 +177,7 @@ s.as_bytes(); So *instead*, we use this alias (in this case, a projection: `AsyncFnKindHelper::Upvars<'env, ...>`) to delay the computation of the *tupled upvars* and give us something to put in its place, while still allowing us to return a `TyKind::Coroutine` (which is a rigid type) and we may successfully confirm the built-in traits we need (in our case, `Future`), since the `Future` implementation doesn't depend on the upvars at all. -## Upvar analysis +### Upvar analysis By and large, the upvar analysis for coroutine-closures and their child coroutines proceeds like normal upvar analysis. However, there are several interesting bits that happen to account for async closures' special natures: @@ -262,7 +266,7 @@ let c = async || { If either of these cases apply, then we should capture the borrow with the lifetime of the parent coroutine-closure's env. Luckily, if this function is not correct, then the program is not unsound, since we still borrowck and validate the choices made from this function -- the only side-effect is that the user may receive unnecessary borrowck errors. -## Instance resolution +### Instance resolution If a coroutine-closure has a closure-kind of `FnOnce`, then its `AsyncFnOnce::call_once` and `FnOnce::call_once` implementations resolve to the coroutine-closure's body[^res1], and the `Future::poll` of the coroutine that gets returned resolves to the body of the child closure. @@ -282,7 +286,7 @@ This is represented by the `ConstructCoroutineInClosureShim`[^i1]. The `receiver [^i3]: -## Borrow-checking +### Borrow-checking It turns out that borrow-checking async closures is pretty straightforward. After adding a new `DefiningTy::CoroutineClosure`[^bck1] variant, and teaching borrowck how to generate the signature of the coroutine-closure[^bck2], borrowck proceeds totally fine. From 6e608e5671423c96910ad81d95b386642ca52be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 2 Jun 2025 16:21:40 +0200 Subject: [PATCH 325/447] Fix some warning blocks that contain Markdown Contents inside of an HTML element only get interpreted as Markdown (as opposed to HTML) if its separated from the HTML tags with line breaks. --- src/autodiff/flags.md | 2 ++ src/tests/ci.md | 4 +++- src/tests/compiletest.md | 2 ++ src/tests/directives.md | 2 ++ src/tests/minicore.md | 2 ++ src/tests/running.md | 4 ++++ 6 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/autodiff/flags.md b/src/autodiff/flags.md index 946ae1d03..65287d9ba 100644 --- a/src/autodiff/flags.md +++ b/src/autodiff/flags.md @@ -16,7 +16,9 @@ LooseTypes // Risk incorrect derivatives instead of aborting when missing Type I ```
+ `LooseTypes` is often helpful to get rid of Enzyme errors stating `Can not deduce type of ` and to be able to run some code. But please keep in mind that this flag absolutely has the chance to cause incorrect gradients. Even worse, the gradients might be correct for certain input values, but not for others. So please create issues about such bugs and only use this flag temporarily while you wait for your bug to be fixed. +
### Benchmark flags diff --git a/src/tests/ci.md b/src/tests/ci.md index d8be8224d..edfc870e8 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -186,9 +186,11 @@ Note that if you start the default try job using `@bors try`, it will skip build Multiple try builds can execute concurrently across different PRs.
-bors identify try jobs by commit hash. This means that if you have two PRs + +Bors identifies try jobs by commit hash. This means that if you have two PRs containing the same (latest) commits, running `@bors try` will result in the *same* try job and it really confuses `bors`. Please refrain from doing so. +
[rustc-perf]: https://github.com/rust-lang/rustc-perf diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index e1b23748d..ee06ca3b6 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -438,7 +438,9 @@ To work around this when working on a particular test, temporarily create a with these contents:
+ Be careful not to add this `Cargo.toml` or its `Cargo.lock` to your actual PR! +
```toml diff --git a/src/tests/directives.md b/src/tests/directives.md index 8a862417b..2dff21ed6 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -248,11 +248,13 @@ ignoring debuggers. | `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |
+ Tests (outside of `run-make`) that want to use incremental tests not in the incremental test-suite must not pass `-C incremental` via `compile-flags`, and must instead use the `//@ incremental` directive. Consider writing the test as a proper incremental test instead. +
### Rustdoc diff --git a/src/tests/minicore.md b/src/tests/minicore.md index 507b259e0..def9aaf87 100644 --- a/src/tests/minicore.md +++ b/src/tests/minicore.md @@ -7,9 +7,11 @@ ui/codegen/assembly test suites. It provides `core` stubs for tests that need to build for cross-compiled targets but do not need/want to run.
+ Please note that [`minicore`] is only intended for `core` items, and explicitly **not** `std` or `alloc` items because `core` items are applicable to a wider range of tests. +
A test can use [`minicore`] by specifying the `//@ add-core-stubs` directive. diff --git a/src/tests/running.md b/src/tests/running.md index 73c387368..6526fe9c2 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -8,6 +8,7 @@ development because it takes a really long time. For local development, see the subsection after on how to run a subset of tests.
+ Running plain `./x test` will build the stage 1 compiler and then run the whole test suite. This not only include `tests/`, but also `library/`, `compiler/`, `src/tools/` package tests and more. @@ -16,6 +17,7 @@ You usually only want to run a subset of the test suites (or even a smaller set of tests than that) which you expect will exercise your changes. PR CI exercises a subset of test collections, and merge queue CI will exercise all of the test collection. +
```text @@ -116,8 +118,10 @@ By listing which test suites you want to run, you avoid having to run tests for components you did not change at all.
+ Note that bors only runs the tests with the full stage 2 build; therefore, while the tests **usually** work fine with stage 1, there are some limitations. +
### Run all tests using a stage 2 compiler From c58ec2174934f040e442706b70d036810024e537 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Mon, 2 Jun 2025 16:49:06 +0300 Subject: [PATCH 326/447] Simplify long sentence --- src/coroutine-closures.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coroutine-closures.md b/src/coroutine-closures.md index 04742d03c..5a6f28e0f 100644 --- a/src/coroutine-closures.md +++ b/src/coroutine-closures.md @@ -10,7 +10,9 @@ As a consequence of the code being somewhat general, this document may flip betw ## HIR -Async closures (and in the future, other coroutine flavors such as `gen`) are represented in HIR as a `hir::Closure` whose closure-kind is `ClosureKind::CoroutineClosure(_)`[^k1], which wraps an async block, which is also represented in HIR as a `hir::Closure`) and whose closure-kind is `ClosureKind::Closure(CoroutineKind::Desugared(_, CoroutineSource::Closure))`[^k2]. +Async closures (and in the future, other coroutine flavors such as `gen`) are represented in HIR as a `hir::Closure`. +The closure-kind of the `hir::Closure` is `ClosureKind::CoroutineClosure(_)`[^k1], which wraps an async block, which is also represented in HIR as a `hir::Closure`. +The closure-kind of the async block is `ClosureKind::Closure(CoroutineKind::Desugared(_, CoroutineSource::Closure))`[^k2]. [^k1]: From 36a33414f5dfe88e89677f0e4ec3ff6ab9ca6ab0 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Tue, 3 Jun 2025 20:01:36 +0800 Subject: [PATCH 327/447] triagebot: configure PR welcome message for no auto/explicit reviewer --- triagebot.toml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 978802edf..ca6fa9f5f 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -72,6 +72,23 @@ days-threshold = 7 # Documentation at: https://forge.rust-lang.org/triagebot/pr-assignment.html [assign] +# NOTE: do not add `[assign.owners]` if we still wish to keep the opt-in +# reviewer model, as `[assign.owners]` will cause triagebot auto-reviewer +# assignment to kick in. + +# Custom PR welcome message for when no auto reviewer assignment is performed +# and no explicit manual reviewer selection is made. +# Documentation at: https://forge.rust-lang.org/triagebot/pr-assignment.html#custom-welcome-messages +[assign.custom_welcome_messages] +welcome-message = "" +welcome-message-no-reviewer = """\ +Thanks for the PR. If you have write access, feel free to merge this PR if it +does not need reviews. You can request a review using `r? rustc-dev-guide` or +`r? `. +""" + +# Groups for `r? `. +# Documentation at: https://forge.rust-lang.org/triagebot/pr-assignment.html#usage # Keep members alphanumerically sorted. [assign.adhoc_groups] rustc-dev-guide = [ From 91be3cb103b4e316bcac7bc7d207d3631a21ff11 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Tue, 3 Jun 2025 20:16:00 +0800 Subject: [PATCH 328/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index b1e9eec52..8b48bd518 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -99e7c15e81385b38a8186b51edc4577d5d7b5bdd +c68032fd4c442d275f4daa571ba19c076106b490 From d159211d5c0083abefda4dc7099aa04e53241a3e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 4 Jun 2025 00:26:47 +0200 Subject: [PATCH 329/447] expand meaning of ~? diagnostic annotation --- src/tests/ui.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index 3402838da..25d3efdbb 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -220,8 +220,12 @@ negligible (i.e. there is no semantic difference between `//~ ERROR` and `//~ERROR` although the former is more common in the codebase). `~? ` (example being `~? ERROR`) -is used to match diagnostics without line information. -These can be placed on any line in the test file, but are conventionally placed at the end. +is used to match diagnostics _without_ line info at all, +or where the line info is outside the main test file[^main test file]. +These annotations can be placed on any line in the test file. + +[^main test file]: This is a file that has the `~?` annotations, +as distinct from aux files, or sources that we have no control over. ### Error annotation examples From 912068221206e2a5ccc43e2aa9a48945bf2eeed6 Mon Sep 17 00:00:00 2001 From: Rageking8 <106309953+Rageking8@users.noreply.github.com> Date: Wed, 4 Jun 2025 16:30:02 +0800 Subject: [PATCH 330/447] Fix incorrect use of "recommend" over "recommended" --- src/building/bootstrapping/debugging-bootstrap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/building/bootstrapping/debugging-bootstrap.md b/src/building/bootstrapping/debugging-bootstrap.md index 35d33ebdb..ed2678504 100644 --- a/src/building/bootstrapping/debugging-bootstrap.md +++ b/src/building/bootstrapping/debugging-bootstrap.md @@ -55,7 +55,7 @@ Bootstrap will conditionally build `tracing` support and enable `tracing` output Example basic usage[^just-trace]: -[^just-trace]: It is not recommend to use *just* `BOOTSTRAP_TRACING=TRACE` because that will dump *everything* at `TRACE` level, including logs intentionally gated behind custom targets as they are too verbose even for `TRACE` level by default. +[^just-trace]: It is not recommended to use *just* `BOOTSTRAP_TRACING=TRACE` because that will dump *everything* at `TRACE` level, including logs intentionally gated behind custom targets as they are too verbose even for `TRACE` level by default. ```bash $ BOOTSTRAP_TRACING=bootstrap=TRACE ./x build library --stage 1 From cda721a97fec79bbe69aa476075369db61fb9407 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 4 Jun 2025 15:16:57 +0300 Subject: [PATCH 331/447] document `skip-std-check-if-no-download-rustc` in rustc-dev-guide Signed-off-by: onur-ozkan --- src/building/suggested.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/building/suggested.md b/src/building/suggested.md index 76c396084..bfb2f4d10 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -59,6 +59,14 @@ always overrides the inner ones. ## Configuring `rust-analyzer` for `rustc` +### Checking the "library" tree + +Checking the "library" tree requires a stage1 compiler, which can be a heavy process on some computers. +For this reason, bootstrap has a flag called `--skip-std-check-if-no-download-rustc` that skips checking the +"library" tree if `rust.download-rustc` isn't available. If you want to avoid putting a heavy load on your computer +with `rust-analyzer`, you can add the `--skip-std-check-if-no-download-rustc` flag to your `./x check` command in +the `rust-analyzer` configuration. + ### Project-local rust-analyzer setup `rust-analyzer` can help you check and format your code whenever you save a From 5404fd07ff38fa3b2bacfe90c96f91e07d302325 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Wed, 4 Jun 2025 21:25:15 +0800 Subject: [PATCH 332/447] triagebot: avoid unnecessary line break in PR welcome message --- triagebot.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index ca6fa9f5f..b3f4c2d28 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -82,8 +82,8 @@ days-threshold = 7 [assign.custom_welcome_messages] welcome-message = "" welcome-message-no-reviewer = """\ -Thanks for the PR. If you have write access, feel free to merge this PR if it -does not need reviews. You can request a review using `r? rustc-dev-guide` or +Thanks for the PR. If you have write access, feel free to merge this PR if it \ +does not need reviews. You can request a review using `r? rustc-dev-guide` or \ `r? `. """ From f5e1a73fb5fd43a15bb8f2c26ca7addc9bd76403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 20 Mar 2025 09:11:45 +0100 Subject: [PATCH 333/447] rustdoc: Further improve chapters and sections on testing --- src/SUMMARY.md | 2 + src/rustdoc-internals.md | 29 --- .../rustdoc-gui-test-suite.md | 14 ++ .../rustdoc-json-test-suite.md | 3 + src/rustdoc-internals/rustdoc-test-suite.md | 190 ++++++++++++------ src/rustdoc.md | 42 ++-- src/tests/compiletest.md | 34 ++-- src/tests/directives.md | 13 +- 8 files changed, 200 insertions(+), 127 deletions(-) create mode 100644 src/rustdoc-internals/rustdoc-gui-test-suite.md create mode 100644 src/rustdoc-internals/rustdoc-json-test-suite.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index a7b76233d..449a7d0c3 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -101,6 +101,8 @@ - [Rustdoc internals](./rustdoc-internals.md) - [Search](./rustdoc-internals/search.md) - [The `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md) + - [The `rustdoc-gui` test suite](./rustdoc-internals/rustdoc-gui-test-suite.md) + - [The `rustdoc-json` test suite](./rustdoc-internals/rustdoc-json-test-suite.md) - [Autodiff internals](./autodiff/internals.md) - [Installation](./autodiff/installation.md) - [How to debug](./autodiff/debugging.md) diff --git a/src/rustdoc-internals.md b/src/rustdoc-internals.md index bc91c62d8..0234d4a92 100644 --- a/src/rustdoc-internals.md +++ b/src/rustdoc-internals.md @@ -270,35 +270,6 @@ in `test.rs` is the function `make_test`, which is where hand-written Some extra reading about `make_test` can be found [here](https://quietmisdreavus.net/code/2018/02/23/how-the-doctests-get-made/). -## Dotting i's And Crossing t's - -So that's `rustdoc`'s code in a nutshell, but there's more things in the -compiler that deal with it. Since we have the full `compiletest` suite at hand, -there's a set of tests in `tests/rustdoc` that make sure the final `HTML` is -what we expect in various situations. These tests also use a supplementary -script, `src/etc/htmldocck.py`, that allows it to look through the final `HTML` -using `XPath` notation to get a precise look at the output. The full -description of all the commands available to `rustdoc` tests (e.g. [`@has`] and -[`@matches`]) is in [`htmldocck.py`]. - -To use multiple crates in a `rustdoc` test, add `//@ aux-build:filename.rs` -to the top of the test file. `filename.rs` should be placed in an `auxiliary` -directory relative to the test file with the comment. If you need to build -docs for the auxiliary file, use `//@ build-aux-docs`. - -In addition, there are separate tests for the search index and `rustdoc`'s -ability to query it. The files in `tests/rustdoc-js` each contain a -different search query and the expected results, broken out by search tab. -These files are processed by a script in `src/tools/rustdoc-js` and the `Node.js` -runtime. These tests don't have as thorough of a writeup, but a broad example -that features results in all tabs can be found in `basic.js`. The basic idea is -that you match a given `QUERY` with a set of `EXPECTED` results, complete with -the full item path of each item. - -[`@has`]: https://github.com/rust-lang/rust/blob/master/src/etc/htmldocck.py#L39 -[`@matches`]: https://github.com/rust-lang/rust/blob/master/src/etc/htmldocck.py#L44 -[`htmldocck.py`]: https://github.com/rust-lang/rust/blob/master/src/etc/htmldocck.py - ## Testing Locally Some features of the generated `HTML` documentation might require local diff --git a/src/rustdoc-internals/rustdoc-gui-test-suite.md b/src/rustdoc-internals/rustdoc-gui-test-suite.md new file mode 100644 index 000000000..e155f960e --- /dev/null +++ b/src/rustdoc-internals/rustdoc-gui-test-suite.md @@ -0,0 +1,14 @@ +# The `rustdoc-gui` test suite + +> **FIXME**: This section is a stub. Please help us flesh it out! + +This page is about the test suite named `rustdoc-gui` used to test the "GUI" of `rustdoc` (i.e., the HTML/JS/CSS as rendered in a browser). +For other rustdoc-specific test suites, see [Rustdoc test suites]. + +These use a NodeJS-based tool called [`browser-UI-test`] that uses [puppeteer] to run tests in a headless browser and check rendering and interactivity. For information on how to write this form of test, see [`tests/rustdoc-gui/README.md`][rustdoc-gui-readme] as well as [the description of the `.goml` format][goml-script] + +[Rustdoc test suites]: ../tests/compiletest.md#rustdoc-test-suites +[`browser-UI-test`]: https://github.com/GuillaumeGomez/browser-UI-test/ +[puppeteer]: https://pptr.dev/ +[rustdoc-gui-readme]: https://github.com/rust-lang/rust/blob/master/tests/rustdoc-gui/README.md +[goml-script]: https://github.com/GuillaumeGomez/browser-UI-test/blob/master/goml-script.md diff --git a/src/rustdoc-internals/rustdoc-json-test-suite.md b/src/rustdoc-internals/rustdoc-json-test-suite.md new file mode 100644 index 000000000..e08f77095 --- /dev/null +++ b/src/rustdoc-internals/rustdoc-json-test-suite.md @@ -0,0 +1,3 @@ +# The `rustdoc-json` test suite + +> **FIXME**: This section is a stub. It will be populated by [PR #2422](https://github.com/rust-lang/rustc-dev-guide/pull/2422/). diff --git a/src/rustdoc-internals/rustdoc-test-suite.md b/src/rustdoc-internals/rustdoc-test-suite.md index bad7ac19d..5d8727dc5 100644 --- a/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/rustdoc-internals/rustdoc-test-suite.md @@ -1,112 +1,190 @@ # The `rustdoc` test suite -This page is specifically about the test suite named `rustdoc`. -For other test suites used for testing rustdoc, see [Rustdoc tests](../rustdoc.md#tests). +This page is about the test suite named `rustdoc` used to test the HTML output of `rustdoc`. +For other rustdoc-specific test suites, see [Rustdoc test suites]. -The `rustdoc` test suite is specifically used to test the HTML output of rustdoc. +Each test file in this test suite is simply a Rust source file `file.rs` sprinkled with +so-called *directives* located inside normal Rust code comments. +These come in two flavors: *Compiletest* and *HtmlDocCk*. -This is achieved by means of `htmldocck.py`, a custom checker script that leverages [XPath]. +To learn more about the former, read [Compiletest directives]. +For the latter, continue reading. -[XPath]: https://en.wikipedia.org/wiki/XPath +Internally, [`compiletest`] invokes the supplementary checker script [`htmldocck.py`]. -## Directives -Directives to htmldocck are similar to those given to `compiletest` in that they take the form of `//@` comments. +[Rustdoc test suites]: ../tests/compiletest.md#rustdoc-test-suites +[`compiletest`]: ../tests/compiletest.md +[`htmldocck.py`]: https://github.com/rust-lang/rust/blob/master/src/etc/htmldocck.py -In addition to the directives listed here, -`rustdoc` tests also support most -[compiletest directives](../tests/directives.html). +## HtmlDocCk Directives -All `PATH`s in directives are relative to the rustdoc output directory (`build/TARGET/test/rustdoc/TESTNAME`), -so it is conventional to use a `#![crate_name = "foo"]` attribute to avoid -having to write a long crate name multiple times. -To avoid repetition, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument. +Directives to HtmlDocCk are assertions that place constraints on the generated HTML. +They look similar to those given to `compiletest` in that they take the form of `//@` comments +but ultimately, they are completey distinct and processed by different programs. -All arguments take the form of quoted strings -(both single and double quotes are supported), -with the exception of `COUNT` and the special `-` form of `PATH`. +[XPath] is used to query parts of the HTML document tree. + +**Introductory example**: + +```rust,ignore (illustrative) +//@ has file/type.Alias.html +//@ has - '//*[@class="rust item-decl"]//code' 'type Alias = Option;' +pub type Alias = Option; +``` + +Here, we check that documentation generated for crate `file` contains a page for the +public type alias `Alias` where the code block that is found at the top contains the +expected rendering of the item. The `//*[@class="rust item-decl"]//code` is an XPath +expression. -Directives are assertions that place constraints on the generated HTML. +Conventionally, you place these directives directly above the thing they are meant to test. +Technically speaking however, they don't need to be as HtmlDocCk only looks for the directives. -All directives (except `files`) can be negated by putting a `!` in front of their name. +All directives take a `PATH` argument. +To avoid repetition, `-` can be passed to it to re-use the previous `PATH` argument. +Since the path contains the name of the crate, it is conventional to add a +`#![crate_name = "foo"]` attribute to the crate root to shorten the resulting path. + +All arguments take the form of shell-style (single or double) quoted strings, +with the exception of `COUNT` and the special `-` form of `PATH`. + +All directives (except `files`) can be *negated* by putting a `!` in front of their name. +Before you add negated directives, please read about [their caveats](#caveats). Similar to shell commands, directives can extend across multiple lines if their last char is `\`. In this case, the start of the next line should be `//`, with no `@`. -For example, `//@ !has 'foo/struct.Bar.html'` checks that crate `foo` does not have a page for a struct named `Bar` in the crate root. +Use the special string `{{channel}}` in XPaths, `PATTERN` arguments and [snapshot files](#snapshot) +if you'd like to refer to the URL `https://doc.rust-lang.org/CHANNEL` where `CHANNEL` refers to the +current release channel (e.g, `stable` or `nightly`). + +Listed below are all possible directives: + +[XPath]: https://en.wikipedia.org/wiki/XPath ### `has` -Usage 1: `//@ has PATH` -Usage 2: `//@ has PATH XPATH PATTERN` +> Usage 1: `//@ has PATH` -In the first form, `has` checks that a given file exists. +Check that the file given by `PATH` exists. -In the second form, `has` is an alias for `matches`, -except `PATTERN` is a whitespace-normalized[^1] string instead of a regex. +> Usage 2: `//@ has PATH XPATH PATTERN` -### `matches` +Checks that the text of each element / attribute / text selected by `XPATH` in the +whitespace-normalized[^1] file given by `PATH` matches the +(also whitespace-normalized) string `PATTERN`. + +**Tip**: If you'd like to avoid whitespace normalization and/or if you'd like to match with a regex, +use `matches` instead. -Usage: `//@ matches PATH XPATH PATTERN` +### `hasraw` -Checks that the text of each element selected by `XPATH` in `PATH` matches the python-flavored regex `PATTERN`. +> Usage: `//@ hasraw PATH PATTERN` -### `matchesraw` +Checks that the contents of the whitespace-normalized[^1] file given by `PATH` +matches the (also whitespace-normalized) string `PATTERN`. -Usage: `//@ matchesraw PATH PATTERN` +**Tip**: If you'd like to avoid whitespace normalization and / or if you'd like to match with a +regex, use `matchesraw` instead. -Checks that the contents of the file `PATH` matches the regex `PATTERN`. +### `matches` -### `hasraw` +> Usage: `//@ matches PATH XPATH PATTERN` -Usage: `//@ hasraw PATH PATTERN` +Checks that the text of each element / attribute / text selected by `XPATH` in the +file given by `PATH` matches the Python-flavored[^2] regex `PATTERN`. -Same as `matchesraw`, except `PATTERN` is a whitespace-normalized[^1] string instead of a regex. +### `matchesraw` + +> Usage: `//@ matchesraw PATH PATTERN` + +Checks that the contents of the file given by `PATH` matches the +Python-flavored[^2] regex `PATTERN`. ### `count` -Usage: `//@ count PATH XPATH COUNT` +> Usage: `//@ count PATH XPATH COUNT` -Checks that there are exactly `COUNT` matches for `XPATH` within the file `PATH`. +Checks that there are exactly `COUNT` matches for `XPATH` within the file given by `PATH`. ### `snapshot` -Usage: `//@ snapshot NAME PATH XPATH` +> Usage: `//@ snapshot NAME PATH XPATH` -Creates a snapshot test named NAME. -A snapshot test captures a subtree of the DOM, at the location -determined by the XPath, and compares it to a pre-recorded value -in a file. The file's name is the test's name with the `.rs` extension -replaced with `.NAME.html`, where NAME is the snapshot's name. +Checks that the element / text selected by `XPATH` in the file given by `PATH` matches the +pre-recorded subtree or text (the "snapshot") in file `FILE_STEM.NAME.html` where `FILE_STEM` +is the file stem of the test file. -htmldocck supports the `--bless` option to accept the current subtree -as expected, saving it to the file determined by the snapshot's name. -compiletest's `--bless` flag is forwarded to htmldocck. +Pass the `--bless` option to `compiletest` to accept the current subtree/text as expected. +This will overwrite the aforementioned file (or create it if it doesn't exist). It will +automatically normalize the channel-dependent URL `https://doc.rust-lang.org/CHANNEL` to +the special string `{{channel}}`. ### `has-dir` -Usage: `//@ has-dir PATH` +> Usage: `//@ has-dir PATH` -Checks for the existence of directory `PATH`. +Checks for the existence of the directory given by `PATH`. ### `files` -Usage: `//@ files PATH ENTRIES` +> Usage: `//@ files PATH ENTRIES` + +Checks that the directory given by `PATH` contains exactly `ENTRIES`. +`ENTRIES` is a Python-like list of strings inside a quoted string. + +**Example**: `//@ files "foo/bar" '["index.html", "sidebar-items.js"]'` + +[^1]: Whitespace normalization means that all spans of consecutive whitespace are replaced with a single space. +[^2]: They are Unicode aware (flag `UNICODE` is set), match case-sensitively and in single-line mode. + +## Compiletest Directives (Brief) + +As mentioned in the introduction, you also have access to [compiletest directives]. +Most importantly, they allow you to register auxiliary crates and +to pass flags to the `rustdoc` binary under test. +It's *strongly recommended* to read that chapter if you don't know anything about them yet. + +Here are some details that are relevant to this test suite specifically: -Checks that the directory `PATH` contains exactly `ENTRIES`. -`ENTRIES` is a python list of strings inside a quoted string, -as if it were to be parsed by `eval`. -(note that the list is actually parsed by `shlex.split`, -so it cannot contain arbitrary python expressions). +* While you can use both `//@ compile-flags` and `//@ doc-flags` to pass flags to `rustdoc`, + prefer to user the latter to show intent. The former is meant for `rustc`. +* Add `//@ build-aux-docs` to the test file that has auxiliary crates to not only compile the + auxiliaries with `rustc` but to also document them with `rustdoc` -Example: `//@ files "foo/bar" '["index.html", "sidebar-items.js"]'` +## Caveats -[^1]: Whitespace normalization means that all spans of consecutive whitespace are replaced with a single space. The files themselves are also whitespace-normalized. +Testing for the absence of an element or a piece of text is quite fragile and not very future proof. + +It's not unusual that the *shape* of the generated HTML document tree changes from time to time. +This includes for example renamings of CSS classes. + +Whenever that happens, *positive* checks will either continue to match the intended element / +attribute / text if their XPath expression is general / loose enough and thus test the correct thing +or they won't in which case they would fail forcing the author of the change tolook at them. + +Compare that to *negative* checks (e.g., `//@ !has PATH XPATH PATTERN`) which won't fail if their +XPath expression "no longer" matches. The author who changed "the shape" thus won't get notified and +as a result someone else can unintentionally reintroduce `PATTERN` into the generated docs without +the original negative check failing. + +**Note**: Please avoid the use of *negated* checks! + +**Tip**: If you can't avoid it, please **always** pair it with an analogous positive check in the +immediate vicinity, so people changing "the shape" have a chance to notice and to update the +negated check! ## Limitations -`htmldocck.py` uses the xpath implementation from the standard library. + +HtmlDocCk uses the XPath implementation from the Python standard library. This leads to several limitations: + * All `XPATH` arguments must start with `//` due to a flaw in the implementation. * Many XPath features (functions, axies, etc.) are not supported. * Only well-formed HTML can be parsed (hopefully rustdoc doesn't output mismatched tags). +Furthmore, compiletest [revisions] are not supported. + +[revisions]: ../tests/compiletest.md#revisions +[compiletest directives]: ../tests/directives.md diff --git a/src/rustdoc.md b/src/rustdoc.md index de70ba638..52ae48c37 100644 --- a/src/rustdoc.md +++ b/src/rustdoc.md @@ -67,43 +67,29 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) ## Code structure -* All paths in this section are relative to `src/librustdoc` in the rust-lang/rust repository. +All paths in this section are relative to `src/librustdoc/` in the rust-lang/rust repository. + * Most of the HTML printing code is in `html/format.rs` and `html/render/mod.rs`. - It's in a bunch of `fmt::Display` implementations and supplementary - functions. -* The types that got `Display` impls above are defined in `clean/mod.rs`, right - next to the custom `Clean` trait used to process them out of the rustc HIR. + It's in a bunch of functions returning `impl std::fmt::Display`. +* The data types that get rendered by the functions mentioned above are defined in `clean/types.rs`. + The functions responsible for creating them from the `HIR` and the `rustc_middle::ty` IR + live in `clean/mod.rs`. * The bits specific to using rustdoc as a test harness are in `doctest.rs`. * The Markdown renderer is loaded up in `html/markdown.rs`, including functions for extracting doctests from a given block of Markdown. * Frontend CSS and JavaScript are stored in `html/static/`. + * Re. JavaScript, type annotations are written using [TypeScript-flavored JSDoc] +comments and an external `.d.ts` file. + This way, the code itself remains plain, valid JavaScript. + We only use `tsc` as a linter. -## Tests +[TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html -* Tests on search engine and index are located in `tests/rustdoc-js` and `tests/rustdoc-js-std`. - The format is specified - [in the search guide](rustdoc-internals/search.md#testing-the-search-engine). -* Tests on the "UI" of rustdoc (the terminal output it produces when run) are in - `tests/rustdoc-ui` -* Tests on the "GUI" of rustdoc (the HTML, JS, and CSS as rendered in a browser) - are in `tests/rustdoc-gui`. These use a [NodeJS tool called - browser-UI-test](https://github.com/GuillaumeGomez/browser-UI-test/) that uses - puppeteer to run tests in a headless browser and check rendering and - interactivity. For information on how to write this form of test, - see [`tests/rustdoc-gui/README.md`][rustdoc-gui-readme] - as well as [the description of the `.goml` format][goml-script] -* Tests on the structure of rustdoc HTML output are located in `tests/rustdoc`, - where they're handled by the test runner of bootstrap and - the supplementary script `src/etc/htmldocck.py`. - [These tests have several extra directives available to them](./rustdoc-internals/rustdoc-test-suite.md). -* Additionally, JavaScript type annotations are written using [TypeScript-flavored JSDoc] - comments and an external d.ts file. The code itself is plain, valid JavaScript; we only - use tsc as a linter. +## Tests -[TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html -[rustdoc-gui-readme]: https://github.com/rust-lang/rust/blob/master/tests/rustdoc-gui/README.md -[goml-script]: https://github.com/GuillaumeGomez/browser-UI-test/blob/master/goml-script.md +`rustdoc`'s integration tests are split across several test suites. +See [Rustdoc tests suites](tests/compiletest.md#rustdoc-test-suites) for more details. ## Constraints diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index ee06ca3b6..20dd16c81 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -56,6 +56,9 @@ incremental compilation. The various suites are defined in The following test suites are available, with links for more information: +[`tests`]: https://github.com/rust-lang/rust/blob/master/tests +[`src/tools/compiletest/src/common.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/common.rs + ### Compiler-specific test suites | Test suite | Purpose | @@ -71,6 +74,7 @@ The following test suites are available, with links for more information: | [`mir-opt`](#mir-opt-tests) | Check MIR generation and optimizations | | [`coverage`](#coverage-tests) | Check coverage instrumentation | | [`coverage-run-rustdoc`](#coverage-tests) | `coverage` tests that also run instrumented doctests | +| [`crashes`](#crashes-tests) | Check that the compiler ICEs/panics/crashes on certain inputs to catch accidental fixes | ### General purpose test suite @@ -78,19 +82,23 @@ The following test suites are available, with links for more information: ### Rustdoc test suites -See [Rustdoc tests](../rustdoc.md#tests) for more details. - -| Test suite | Purpose | -|------------------|--------------------------------------------------------------------------| -| `rustdoc` | Check `rustdoc` generated files contain the expected documentation | -| `rustdoc-gui` | Check `rustdoc`'s GUI using a web browser | -| `rustdoc-js` | Check `rustdoc` search is working as expected | -| `rustdoc-js-std` | Check rustdoc search is working as expected specifically on the std docs | -| `rustdoc-json` | Check JSON output of `rustdoc` | -| `rustdoc-ui` | Check terminal output of `rustdoc` | - -[`tests`]: https://github.com/rust-lang/rust/blob/master/tests -[`src/tools/compiletest/src/common.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/common.rs +| Test suite | Purpose | +|--------------------------------------|--------------------------------------------------------------------------| +| [`rustdoc`][rustdoc-html-tests] | Check HTML output of `rustdoc` | +| [`rustdoc-gui`][rustdoc-gui-tests] | Check `rustdoc`'s GUI using a web browser | +| [`rustdoc-js`][rustdoc-js-tests] | Check `rustdoc`'s search engine and index | +| [`rustdoc-js-std`][rustdoc-js-tests] | Check `rustdoc`'s search engine and index on the std library docs | +| [`rustdoc-json`][rustdoc-json-tests] | Check JSON output of `rustdoc` | +| `rustdoc-ui` | Check terminal output of `rustdoc` ([see also](ui.md)) | + +Some rustdoc-specific tests can also be found in `ui/rustdoc/`. +These check rustdoc-related or -specific lints that (also) run as part of `rustc`, not (only) `rustdoc`. +Run-make tests pertaining to rustdoc are typically named `run-make/rustdoc-*/`. + +[rustdoc-html-tests]: ../rustdoc-internals/rustdoc-test-suite.md +[rustdoc-gui-tests]: ../rustdoc-internals/rustdoc-gui-test-suite.md +[rustdoc-js-tests]: ../rustdoc-internals/search.md#testing-the-search-engine +[rustdoc-json-tests]: ../rustdoc-internals/rustdoc-json-test-suite.md ### Pretty-printer tests diff --git a/src/tests/directives.md b/src/tests/directives.md index 2dff21ed6..f73a2811d 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -261,7 +261,7 @@ Consider writing the test as a proper incremental test instead. | Directive | Explanation | Supported test suites | Possible values | |-------------|--------------------------------------------------------------|------------------------------------------|---------------------------| -| `doc-flags` | Flags passed to `rustdoc` when building the test or aux file | `rustdoc`, `rustdoc-js`, `rustdoc-json` | Any valid `rustdoc` flags | +| `doc-flags` | Flags passed to `rustdoc` when building the test or aux file | `rustdoc`, `rustdoc-js`, `rustdoc-json` | Any valid `rustdoc` flags | +#### Test-suite-specific directives + +The test suites [`rustdoc`][rustdoc-html-tests], [`rustdoc-js`/`rustdoc-js-std`][rustdoc-js-tests] +and [`rustdoc-json`][rustdoc-json-tests] each feature an additional set of directives whose basic +syntax resembles the one of compiletest directives but which are ultimately read and checked by +separate tools. For more information, please read their respective chapters as linked above. + +[rustdoc-html-tests]: ../rustdoc-internals/rustdoc-test-suite.md +[rustdoc-js-tests]: ../rustdoc-internals/search.html#testing-the-search-engine +[rustdoc-json-tests]: ../rustdoc-internals/rustdoc-json-test-suite.md + ### Pretty printing See [Pretty-printer](compiletest.md#pretty-printer-tests). From 3eb40c40b75116b974ba56881839b2727d4f7bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sat, 7 Jun 2025 18:58:41 +0200 Subject: [PATCH 334/447] Fix typo --- src/rustdoc-internals/rustdoc-test-suite.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/rustdoc-internals/rustdoc-test-suite.md b/src/rustdoc-internals/rustdoc-test-suite.md index 5d8727dc5..b05318ce9 100644 --- a/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/rustdoc-internals/rustdoc-test-suite.md @@ -151,7 +151,7 @@ Here are some details that are relevant to this test suite specifically: * While you can use both `//@ compile-flags` and `//@ doc-flags` to pass flags to `rustdoc`, prefer to user the latter to show intent. The former is meant for `rustc`. * Add `//@ build-aux-docs` to the test file that has auxiliary crates to not only compile the - auxiliaries with `rustc` but to also document them with `rustdoc` + auxiliaries with `rustc` but to also document them with `rustdoc`. ## Caveats @@ -161,8 +161,9 @@ It's not unusual that the *shape* of the generated HTML document tree changes fr This includes for example renamings of CSS classes. Whenever that happens, *positive* checks will either continue to match the intended element / -attribute / text if their XPath expression is general / loose enough and thus test the correct thing -or they won't in which case they would fail forcing the author of the change tolook at them. +attribute / text (if their XPath expression is general / loose enough) and +thus continue to test the correct thing or they won't in which case they would fail thereby +forcing the author of the change to look at them. Compare that to *negative* checks (e.g., `//@ !has PATH XPATH PATTERN`) which won't fail if their XPath expression "no longer" matches. The author who changed "the shape" thus won't get notified and From ea2377504f5e6a891b4ab32ff939f0429838d506 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sun, 8 Jun 2025 21:49:54 +0200 Subject: [PATCH 335/447] remove the archived ICE ping groups --- src/SUMMARY.md | 2 - src/getting-started.md | 4 -- src/notification-groups/about.md | 14 ++-- src/notification-groups/cleanup-crew.md | 90 ------------------------- src/notification-groups/llvm.md | 38 ----------- 5 files changed, 4 insertions(+), 144 deletions(-) delete mode 100644 src/notification-groups/cleanup-crew.md delete mode 100644 src/notification-groups/llvm.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 449a7d0c3..cba8eac61 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -63,10 +63,8 @@ - [Notification groups](notification-groups/about.md) - [Apple](notification-groups/apple.md) - [ARM](notification-groups/arm.md) - - [Cleanup Crew](notification-groups/cleanup-crew.md) - [Emscripten](notification-groups/emscripten.md) - [Fuchsia](notification-groups/fuchsia.md) - - [LLVM](notification-groups/llvm.md) - [RISC-V](notification-groups/risc-v.md) - [Rust for Linux](notification-groups/rust-for-linux.md) - [WASI](notification-groups/wasi.md) diff --git a/src/getting-started.md b/src/getting-started.md index 435202ca6..d6c5c3ac8 100644 --- a/src/getting-started.md +++ b/src/getting-started.md @@ -158,9 +158,6 @@ feel comfortable jumping straight into the large `rust-lang/rust` codebase. The following tasks are doable without much background knowledge but are incredibly helpful: -- [Cleanup crew][iceb]: find minimal reproductions of ICEs, bisect - regressions, etc. This is a way of helping that saves a ton of time for - others to fix an error later. - [Writing documentation][wd]: if you are feeling a bit more intrepid, you could try to read a part of the code and write doc comments for it. This will help you to learn some part of the compiler while also producing a useful artifact! @@ -179,7 +176,6 @@ incredibly helpful: [users]: https://users.rust-lang.org/ [so]: http://stackoverflow.com/questions/tagged/rust [community-library]: https://github.com/rust-lang/rfcs/labels/A-community-library -[iceb]: ./notification-groups/cleanup-crew.md [wd]: ./contributing.md#writing-documentation [wg]: https://rust-lang.github.io/compiler-team/working-groups/ [triage]: ./contributing.md#issue-triage diff --git a/src/notification-groups/about.md b/src/notification-groups/about.md index af305f010..d75891ecf 100644 --- a/src/notification-groups/about.md +++ b/src/notification-groups/about.md @@ -21,9 +21,7 @@ search for existing issues that haven't been claimed yet. Here's the list of the notification groups: - [Apple](./apple.md) - [ARM](./arm.md) -- [Cleanup Crew](./cleanup-crew.md) - [Emscripten](./emscripten.md) -- [LLVM Icebreakers](./llvm.md) - [RISC-V](./risc-v.md) - [WASI](./wasi.md) - [WebAssembly](./wasm.md) @@ -64,9 +62,7 @@ Example PRs: * [Example of adding yourself to the Apple group.](https://github.com/rust-lang/team/pull/1434) * [Example of adding yourself to the ARM group.](https://github.com/rust-lang/team/pull/358) -* [Example of adding yourself to the Cleanup Crew.](https://github.com/rust-lang/team/pull/221) * [Example of adding yourself to the Emscripten group.](https://github.com/rust-lang/team/pull/1579) -* [Example of adding yourself to the LLVM group.](https://github.com/rust-lang/team/pull/140) * [Example of adding yourself to the RISC-V group.](https://github.com/rust-lang/team/pull/394) * [Example of adding yourself to the WASI group.](https://github.com/rust-lang/team/pull/1580) * [Example of adding yourself to the WebAssembly group.](https://github.com/rust-lang/team/pull/1581) @@ -81,9 +77,7 @@ group. For example: ```text @rustbot ping apple @rustbot ping arm -@rustbot ping cleanup-crew @rustbot ping emscripten -@rustbot ping icebreakers-llvm @rustbot ping risc-v @rustbot ping wasi @rustbot ping wasm @@ -92,12 +86,12 @@ group. For example: To make some commands shorter and easier to remember, there are aliases, defined in the [`triagebot.toml`] file. For example, all of these commands -are equivalent and will ping the Cleanup Crew: +are equivalent and will ping the Apple group: ```text -@rustbot ping cleanup -@rustbot ping bisect -@rustbot ping reduce +@rustbot ping apple +@rustbot ping macos +@rustbot ping ios ``` Keep in mind that these aliases are meant to make humans' life easier. diff --git a/src/notification-groups/cleanup-crew.md b/src/notification-groups/cleanup-crew.md deleted file mode 100644 index 9cf4e512c..000000000 --- a/src/notification-groups/cleanup-crew.md +++ /dev/null @@ -1,90 +0,0 @@ -# Cleanup Crew - -**Github Label:** [ICEBreaker-Cleanup-Crew]
-**Ping command:** `@rustbot ping cleanup-crew` - -[ICEBreaker-Cleanup-Crew]: https://github.com/rust-lang/rust/labels/ICEBreaker-Cleanup-Crew - -The "Cleanup Crew" are focused on improving bug reports. Specifically, -the goal is to try to ensure that every bug report has all the -information that will be needed for someone to fix it: - -* a minimal, standalone example that shows the problem -* links to duplicates or related bugs -* if the bug is a regression (something that used to work, but no longer does), - then a bisection to the PR or nightly that caused the regression - -This kind of cleanup is invaluable in getting bugs fixed. Better -still, it can be done by anybody who knows Rust, without any -particularly deep knowledge of the compiler. - -Let's look a bit at the workflow for doing "cleanup crew" actions. - -## Finding a minimal, standalone example - -Here the ultimate goal is to produce an example that reproduces the same -problem but without relying on any external crates. Such a test ought to contain -as little code as possible, as well. This will make it much easier to isolate the problem. - -However, even if the "ultimate minimal test" cannot be achieved, it's -still useful to post incremental minimizations. For example, if you -can eliminate some of the external dependencies, that is helpful, and -so forth. - -It's particularly useful to reduce to an example that works -in the [Rust playground](https://play.rust-lang.org/), rather than -requiring people to checkout a cargo build. - -There are many resources for how to produce minimized test cases. Here -are a few: - -* The [rust-reduce](https://github.com/jethrogb/rust-reduce) tool can try to reduce - code automatically. - * The [C-reduce](https://github.com/csmith-project/creduce) tool also works - on Rust code, though it requires that you start from a single - file. (A post explaining how to do it can be found [here](https://insaneinside.net/2017/09/12/whole-crate-bug-reduction-with-creduce.html).) -* pnkfelix's [Rust Bug Minimization Patterns] blog post - * This post focuses on "heavy bore" techniques, where you are - starting with a large, complex cargo project that you wish to - narrow down to something standalone. - -[Rust Bug Minimization Patterns]: http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/ - -## Links to duplicate or related bugs - -If you are on the "Cleanup Crew", you will sometimes see multiple bug -reports that seem very similar. You can link one to the other just by -mentioning the other bug number in a Github comment. Sometimes it is -useful to close duplicate bugs. But if you do so, you should always -copy any test case from the bug you are closing to the other bug that -remains open, as sometimes duplicate-looking bugs will expose -different facets of the same problem. - -## Bisecting regressions - -For regressions (something that used to work, but no longer does), it -is super useful if we can figure out precisely when the code stopped -working. The gold standard is to be able to identify the precise -**PR** that broke the code, so we can ping the author, but even -narrowing it down to a nightly build is helpful, especially as that -then gives us a range of PRs. (One other challenge is that we -sometimes land "rollup" PRs, which combine multiple PRs into one.) - -### cargo-bisect-rustc - -To help in figuring out the cause of a regression we have a tool -called [cargo-bisect-rustc]. It will automatically download and test -various builds of rustc. For recent regressions, it is even able to -use the builds from our CI to track down the regression to a specific -PR; for older regressions, it will simply identify a nightly. - -To learn to use [cargo-bisect-rustc], check out [this blog post][learn], which -gives a quick introduction to how it works. Additionally, there is a [Guide] -which goes into more detail on how to use it. You can also ask questions at -the Zulip stream [`#t-compiler/cargo-bisect-rustc`][zcbr], or help in -improving the tool. - -[cargo-bisect-rustc]: https://github.com/rust-lang/cargo-bisect-rustc/ -[learn]: https://blog.rust-lang.org/inside-rust/2019/12/18/bisecting-rust-compiler.html -[zcbr]: https://rust-lang.zulipchat.com/#narrow/stream/217417-t-compiler.2Fcargo-bisect-rustc -[Guide]: https://rust-lang.github.io/cargo-bisect-rustc/ diff --git a/src/notification-groups/llvm.md b/src/notification-groups/llvm.md deleted file mode 100644 index 9d0087285..000000000 --- a/src/notification-groups/llvm.md +++ /dev/null @@ -1,38 +0,0 @@ -# LLVM Icebreakers Notification group - -**Github Label:** [A-LLVM]
-**Ping command:** `@rustbot ping icebreakers-llvm` - -[A-LLVM]: https://github.com/rust-lang/rust/labels/A-LLVM - -*Note*: this notification group is *not* the same as the LLVM working group -(WG-llvm). - -The "LLVM Icebreakers Notification Group" are focused on bugs that center around -LLVM. These bugs often arise because of LLVM optimizations gone awry, or as the -result of an LLVM upgrade. The goal here is: - -- to determine whether the bug is a result of us generating invalid LLVM IR, - or LLVM misoptimizing; -- if the former, to fix our IR; -- if the latter, to try and file a bug on LLVM (or identify an existing bug). - -The group may also be asked to weigh in on other sorts of LLVM-focused -questions. - -## Helpful tips and options - -The ["Debugging LLVM"][d] section of the -rustc-dev-guide gives a step-by-step process for how to help debug bugs -caused by LLVM. In particular, it discusses how to emit LLVM IR, run -the LLVM IR optimization pipelines, and so forth. You may also find -it useful to look at the various codegen options listed under `-C help` -and the internal options under `-Z help` -- there are a number that -pertain to LLVM (just search for LLVM). - -[d]: ../backend/debugging.md - -## If you do narrow to an LLVM bug - -The ["Debugging LLVM"][d] section also describes what to do once -you've identified the bug. From 1aa9e7592cc144a2b1ee6fdee45d1949a355e8cb Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Mon, 9 Jun 2025 04:08:59 +0000 Subject: [PATCH 336/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 8b48bd518..c8721bb36 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -c68032fd4c442d275f4daa571ba19c076106b490 +c31cccb7b5cc098b1a8c1794ed38d7fdbec0ccb0 From b8b2ca49e069785566fd1b98abe889f673423150 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Tue, 10 Jun 2025 22:17:57 +0800 Subject: [PATCH 337/447] Document `//@ needs-target-std` in rustc-dev-guide --- src/tests/directives.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/directives.md b/src/tests/directives.md index 2dff21ed6..b043c7035 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -202,6 +202,7 @@ settings: `//@ needs-crate-type: cdylib, proc-macro` will cause the test to be ignored on `wasm32-unknown-unknown` target because the target does not support the `proc-macro` crate type. +- `needs-target-std` — ignores if target platform does not have std support. The following directives will check LLVM support: From aa0516b8632677cb4f747f2995b6513a7d46dc7c Mon Sep 17 00:00:00 2001 From: lolbinarycat Date: Tue, 10 Jun 2025 12:48:05 -0500 Subject: [PATCH 338/447] =?UTF-8?q?Using=20git=20=C2=A7=20I=20changed=20a?= =?UTF-8?q?=20submodule=20by=20accident:=20be=20explicit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewriting git history is something that is often difficult for new contributors, and we're already explaining the `` placeholder syntax, so I think it makes sense to be explicit about what exactly the paths mean. --- src/git.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/git.md b/src/git.md index 8118ddff1..8726ddfce 100644 --- a/src/git.md +++ b/src/git.md @@ -142,7 +142,8 @@ The most common cause is that you rebased after a change and ran `git add .` wit `x` to update the submodules. Alternatively, you might have run `cargo fmt` instead of `x fmt` and modified files in a submodule, then committed the changes. -To fix it, do the following things: +To fix it, do the following things (if you changed a submodule other than cargo, +replace `src/tools/cargo` with the path to that submodule): 1. See which commit has the accidental changes: `git log --stat -n1 src/tools/cargo` 2. Revert the changes to that commit: `git checkout ~ src/tools/cargo`. Type `~` From 23604cd1a33a562c6ab9973404d36897eaebd1ab Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 11 Jun 2025 07:14:12 +0200 Subject: [PATCH 339/447] that was phrased like a separate sentence --- src/tests/compiletest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index 20dd16c81..ded30234e 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -115,7 +115,7 @@ default behavior without any commands is to: 2. Run `rustc -Zunpretty=normal` on the output of the previous step. 3. The output of the previous two steps should be the same. 4. Run `rustc -Zno-codegen` on the output to make sure that it can type check - (this is similar to running `cargo check`). + (similar to `cargo check`). If any of the commands above fail, then the test fails. From bf475d08f295577c66e916034eec5254cae94051 Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Thu, 12 Jun 2025 04:06:27 +0000 Subject: [PATCH 340/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index c8721bb36..86d35b314 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -c31cccb7b5cc098b1a8c1794ed38d7fdbec0ccb0 +14346303d760027e53214e705109a62c0f00b214 From de6ce41bf5697f2fea43b4a657fdc1c09bf3efe2 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Fri, 13 Jun 2025 01:16:36 +0200 Subject: [PATCH 341/447] Unimplement unsized_locals --- src/implementing_new_features.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/implementing_new_features.md b/src/implementing_new_features.md index d7561bbba..5d0e875cb 100644 --- a/src/implementing_new_features.md +++ b/src/implementing_new_features.md @@ -156,8 +156,8 @@ a new unstable feature: [`incomplete_features` lint]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#incomplete-features ```rust ignore - /// Allows unsized rvalues at arguments and parameters. - (incomplete, unsized_locals, "CURRENT_RUSTC_VERSION", Some(48055), None), + /// Allows deref patterns. + (incomplete, deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121), None), ``` To avoid [semantic merge conflicts], please use `CURRENT_RUSTC_VERSION` instead of `1.70` or From 1b289a860b5095ac0c492fbac4d87c3e46c862fb Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 13 Jun 2025 22:32:33 +0800 Subject: [PATCH 342/447] Adjust some doc for Query System Signed-off-by: xizheyin --- src/query.md | 85 ++++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/src/query.md b/src/query.md index 782c5b4b3..0c8e136b3 100644 --- a/src/query.md +++ b/src/query.md @@ -67,9 +67,15 @@ are cheaply cloneable; insert an `Rc` if necessary). ### Providers If, however, the query is *not* in the cache, then the compiler will -try to find a suitable **provider**. A provider is a function that has -been defined and linked into the compiler somewhere that contains the -code to compute the result of the query. +call the corresponding **provider** function. A provider is a function +implemented in a specific module and **manually registered** into the +[`Providers`][providers_struct] struct during compiler initialization. +The macro system generates the [`Providers`][providers_struct] struct, +which acts as a function table for all query implementations, where each +field is a function pointer to the actual provider. + +**Note:** The `Providers` struct is generated by macros and acts as a function table for all query implementations. +It is **not** a Rust trait, but a plain struct with function pointer fields. **Providers are defined per-crate.** The compiler maintains, internally, a table of providers for every crate, at least @@ -97,7 +103,18 @@ fn provider<'tcx>( Providers take two arguments: the `tcx` and the query key. They return the result of the query. -### How providers are setup +N.B. Most of the `rustc_*` crates only provide **local +providers**. Almost all **extern providers** wind up going through the +[`rustc_metadata` crate][rustc_metadata], which loads the information +from the crate metadata. But in some cases there are crates that +provide queries for *both* local and external crates, in which case +they define both a `provide` and a `provide_extern` function, through +[`wasm_import_module_map`][wasm_import_module_map], that `rustc_driver` can invoke. + +[rustc_metadata]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/index.html +[wasm_import_module_map]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/back/symbol_export/fn.wasm_import_module_map.html + +### How providers are set up When the tcx is created, it is given the providers by its creator using the [`Providers`][providers_struct] struct. This struct is generated by @@ -108,19 +125,16 @@ the macros here, but it is basically a big list of function pointers: ```rust,ignore struct Providers { type_of: for<'tcx> fn(TyCtxt<'tcx>, DefId) -> Ty<'tcx>, - ... + // ... one field for each query } ``` -At present, we have one copy of the struct for local crates, and one -for external crates, though the plan is that we may eventually have -one per crate. +#### How are providers registered? + +The `Providers` struct is filled in during compiler initialization, mainly by the `rustc_driver` crate. +But the actual provider functions are implemented in various `rustc_*` crates (like `rustc_middle`, `rustc_hir_analysis`, etc). -These `Providers` structs are ultimately created and populated by -`rustc_driver`, but it does this by distributing the work -throughout the other `rustc_*` crates. This is done by invoking -various [`provide`][provide_fn] functions. These functions tend to look -something like this: +To register providers, each crate exposes a [`provide`][provide_fn] function that looks like this: [provide_fn]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/fn.provide.html @@ -128,41 +142,34 @@ something like this: pub fn provide(providers: &mut Providers) { *providers = Providers { type_of, + // ... add more providers here ..*providers }; } ``` -That is, they take an `&mut Providers` and mutate it in place. Usually -we use the formulation above just because it looks nice, but you could -as well do `providers.type_of = type_of`, which would be equivalent. -(Here, `type_of` would be a top-level function, defined as we saw -before.) So, if we want to add a provider for some other query, -let's call it `fubar`, into the crate above, we might modify the `provide()` -function like so: +- This function takes a mutable reference to the `Providers` struct and sets the fields to point to the correct provider functions. +- You can also assign fields individually, e.g. `providers.type_of = type_of;`. -```rust,ignore -pub fn provide(providers: &mut Providers) { - *providers = Providers { - type_of, - fubar, - ..*providers - }; -} +#### Adding a new provider -fn fubar<'tcx>(tcx: TyCtxt<'tcx>, key: DefId) -> Fubar<'tcx> { ... } -``` +Suppose you want to add a new query called `fubar`. You would: -N.B. Most of the `rustc_*` crates only provide **local -providers**. Almost all **extern providers** wind up going through the -[`rustc_metadata` crate][rustc_metadata], which loads the information -from the crate metadata. But in some cases there are crates that -provide queries for *both* local and external crates, in which case -they define both a `provide` and a `provide_extern` function, through -[`wasm_import_module_map`][wasm_import_module_map], that `rustc_driver` can invoke. +1. Implement the provider function: + ```rust,ignore + fn fubar<'tcx>(tcx: TyCtxt<'tcx>, key: DefId) -> Fubar<'tcx> { ... } + ``` +2. Register it in the `provide` function: + ```rust,ignore + pub fn provide(providers: &mut Providers) { + *providers = Providers { + fubar, + ..*providers + }; + } + ``` -[rustc_metadata]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/index.html -[wasm_import_module_map]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/back/symbol_export/fn.wasm_import_module_map.html +--- ## Adding a new query From febe3e6cab28916aa70d0ce0b58e8d96c56944a7 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 14 Jun 2025 22:16:51 +0200 Subject: [PATCH 343/447] content has moved to another chapter --- src/query.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/query.md b/src/query.md index 0c8e136b3..9255c4fa4 100644 --- a/src/query.md +++ b/src/query.md @@ -2,7 +2,7 @@ -As described in [the high-level overview of the compiler][hl], the Rust compiler +As described in [Overview of the compiler], the Rust compiler is still (as of July 2021) transitioning from a traditional "pass-based" setup to a "demand-driven" system. The compiler query system is the key to rustc's demand-driven organization. @@ -13,7 +13,7 @@ there is a query called `type_of` that, given the [`DefId`] of some item, will compute the type of that item and return it to you. [`DefId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/def_id/struct.DefId.html -[hl]: ./compiler-src.md +[Overview of the compiler]: overview.md#queries Query execution is *memoized*. The first time you invoke a query, it will go do the computation, but the next time, the result is From 43cc7cb922ae8e99766e212cc975dc3299a2a90c Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 14 Jun 2025 22:44:47 +0200 Subject: [PATCH 344/447] use sentence case --- .../incremental-compilation-in-detail.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/queries/incremental-compilation-in-detail.md b/src/queries/incremental-compilation-in-detail.md index 03c822d4f..18e0e25c5 100644 --- a/src/queries/incremental-compilation-in-detail.md +++ b/src/queries/incremental-compilation-in-detail.md @@ -1,4 +1,4 @@ -# Incremental Compilation in detail +# Incremental compilation in detail @@ -66,7 +66,7 @@ because it reads the up-to-date version of `Hir(bar)`. Also, we re-run `type_check_item(bar)` because result of `type_of(bar)` might have changed. -## The Problem With The Basic Algorithm: False Positives +## The problem with the basic algorithm: false positives If you read the previous paragraph carefully you'll notice that it says that `type_of(bar)` *might* have changed because one of its inputs has changed. @@ -93,7 +93,7 @@ of examples like this and small changes to the input often potentially affect very large parts of the output binaries. As a consequence, we had to make the change detection system smarter and more accurate. -## Improving Accuracy: The red-green Algorithm +## Improving accuracy: the red-green algorithm The "false positives" problem can be solved by interleaving change detection and query re-evaluation. Instead of walking the graph all the way to the @@ -191,7 +191,7 @@ then itself involve recursively invoking more queries, which can mean we come ba to the `try_mark_green()` algorithm for the dependencies recursively. -## The Real World: How Persistence Makes Everything Complicated +## The real world: how persistence makes everything complicated The sections above described the underlying algorithm for incremental compilation but because the compiler process exits after being finished and @@ -258,7 +258,7 @@ the `LocalId`s within it are still the same. -### Checking Query Results For Changes: HashStable And Fingerprints +### Checking query results for changes: `HashStable` and `Fingerprint`s In order to do red-green-marking we often need to check if the result of a query has changed compared to the result it had during the previous @@ -306,7 +306,7 @@ This approach works rather well but it's not without flaws: their stable equivalents while doing the hashing. -### A Tale Of Two DepGraphs: The Old And The New +### A tale of two `DepGraph`s: the old and the new The initial description of dependency tracking glosses over a few details that quickly become a head scratcher when actually trying to implement things. @@ -344,7 +344,7 @@ new graph is serialized out to disk, alongside the query result cache, and can act as the previous dep-graph in a subsequent compilation session. -### Didn't You Forget Something?: Cache Promotion +### Didn't you forget something?: cache promotion The system described so far has a somewhat subtle property: If all inputs of a dep-node are green then the dep-node itself can be marked as green without @@ -374,7 +374,7 @@ the result cache doesn't unnecessarily shrink again. -# Incremental Compilation and the Compiler Backend +# Incremental compilation and the compiler backend The compiler backend, the part involving LLVM, is using the query system but it is not implemented in terms of queries itself. As a consequence it does not @@ -406,7 +406,7 @@ would save. -## Query Modifiers +## Query modifiers The query system allows for applying [modifiers][mod] to queries. These modifiers affect certain aspects of how the system treats the query with @@ -472,7 +472,7 @@ respect to incremental compilation: [mod]: ../query.html#adding-a-new-kind-of-query -## The Projection Query Pattern +## The projection query pattern It's interesting to note that `eval_always` and `no_hash` can be used together in the so-called "projection query" pattern. It is often the case that there is @@ -516,7 +516,7 @@ because we have the projections to take care of keeping things green as much as possible. -# Shortcomings of the Current System +# Shortcomings of the current system There are many things that still can be improved. From 754e07e449b38995ce506b26803d79d768e8c792 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 14 Jun 2025 22:49:46 +0200 Subject: [PATCH 345/447] title case --- src/query.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query.md b/src/query.md index 9255c4fa4..581d31966 100644 --- a/src/query.md +++ b/src/query.md @@ -39,7 +39,7 @@ will in turn demand information about that crate, starting from the Although this vision is not fully realized, large sections of the compiler (for example, generating [MIR](./mir/index.md)) currently work exactly like this. -[^incr-comp-detail]: The ["Incremental Compilation in Detail](queries/incremental-compilation-in-detail.md) chapter gives a more +[^incr-comp-detail]: The ["Incremental compilation in detail](queries/incremental-compilation-in-detail.md) chapter gives a more in-depth description of what queries are and how they work. If you intend to write a query of your own, this is a good read. From 288ea6e730f1efe20bfe2c7b2650154c792da60f Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 14 Jun 2025 22:56:10 +0200 Subject: [PATCH 346/447] do not inline links --- src/query.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/query.md b/src/query.md index 581d31966..0ca1b360a 100644 --- a/src/query.md +++ b/src/query.md @@ -37,12 +37,15 @@ will in turn demand information about that crate, starting from the actual parsing. Although this vision is not fully realized, large sections of the -compiler (for example, generating [MIR](./mir/index.md)) currently work exactly like this. +compiler (for example, generating [MIR]) currently work exactly like this. -[^incr-comp-detail]: The ["Incremental compilation in detail](queries/incremental-compilation-in-detail.md) chapter gives a more +[^incr-comp-detail]: The [Incremental compilation in detail] chapter gives a more in-depth description of what queries are and how they work. If you intend to write a query of your own, this is a good read. +[Incremental compilation in detail]: queries/incremental-compilation-in-detail.md +[MIR]: mir/index.md + ## Invoking queries Invoking a query is simple. The [`TyCtxt`] ("type context") struct offers a method From cb503e8910dc647cb207936b3ba5747d64cf0212 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 11 Jun 2025 18:37:48 +0200 Subject: [PATCH 347/447] Un-remap `rustc-dev` component paths --- src/tests/ui.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/ui.md b/src/tests/ui.md index 25d3efdbb..9e4a11044 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -113,6 +113,8 @@ Compiletest makes the following replacements on the compiler output: - The base directory where the test's output goes is replaced with `$TEST_BUILD_DIR`. This only comes up in a few rare circumstances. Example: `/path/to/rust/build/x86_64-unknown-linux-gnu/test/ui` +- The real directory to the standard library source is replaced with `$SRC_DIR_REAL`. +- The real directory to the compiler source is replaced with `$COMPILER_DIR_REAL`. - Tabs are replaced with `\t`. - Backslashes (`\`) are converted to forward slashes (`/`) within paths (using a heuristic). This helps normalize differences with Windows-style paths. From 38f01f117c5a1577c7cd7a0baa270a5ecfdff637 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Mon, 16 Jun 2025 17:03:33 +0200 Subject: [PATCH 348/447] Use stage 1 for building docs --- src/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contributing.md b/src/contributing.md index 0575de642..46d74b967 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -364,7 +364,7 @@ To find documentation-related issues, use the [A-docs label]. You can find documentation style guidelines in [RFC 1574]. -To build the standard library documentation, use `x doc --stage 0 library --open`. +To build the standard library documentation, use `x doc --stage 1 library --open`. To build the documentation for a book (e.g. the unstable book), use `x doc src/doc/unstable-book.` Results should appear in `build/host/doc`, as well as automatically open in your default browser. See [Building Documentation](./building/compiler-documenting.md#building-documentation) for more From ae0a09eae1d650bd7ef9bd8ba5a6d030e61baca8 Mon Sep 17 00:00:00 2001 From: Chris Bloodsworth Date: Mon, 16 Jun 2025 16:08:21 -0400 Subject: [PATCH 349/447] Remove hanging parenthesis from example signature. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also replaced '→' symbol with '->' for consistency across the table. --- src/ty.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ty.md b/src/ty.md index ce6cffec1..767ac3fdb 100644 --- a/src/ty.md +++ b/src/ty.md @@ -62,8 +62,8 @@ Here is a summary: | Describe the *syntax* of a type: what the user wrote (with some desugaring). | Describe the *semantics* of a type: the meaning of what the user wrote. | | Each `rustc_hir::Ty` has its own spans corresponding to the appropriate place in the program. | Doesn’t correspond to a single place in the user’s program. | | `rustc_hir::Ty` has generics and lifetimes; however, some of those lifetimes are special markers like [`LifetimeKind::Implicit`][implicit]. | `ty::Ty` has the full type, including generics and lifetimes, even if the user left them out | -| `fn foo(x: u32) → u32 { }` - Two `rustc_hir::Ty` representing each usage of `u32`, each has its own `Span`s, and `rustc_hir::Ty` doesn’t tell us that both are the same type | `fn foo(x: u32) → u32 { }` - One `ty::Ty` for all instances of `u32` throughout the program, and `ty::Ty` tells us that both usages of `u32` mean the same type. | -| `fn foo(x: &u32) -> &u32)` - Two `rustc_hir::Ty` again. Lifetimes for the references show up in the `rustc_hir::Ty`s using a special marker, [`LifetimeKind::Implicit`][implicit]. | `fn foo(x: &u32) -> &u32)`- A single `ty::Ty`. The `ty::Ty` has the hidden lifetime param. | +| `fn foo(x: u32) -> u32 { }` - Two `rustc_hir::Ty` representing each usage of `u32`, each has its own `Span`s, and `rustc_hir::Ty` doesn’t tell us that both are the same type | `fn foo(x: u32) -> u32 { }` - One `ty::Ty` for all instances of `u32` throughout the program, and `ty::Ty` tells us that both usages of `u32` mean the same type. | +| `fn foo(x: &u32) -> &u32 { }` - Two `rustc_hir::Ty` again. Lifetimes for the references show up in the `rustc_hir::Ty`s using a special marker, [`LifetimeKind::Implicit`][implicit]. | `fn foo(x: &u32) -> &u32 { }`- A single `ty::Ty`. The `ty::Ty` has the hidden lifetime param. | [implicit]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.LifetimeKind.html#variant.Implicit From 7b921990fcc7c7818481a9888d27cf29aaee551d Mon Sep 17 00:00:00 2001 From: lolbinarycat Date: Tue, 17 Jun 2025 11:31:04 -0500 Subject: [PATCH 350/447] Profiling with perf: specify the section of bootstrap settings. --- src/profiling/with_perf.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/profiling/with_perf.md b/src/profiling/with_perf.md index 742ea1c41..0d4f23bcd 100644 --- a/src/profiling/with_perf.md +++ b/src/profiling/with_perf.md @@ -7,8 +7,8 @@ This is a guide for how to profile rustc with [perf](https://perf.wiki.kernel.or - Get a clean checkout of rust-lang/master, or whatever it is you want to profile. - Set the following settings in your `bootstrap.toml`: - - `debuginfo-level = 1` - enables line debuginfo - - `jemalloc = false` - lets you do memory use profiling with valgrind + - `rust.debuginfo-level = 1` - enables line debuginfo + - `rust.jemalloc = false` - lets you do memory use profiling with valgrind - leave everything else the defaults - Run `./x build` to get a full build - Make a rustup toolchain pointing to that result From 4185dca09501ae8b941457563c5658d4d5d98d5b Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 6 Jun 2025 20:20:06 +0100 Subject: [PATCH 351/447] Stub chapter and consolidate under `/hir/` --- src/SUMMARY.md | 5 +++-- src/diagnostics.md | 2 +- src/hir.md | 2 +- src/hir/ambig-unambig-ty-and-consts.md | 1 + src/{hir-debugging.md => hir/debugging.md} | 0 src/{ast-lowering.md => hir/lowering.md} | 2 +- src/overview.md | 2 +- 7 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 src/hir/ambig-unambig-ty-and-consts.md rename src/{hir-debugging.md => hir/debugging.md} (100%) rename src/{ast-lowering.md => hir/lowering.md} (97%) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 2acc3c219..50a3f44ad 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -121,8 +121,9 @@ - [Feature gate checking](./feature-gate-ck.md) - [Lang Items](./lang-items.md) - [The HIR (High-level IR)](./hir.md) - - [Lowering AST to HIR](./ast-lowering.md) - - [Debugging](./hir-debugging.md) + - [Lowering AST to HIR](./hir/lowering.md) + - [Ambig/Unambig Types and Consts](./hir/ambig-unambig-ty-and-consts.md) + - [Debugging](./hir/debugging.md) - [The THIR (Typed High-level IR)](./thir.md) - [The MIR (Mid-level IR)](./mir/index.md) - [MIR construction](./mir/construction.md) diff --git a/src/diagnostics.md b/src/diagnostics.md index 01e59c919..33f5441d3 100644 --- a/src/diagnostics.md +++ b/src/diagnostics.md @@ -553,7 +553,7 @@ compiler](#linting-early-in-the-compiler). [AST nodes]: the-parser.md -[AST lowering]: ast-lowering.md +[AST lowering]: ./hir/lowering.md [HIR nodes]: hir.md [MIR nodes]: mir/index.md [macro expansion]: macro-expansion.md diff --git a/src/hir.md b/src/hir.md index 0c1c99415..72fb10701 100644 --- a/src/hir.md +++ b/src/hir.md @@ -5,7 +5,7 @@ The HIR – "High-Level Intermediate Representation" – is the primary IR used in most of rustc. It is a compiler-friendly representation of the abstract syntax tree (AST) that is generated after parsing, macro expansion, and name -resolution (see [Lowering](./ast-lowering.html) for how the HIR is created). +resolution (see [Lowering](./hir/lowering.md) for how the HIR is created). Many parts of HIR resemble Rust surface syntax quite closely, with the exception that some of Rust's expression forms have been desugared away. For example, `for` loops are converted into a `loop` and do not appear in diff --git a/src/hir/ambig-unambig-ty-and-consts.md b/src/hir/ambig-unambig-ty-and-consts.md new file mode 100644 index 000000000..b5458d71b --- /dev/null +++ b/src/hir/ambig-unambig-ty-and-consts.md @@ -0,0 +1 @@ +# Ambig/Unambig Types and Consts \ No newline at end of file diff --git a/src/hir-debugging.md b/src/hir/debugging.md similarity index 100% rename from src/hir-debugging.md rename to src/hir/debugging.md diff --git a/src/ast-lowering.md b/src/hir/lowering.md similarity index 97% rename from src/ast-lowering.md rename to src/hir/lowering.md index 033fd4b76..02c69b860 100644 --- a/src/ast-lowering.md +++ b/src/hir/lowering.md @@ -1,6 +1,6 @@ # AST lowering -The AST lowering step converts AST to [HIR](hir.html). +The AST lowering step converts AST to [HIR](../hir.md). This means many structures are removed if they are irrelevant for type analysis or similar syntax agnostic analyses. Examples of such structures include but are not limited to diff --git a/src/overview.md b/src/overview.md index 92d0c7b0c..8a1a22fad 100644 --- a/src/overview.md +++ b/src/overview.md @@ -410,7 +410,7 @@ For more details on bootstrapping, see - Guide: [The HIR](hir.md) - Guide: [Identifiers in the HIR](hir.md#identifiers-in-the-hir) - Guide: [The `HIR` Map](hir.md#the-hir-map) - - Guide: [Lowering `AST` to `HIR`](ast-lowering.md) + - Guide: [Lowering `AST` to `HIR`](./hir/lowering.md) - How to view `HIR` representation for your code `cargo rustc -- -Z unpretty=hir-tree` - Rustc `HIR` definition: [`rustc_hir`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/index.html) - Main entry point: **TODO** From a02af2f1353429ee996575d8a956e3b1e471ebe9 Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 17 Jun 2025 15:41:07 +0100 Subject: [PATCH 352/447] Write chapter on Unambig vs Ambig Types/Consts --- src/hir/ambig-unambig-ty-and-consts.md | 54 +++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/hir/ambig-unambig-ty-and-consts.md b/src/hir/ambig-unambig-ty-and-consts.md index b5458d71b..4d9a2d081 100644 --- a/src/hir/ambig-unambig-ty-and-consts.md +++ b/src/hir/ambig-unambig-ty-and-consts.md @@ -1 +1,53 @@ -# Ambig/Unambig Types and Consts \ No newline at end of file +# Ambig/Unambig Types and Consts + +Types and Consts args in the HIR can be in two kinds of positions "ambig" or "unambig". Ambig positions are where +it would be valid to parse either a type or a const, unambig positions are where only one kind would be valid to +parse. + +```rust +fn func(arg: T) { + // ^ Unambig type position + let a: _ = arg; + // ^ Unambig type position + + func::(arg); + // ^ ^ + // ^^^^ Ambig position + + let _: [u8; 10]; + // ^^ ^^ Unambig const position + // ^^ Unambig type position +} + +``` + +Most types/consts in ambig positions are able to be disambiguated as either a type or const during either parsing or ast-lowering. +Currently the only exception to this is inferred generic arguments in path segments. In `Foo<_>` it is not clear whether the `_` argument is an +inferred type argument, or an inferred const argument. + +In unambig positions, inferred arguments are represented with `hir::TyKind::Infer` or `hir::ConstArgKind::Infer` depending on whether it is a type or const position respectively. +In ambig positions, inferred arguments are represented with `hir::GenericArg::Infer`. + +A naive implementation of this structure would result in there being potentially 5 places where an inferred type/const could be found in the HIR if you just looked at the types: +- In unambig type position as a `hir::TyKind::Infer` +- In unambig const arg position as a `hir::ConstArgKind::Infer` +- In an ambig position as a `GenericArg::Ty(TyKind::Infer)` +- In an ambig position as a `GenericArg::Const(ConstArgKind::Infer)` +- In an ambig position as a `GenericArg::Infer` + +This has a few failure modes: +- People may write visitors which check for `GenericArg::Infer` but forget to check for `hir::TyKind/ConstArgKind::Infer`, only handling infers in ambig positions by accident. +- People may write visitors which check for `hir::TyKind/ConstArgKind::Infer` but forget to check for `GenericArg::Infer`, only handling infers in unambig positions by accident. +- People may write visitors which check for `GenerArg::Ty/Const(TyKind/ConstArgKind::Infer)` and `GenerigArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Ty/Const`. +- People may write visitors which check for *only* `TyKind::Infer` and not `ConstArgKind::Infer` forgetting that there are also inferred const arguments (and vice versa). + +To make writing HIR visitors less error prone when caring about inferred types/consts we have a relatively complex system: + +1. We have different types in the compiler for when a type or const is in an unambig or ambig position, `hir::Ty` and `hir::Ty<()>`. `AmbigArg` is an uninhabited type which we use in the `Infer` variant of `TyKind` and `ConstArgKind` to selectively "disable" it if we are in an ambig position. + +2. The `visit_ty` and `visit_const_arg` methods on HIR visitors only accept the ambig position versions of types/consts. Unambig types/consts are implicitly converted to ambig types/consts during the visiting process, with the `Infer` variant handled by a dedicated `visit_infer` method. + +This has a number of benefits: +- It's clear that `GenericArg::Ty/Const` cannot represent inferred type/const arguments +- Implementors of `visit_ty` and `visit_const_arg` will never encounter inferred types/consts making it impossible to write a visitor that seems to work right but handles edge cases wrong +- The `visit_infer` method handles *all* cases of inferred type/consts in the HIR making it easy for visitors to handle inferred type/consts in one dedicated place and not forget cases \ No newline at end of file From c963b4ad93245859912ee073f3f23a03f227e956 Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 17 Jun 2025 15:48:15 +0100 Subject: [PATCH 353/447] Add links --- src/hir/ambig-unambig-ty-and-consts.md | 28 +++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/hir/ambig-unambig-ty-and-consts.md b/src/hir/ambig-unambig-ty-and-consts.md index 4d9a2d081..a43ad8b49 100644 --- a/src/hir/ambig-unambig-ty-and-consts.md +++ b/src/hir/ambig-unambig-ty-and-consts.md @@ -25,29 +25,39 @@ Most types/consts in ambig positions are able to be disambiguated as either a ty Currently the only exception to this is inferred generic arguments in path segments. In `Foo<_>` it is not clear whether the `_` argument is an inferred type argument, or an inferred const argument. -In unambig positions, inferred arguments are represented with `hir::TyKind::Infer` or `hir::ConstArgKind::Infer` depending on whether it is a type or const position respectively. +In unambig positions, inferred arguments are represented with [`hir::TyKind::Infer`][ty_infer] or [`hir::ConstArgKind::Infer`][const_infer] depending on whether it is a type or const position respectively. In ambig positions, inferred arguments are represented with `hir::GenericArg::Infer`. A naive implementation of this structure would result in there being potentially 5 places where an inferred type/const could be found in the HIR if you just looked at the types: - In unambig type position as a `hir::TyKind::Infer` - In unambig const arg position as a `hir::ConstArgKind::Infer` -- In an ambig position as a `GenericArg::Ty(TyKind::Infer)` -- In an ambig position as a `GenericArg::Const(ConstArgKind::Infer)` -- In an ambig position as a `GenericArg::Infer` +- In an ambig position as a [`GenericArg::Type(TyKind::Infer)`][generic_arg_ty] +- In an ambig position as a [`GenericArg::Const(ConstArgKind::Infer)`][generic_arg_const] +- In an ambig position as a [`GenericArg::Infer`][generic_arg_infer] This has a few failure modes: - People may write visitors which check for `GenericArg::Infer` but forget to check for `hir::TyKind/ConstArgKind::Infer`, only handling infers in ambig positions by accident. - People may write visitors which check for `hir::TyKind/ConstArgKind::Infer` but forget to check for `GenericArg::Infer`, only handling infers in unambig positions by accident. -- People may write visitors which check for `GenerArg::Ty/Const(TyKind/ConstArgKind::Infer)` and `GenerigArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Ty/Const`. +- People may write visitors which check for `GenerArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenerigArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`. - People may write visitors which check for *only* `TyKind::Infer` and not `ConstArgKind::Infer` forgetting that there are also inferred const arguments (and vice versa). To make writing HIR visitors less error prone when caring about inferred types/consts we have a relatively complex system: -1. We have different types in the compiler for when a type or const is in an unambig or ambig position, `hir::Ty` and `hir::Ty<()>`. `AmbigArg` is an uninhabited type which we use in the `Infer` variant of `TyKind` and `ConstArgKind` to selectively "disable" it if we are in an ambig position. +1. We have different types in the compiler for when a type or const is in an unambig or ambig position, `hir::Ty` and `hir::Ty<()>`. [`AmbigArg`][ambig_arg] is an uninhabited type which we use in the `Infer` variant of `TyKind` and `ConstArgKind` to selectively "disable" it if we are in an ambig position. -2. The `visit_ty` and `visit_const_arg` methods on HIR visitors only accept the ambig position versions of types/consts. Unambig types/consts are implicitly converted to ambig types/consts during the visiting process, with the `Infer` variant handled by a dedicated `visit_infer` method. +2. The [`visit_ty`][visit_infer] and [`visit_const_arg`][visit_const_arg] methods on HIR visitors only accept the ambig position versions of types/consts. Unambig types/consts are implicitly converted to ambig types/consts during the visiting process, with the `Infer` variant handled by a dedicated [`visit_infer`][visit_infer] method. This has a number of benefits: -- It's clear that `GenericArg::Ty/Const` cannot represent inferred type/const arguments +- It's clear that `GenericArg::Type/Const` cannot represent inferred type/const arguments - Implementors of `visit_ty` and `visit_const_arg` will never encounter inferred types/consts making it impossible to write a visitor that seems to work right but handles edge cases wrong -- The `visit_infer` method handles *all* cases of inferred type/consts in the HIR making it easy for visitors to handle inferred type/consts in one dedicated place and not forget cases \ No newline at end of file +- The `visit_infer` method handles *all* cases of inferred type/consts in the HIR making it easy for visitors to handle inferred type/consts in one dedicated place and not forget cases + +[ty_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.TyKind.html#variant.Infer +[const_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.ConstArgKind.html#variant.Infer +[generic_arg_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.GenericArg.html#variant.Type +[generic_arg_const]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.GenericArg.html#variant.Const +[generic_arg_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.GenericArg.html#variant.Infer +[ambig_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.AmbigArg.html +[visit_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_ty +[visit_const_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_const_arg +[visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer \ No newline at end of file From 79db838b7aa38f8237278064becf89f48d927263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 18 Jun 2025 15:07:36 +0200 Subject: [PATCH 354/447] Fix compiletest and rustc-dev-guide --- src/building/bootstrapping/writing-tools-in-bootstrap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/building/bootstrapping/writing-tools-in-bootstrap.md b/src/building/bootstrapping/writing-tools-in-bootstrap.md index 6046d5b13..41d0cf8d9 100644 --- a/src/building/bootstrapping/writing-tools-in-bootstrap.md +++ b/src/building/bootstrapping/writing-tools-in-bootstrap.md @@ -4,7 +4,7 @@ There are three types of tools you can write in bootstrap: - **`Mode::ToolBootstrap`** Use this for tools that don’t need anything from the in-tree compiler and can run with the stage0 `rustc`. - The output is placed in the "stage0-bootstrap-tools" directory. This mode is for general-purpose tools built + The output is placed in the "bootstrap-tools" directory. This mode is for general-purpose tools built entirely with the stage0 compiler, including target libraries and only works for stage 0. - **`Mode::ToolStd`** From 9d7ba8573d4dbfba8ac459f1c15329010f8c3f29 Mon Sep 17 00:00:00 2001 From: Boxy Date: Wed, 18 Jun 2025 15:26:18 +0100 Subject: [PATCH 355/447] Reviews --- src/hir/ambig-unambig-ty-and-consts.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/hir/ambig-unambig-ty-and-consts.md b/src/hir/ambig-unambig-ty-and-consts.md index a43ad8b49..709027883 100644 --- a/src/hir/ambig-unambig-ty-and-consts.md +++ b/src/hir/ambig-unambig-ty-and-consts.md @@ -1,11 +1,11 @@ # Ambig/Unambig Types and Consts -Types and Consts args in the HIR can be in two kinds of positions "ambig" or "unambig". Ambig positions are where +Types and Consts args in the HIR can be in two kinds of positions ambiguous (ambig) or unambiguous (unambig). Ambig positions are where it would be valid to parse either a type or a const, unambig positions are where only one kind would be valid to parse. ```rust -fn func(arg: T) { +fn func(arg: T) { // ^ Unambig type position let a: _ = arg; // ^ Unambig type position @@ -21,19 +21,19 @@ fn func(arg: T) { ``` -Most types/consts in ambig positions are able to be disambiguated as either a type or const during either parsing or ast-lowering. -Currently the only exception to this is inferred generic arguments in path segments. In `Foo<_>` it is not clear whether the `_` argument is an -inferred type argument, or an inferred const argument. +Most types/consts in ambig positions are able to be disambiguated as either a type or const during parsing. Single segment paths are always represented as types in the AST but may get resolved to a const parameter during name resolution, then lowered to a const argument during ast-lowering. The only generic arguments which remain ambiguous after lowering are inferred generic arguments (`_`) in path segments. For example, in `Foo<_>` it is not clear whether the `_` argument is an inferred type argument, or an inferred const argument. In unambig positions, inferred arguments are represented with [`hir::TyKind::Infer`][ty_infer] or [`hir::ConstArgKind::Infer`][const_infer] depending on whether it is a type or const position respectively. In ambig positions, inferred arguments are represented with `hir::GenericArg::Infer`. -A naive implementation of this structure would result in there being potentially 5 places where an inferred type/const could be found in the HIR if you just looked at the types: -- In unambig type position as a `hir::TyKind::Infer` -- In unambig const arg position as a `hir::ConstArgKind::Infer` -- In an ambig position as a [`GenericArg::Type(TyKind::Infer)`][generic_arg_ty] -- In an ambig position as a [`GenericArg::Const(ConstArgKind::Infer)`][generic_arg_const] -- In an ambig position as a [`GenericArg::Infer`][generic_arg_infer] +A naive implementation of this would result in there being potentially 5 places where you might think an inferred type/const could be found in the HIR from looking at the structure of the HIR: +1. In unambig type position as a `hir::TyKind::Infer` +2. In unambig const arg position as a `hir::ConstArgKind::Infer` +3. In an ambig position as a [`GenericArg::Type(TyKind::Infer)`][generic_arg_ty] +4. In an ambig position as a [`GenericArg::Const(ConstArgKind::Infer)`][generic_arg_const] +5. In an ambig position as a [`GenericArg::Infer`][generic_arg_infer] + +Note that places 3 and 4 would never actually be possible to encounter as we always lower to `GenericArg::Infer` in generic arg position. This has a few failure modes: - People may write visitors which check for `GenericArg::Infer` but forget to check for `hir::TyKind/ConstArgKind::Infer`, only handling infers in ambig positions by accident. @@ -45,7 +45,7 @@ To make writing HIR visitors less error prone when caring about inferred types/c 1. We have different types in the compiler for when a type or const is in an unambig or ambig position, `hir::Ty` and `hir::Ty<()>`. [`AmbigArg`][ambig_arg] is an uninhabited type which we use in the `Infer` variant of `TyKind` and `ConstArgKind` to selectively "disable" it if we are in an ambig position. -2. The [`visit_ty`][visit_infer] and [`visit_const_arg`][visit_const_arg] methods on HIR visitors only accept the ambig position versions of types/consts. Unambig types/consts are implicitly converted to ambig types/consts during the visiting process, with the `Infer` variant handled by a dedicated [`visit_infer`][visit_infer] method. +2. The [`visit_ty`][visit_ty] and [`visit_const_arg`][visit_const_arg] methods on HIR visitors only accept the ambig position versions of types/consts. Unambig types/consts are implicitly converted to ambig types/consts during the visiting process, with the `Infer` variant handled by a dedicated [`visit_infer`][visit_infer] method. This has a number of benefits: - It's clear that `GenericArg::Type/Const` cannot represent inferred type/const arguments From 980acc5eeed38b50a8ef4861d2070c5409439e1b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 19 Jun 2025 00:03:33 +0200 Subject: [PATCH 356/447] fix markup That was intended to be a list. Also, the order is not relevant. --- src/building/new-target.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/building/new-target.md b/src/building/new-target.md index 8d323ba96..e11a2cd8e 100644 --- a/src/building/new-target.md +++ b/src/building/new-target.md @@ -174,8 +174,8 @@ compiler, you can use it instead of the JSON file for both arguments. ## Promoting a target from tier 2 (target) to tier 2 (host) There are two levels of tier 2 targets: - a) Targets that are only cross-compiled (`rustup target add`) - b) Targets that [have a native toolchain][tier2-native] (`rustup toolchain install`) +- Targets that are only cross-compiled (`rustup target add`) +- Targets that [have a native toolchain][tier2-native] (`rustup toolchain install`) [tier2-native]: https://doc.rust-lang.org/nightly/rustc/target-tier-policy.html#tier-2-with-host-tools From 4233695feaa203816f2fea8cffede89d851a1c5c Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Mon, 2 Jun 2025 12:06:27 -0700 Subject: [PATCH 357/447] initial instructions for gpu offload --- src/SUMMARY.md | 2 ++ src/offload/installation.md | 71 +++++++++++++++++++++++++++++++++++++ src/offload/internals.md | 9 +++++ 3 files changed, 82 insertions(+) create mode 100644 src/offload/installation.md create mode 100644 src/offload/internals.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 50a3f44ad..7f2f32c62 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -101,6 +101,8 @@ - [The `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md) - [The `rustdoc-gui` test suite](./rustdoc-internals/rustdoc-gui-test-suite.md) - [The `rustdoc-json` test suite](./rustdoc-internals/rustdoc-json-test-suite.md) +- [GPU offload internals](./offload/internals.md) + - [Installation](./offload/installation.md) - [Autodiff internals](./autodiff/internals.md) - [Installation](./autodiff/installation.md) - [How to debug](./autodiff/debugging.md) diff --git a/src/offload/installation.md b/src/offload/installation.md new file mode 100644 index 000000000..2536af09a --- /dev/null +++ b/src/offload/installation.md @@ -0,0 +1,71 @@ +# Installation + +In the future, `std::offload` should become available in nightly builds for users. For now, everyone still needs to build rustc from source. + +## Build instructions + +First you need to clone and configure the Rust repository: +```bash +git clone --depth=1 git@github.com:rust-lang/rust.git +cd rust +./configure --enable-llvm-link-shared --release-channel=nightly --enable-llvm-assertions --enable-offload --enable-enzyme --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs +``` + +Afterwards you can build rustc using: +```bash +./x.py build --stage 1 library +``` + +Afterwards rustc toolchain link will allow you to use it through cargo: +``` +rustup toolchain link offload build/host/stage1 +rustup toolchain install nightly # enables -Z unstable-options +``` + + + +## Build instruction for LLVM itself +```bash +git clone --depth=1 git@github.com:llvm/llvm-project.git +cd llvm-project +mkdir build +cd build +cmake -G Ninja ../llvm -DLLVM_TARGETS_TO_BUILD="host,AMDGPU,NVPTX" -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_ENABLE_RUNTIMES="offload,openmp" -DLLVM_ENABLE_PLUGINS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=. +ninja +ninja install +``` +This gives you a working LLVM build. + + +## Testing +run +``` +./x.py test --stage 1 tests/codegen/gpu_offload +``` + +## Usage +It is important to use a clang compiler build on the same llvm as rustc. Just calling clang without the full path will likely use your system clang, which probably will be incompatible. +``` +/absolute/path/to/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc --edition=2024 --crate-type cdylib src/main.rs --emit=llvm-ir -O -C lto=fat -Cpanic=abort -Zoffload=Enable +/absolute/path/to/rust/build/x86_64-unknown-linux-gnu/llvm/bin/clang++ -fopenmp --offload-arch=native -g -O3 main.ll -o main -save-temps +LIBOMPTARGET_INFO=-1 ./main +``` +The first step will generate a `main.ll` file, which has enough instructions to cause the offload runtime to move data to and from a gpu. +The second step will use clang as the compilation driver to compile our IR file down to a working binary. Only a very small Rust subset will work out of the box here, unless +you use features like build-std, which are not covered by this guide. Look at the codegen test to get a feeling for how to write a working example. +In the last step you can run your binary, if all went well you will see a data transfer being reported: +``` +omptarget device 0 info: Entering OpenMP data region with being_mapper at unknown:0:0 with 1 arguments: +omptarget device 0 info: tofrom(unknown)[1024] +omptarget device 0 info: Creating new map entry with HstPtrBase=0x00007fffffff9540, HstPtrBegin=0x00007fffffff9540, TgtAllocBegin=0x0000155547200000, TgtPtrBegin=0x0000155547200000, Size=1024, DynRefCount=1, HoldRefCount=0, Name=unknown +omptarget device 0 info: Copying data from host to device, HstPtr=0x00007fffffff9540, TgtPtr=0x0000155547200000, Size=1024, Name=unknown +omptarget device 0 info: OpenMP Host-Device pointer mappings after block at unknown:0:0: +omptarget device 0 info: Host Ptr Target Ptr Size (B) DynRefCount HoldRefCount Declaration +omptarget device 0 info: 0x00007fffffff9540 0x0000155547200000 1024 1 0 unknown at unknown:0:0 +// some other output +omptarget device 0 info: Exiting OpenMP data region with end_mapper at unknown:0:0 with 1 arguments: +omptarget device 0 info: tofrom(unknown)[1024] +omptarget device 0 info: Mapping exists with HstPtrBegin=0x00007fffffff9540, TgtPtrBegin=0x0000155547200000, Size=1024, DynRefCount=0 (decremented, delayed deletion), HoldRefCount=0 +omptarget device 0 info: Copying data from device to host, TgtPtr=0x0000155547200000, HstPtr=0x00007fffffff9540, Size=1024, Name=unknown +omptarget device 0 info: Removing map entry with HstPtrBegin=0x00007fffffff9540, TgtPtrBegin=0x0000155547200000, Size=1024, Name=unknown +``` diff --git a/src/offload/internals.md b/src/offload/internals.md new file mode 100644 index 000000000..28857a6e7 --- /dev/null +++ b/src/offload/internals.md @@ -0,0 +1,9 @@ +# std::offload + +This module is under active development. Once upstream, it should allow Rust developers to run Rust code on GPUs. +We aim to develop a `rusty` GPU programming interface, which is safe, convenient and sufficiently fast by default. +This includes automatic data movement to and from the GPU, in a efficient way. We will (later) +also offer more advanced, possibly unsafe, interfaces which allow a higher degree of control. + +The implementation is based on LLVM's "offload" project, which is already used by OpenMP to run Fortran or C++ code on GPUs. +While the project is under development, users will need to call other compilers like clang to finish the compilation process. From c6bbfe0945b11fd17743f78562a759038607131a Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Thu, 19 Jun 2025 04:07:21 +0000 Subject: [PATCH 358/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 86d35b314..30ba3070e 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -14346303d760027e53214e705109a62c0f00b214 +d1d8e386c5e84c4ba857f56c3291f73c27e2d62a From 105177734c0fde5e859295547247cabde6bcf25e Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 27 May 2025 14:24:03 -0400 Subject: [PATCH 359/447] Add a SUMMARY.md outlining immediate subdirectories of the ui test suite Co-authored-by: Jieyou Xu --- src/tests/ui.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tests/ui.md b/src/tests/ui.md index 9e4a11044..8f4467a55 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -13,6 +13,11 @@ used for many other purposes. For example, tests can also be configured to [run the resulting program](#controlling-passfail-expectations) to verify its behavior. +For a survey of each subdirectory's purpose under `tests/ui`, consult the +[SUMMARY.md](https://github.com/rust-lang/rust/tree/master/tests/ui/SUMMARY.md). +This is useful if you write a new test, and are looking for a category to +place it in. + If you need to work with `#![no_std]` cross-compiling tests, consult the [`minicore` test auxiliary](./minicore.md) chapter. From a19cd234f3aa156e1ae8e498a9979ee2b0cb10b8 Mon Sep 17 00:00:00 2001 From: Karan Janthe Date: Wed, 25 Jun 2025 02:06:53 +0000 Subject: [PATCH 360/447] added PrintTAFn flag for autodiff Signed-off-by: Karan Janthe --- src/autodiff/flags.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/autodiff/flags.md b/src/autodiff/flags.md index 65287d9ba..efbb9ea34 100644 --- a/src/autodiff/flags.md +++ b/src/autodiff/flags.md @@ -6,6 +6,7 @@ To support you while debugging or profiling, we have added support for an experi ```text PrintTA // Print TypeAnalysis information +PrintTAFn // Print TypeAnalysis information for a specific function PrintAA // Print ActivityAnalysis information Print // Print differentiated functions while they are being generated and optimized PrintPerf // Print AD related Performance warnings From 63a463e6119d17ee4c3586ce8fc18b5f95b03d7a Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 24 Jun 2025 21:21:13 -0700 Subject: [PATCH 361/447] Sprinkle breadcrumbs around to lead people to the rust-invalid ABI --- src/tests/ui.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tests/ui.md b/src/tests/ui.md index 8f4467a55..09dc476d6 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -59,6 +59,11 @@ The output is normalized to ignore unwanted differences, see the [Normalization](#normalization) section. If the file is missing, then compiletest expects the corresponding output to be empty. +A common reason to use normalization, revisions, and most of the other following tools, +is to account for platform differences. Consider alternatives to these tools, like +e.g. using the `extern "rust-invalid"` ABI that is invalid on every platform +instead of fixing the test to use cross-compilation and testing every possibly-invalid ABI. + There can be multiple stdout/stderr files. The general form is: ```text From a66ddbdc8d319548988b2eb04fb71ac25b1e44f0 Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Thu, 26 Jun 2025 04:07:24 +0000 Subject: [PATCH 362/447] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 30ba3070e..c986141b6 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -d1d8e386c5e84c4ba857f56c3291f73c27e2d62a +bc4376fa73b636eb6f2c7d48b1f731d70f022c4b From 3bac737f29b37fea762480c104c034a920c657e7 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 26 Jun 2025 22:32:39 +0800 Subject: [PATCH 363/447] Add `arguments sharing and isolation` section in `diagnostic-struct` of rdg Signed-off-by: xizheyin --- src/diagnostics/diagnostic-structs.md | 47 ++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/diagnostics/diagnostic-structs.md b/src/diagnostics/diagnostic-structs.md index e01b8f2f1..ea6cdf024 100644 --- a/src/diagnostics/diagnostic-structs.md +++ b/src/diagnostics/diagnostic-structs.md @@ -1,14 +1,18 @@ # Diagnostic and subdiagnostic structs rustc has three diagnostic traits that can be used to create diagnostics: -`Diagnostic`, `LintDiagnostic`, and `Subdiagnostic`. For simple diagnostics, -instead of using the `Diag` API to create and emit diagnostics, -derived impls can be used. They are only suitable for simple diagnostics that +`Diagnostic`, `LintDiagnostic`, and `Subdiagnostic`. + +For simple diagnostics, +derived impls can be used, e.g. `#[derive(Diagnostic)]`. They are only suitable for simple diagnostics that don't require much logic in deciding whether or not to add additional subdiagnostics. -Such diagnostic can be translated into -different languages and each has a slug that uniquely identifies the -diagnostic. +In cases where diagnostics require more complex or dynamic behavior, such as conditionally adding subdiagnostics, +customizing the rendering logic, or selecting messages at runtime, you will need to manually implement +the corresponding trait (`Diagnostic`, `LintDiagnostic`, or `Subdiagnostic`). +This approach provides greater flexibility and is recommended for diagnostics that go beyond simple, static structures. + +Diagnostic can be translated into different languages and each has a slug that uniquely identifies the diagnostic. ## `#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]` @@ -142,7 +146,7 @@ tcx.dcx().emit_err(FieldAlreadyDeclared { }); ``` -### Reference +### Reference for `#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]` `#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]` support the following attributes: @@ -330,7 +334,34 @@ function ([example][subdiag_use_1] and [example][subdiag_use_2]) on a diagnostic or by assigning it to a `#[subdiagnostic]`-annotated field of a diagnostic struct. -### Reference +### Argument sharing and isolation + +Subdiagnostics will add their own arguments, +i.e. some fields in their struct, into the subdiagnostic when rendering the message, +so that the parameters in the main diagnostic can be used. +However, when a subdiagnostic is added to a main diagnostic by implementing `#[derive(Subdiagnostic)]`, +the following rules, introduced in [rust-lang/rust#142724](https://github.com/rust-lang/rust/pull/142724) +apply to the handling of arguments (i.e., variables used in Fluent messages): + +**Argument isolation between sub diagnostics**: +Arguments set by a subdiagnostic are only available during the rendering of that subdiagnostic. +After the subdiagnostic is rendered, all arguments it introduced are restore from the main diagnostic. +This ensures that multiple subdiagnostics do not pollute each other's argument scope. +For example, when using a `Vec`, it iteratively add the same arg over and over again. + +**Same argument override between sub and main diagnostics**: +If a subdiagnostic sets a argument with the same name as a arg already in the master diagnostic, +it will report an error at runtime unless both have exactly the same value. +This +- preserves the flexibility that can that *arguments is allowed to appear in the attributes of the subdiagnostic. +For example, There is a attribute `#[suggestion(code = "{new_vis}")]` in sub-diagnostic, but `new_vis` is the field in main diagnostic struct. +- prevents accidental overwriting or deletion of parameters required by the main diagnostic or other sub-diagnostics. + +These rules guarantee that arguments injected by subdiagnostics are strictly scoped to their own rendering. +The main diagnostic's arguments remain unaffected by subdiagnostic logic, even in the presence of name collisions. +Additionally, subdiagnostics can access parameters from the main diagnostic with the same name when needed. + +### Reference for `#[derive(Subdiagnostic)]` `#[derive(Subdiagnostic)]` supports the following attributes: - `#[label(slug)]`, `#[help(slug)]`, `#[warning(slug)]` or `#[note(slug)]` From 58648c82a15476725ba5862901eff0bea31beeea Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 27 Jun 2025 17:44:15 +0800 Subject: [PATCH 364/447] Fix typo Signed-off-by: xizheyin --- src/diagnostics/diagnostic-structs.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/diagnostics/diagnostic-structs.md b/src/diagnostics/diagnostic-structs.md index ea6cdf024..4e5c3413c 100644 --- a/src/diagnostics/diagnostic-structs.md +++ b/src/diagnostics/diagnostic-structs.md @@ -336,30 +336,30 @@ diagnostic struct. ### Argument sharing and isolation -Subdiagnostics will add their own arguments, -i.e. some fields in their struct, into the subdiagnostic when rendering the message, -so that the parameters in the main diagnostic can be used. +Subdiagnostics add their own arguments (i.e., certain fields in their structure) to the `Diag` structure before rendering the information. +`Diag` structure also stores the arguments from the main diagnostic, so the subdiagnostic can also use the arguments from the main diagnostic. + However, when a subdiagnostic is added to a main diagnostic by implementing `#[derive(Subdiagnostic)]`, the following rules, introduced in [rust-lang/rust#142724](https://github.com/rust-lang/rust/pull/142724) apply to the handling of arguments (i.e., variables used in Fluent messages): **Argument isolation between sub diagnostics**: Arguments set by a subdiagnostic are only available during the rendering of that subdiagnostic. -After the subdiagnostic is rendered, all arguments it introduced are restore from the main diagnostic. +After the subdiagnostic is rendered, all arguments it introduced are restored from the main diagnostic. This ensures that multiple subdiagnostics do not pollute each other's argument scope. -For example, when using a `Vec`, it iteratively add the same arg over and over again. +For example, when using a `Vec`, it iteratively adds the same argument over and over again. **Same argument override between sub and main diagnostics**: -If a subdiagnostic sets a argument with the same name as a arg already in the master diagnostic, +If a subdiagnostic sets a argument with the same name as a arguments already in the main diagnostic, it will report an error at runtime unless both have exactly the same value. -This -- preserves the flexibility that can that *arguments is allowed to appear in the attributes of the subdiagnostic. -For example, There is a attribute `#[suggestion(code = "{new_vis}")]` in sub-diagnostic, but `new_vis` is the field in main diagnostic struct. -- prevents accidental overwriting or deletion of parameters required by the main diagnostic or other sub-diagnostics. +It has two benefits: +- preserves the flexibility that arguments in the main diagnostic are allowed to appear in the attributes of the subdiagnostic. +For example, There is an attribute `#[suggestion(code = "{new_vis}")]` in the subdiagnostic, but `new_vis` is the field in the main diagnostic struct. +- prevents accidental overwriting or deletion of arguments required by the main diagnostic or other subdiagnostics. These rules guarantee that arguments injected by subdiagnostics are strictly scoped to their own rendering. The main diagnostic's arguments remain unaffected by subdiagnostic logic, even in the presence of name collisions. -Additionally, subdiagnostics can access parameters from the main diagnostic with the same name when needed. +Additionally, subdiagnostics can access arguments from the main diagnostic with the same name when needed. ### Reference for `#[derive(Subdiagnostic)]` `#[derive(Subdiagnostic)]` supports the following attributes: From 3407b01bdd996b32f923887a1463d5d32f9966b3 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 26 Jun 2025 22:50:31 +0800 Subject: [PATCH 365/447] Add a link to rust-forge to explain where rdg changes should be submitted Signed-off-by: xizheyin --- src/contributing.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/contributing.md b/src/contributing.md index 46d74b967..b3fcd79ec 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -434,6 +434,10 @@ Just a few things to keep in mind: it might benefit from having a Table of Contents at the beginning, which you can auto-generate by including the `` marker at the top. +#### ⚠️ Note: Where to contribute `rustc-dev-guide` changes + +For detailed information about where to contribute rustc-dev-guide changes and the benefits of doing so, see [the rustc-dev-guide working group documentation](https://forge.rust-lang.org/wg-rustc-dev-guide/index.html#where-to-contribute-rustc-dev-guide-changes). + ## Issue triage Please see . From a20a4905725873f02f4f3118510d027d191affae Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 29 Jun 2025 11:23:19 +0800 Subject: [PATCH 366/447] Add broken `./x test library/std` advisory --- src/building/how-to-build-and-run.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/building/how-to-build-and-run.md b/src/building/how-to-build-and-run.md index c4783002b..d29cd1448 100644 --- a/src/building/how-to-build-and-run.md +++ b/src/building/how-to-build-and-run.md @@ -2,6 +2,24 @@ +
+ +For `profile = "library"` users, or users who use `download-rustc = true | "if-unchanged"`, please be advised that +the `./x test library/std` flow where `download-rustc` is active (i.e. no compiler changes) is currently broken. +This is tracked in . Only the `./x test` flow is affected in this +case, `./x {check,build} library/std` should still work. + +In the short-term, you may need to disable `download-rustc` for `./x test library/std`. This can be done either by: + +1. `./x test library/std --set rust.download-rustc=false` +2. Or set `rust.download-rustc=false` in `bootstrap.toml`. + +Unfortunately that will require building the stage 1 compiler. The bootstrap team is working on this, but +implementing a maintainable fix is taking some time. + +
+ + The compiler is built using a tool called `x.py`. You will need to have Python installed to run it. From 87d1eb87b498a41c1564b71bed3f751d51cdb07e Mon Sep 17 00:00:00 2001 From: kilavvy <140459108+kilavvy@users.noreply.github.com> Date: Sun, 29 Jun 2025 10:01:27 +0200 Subject: [PATCH 367/447] Update README.md - Update ui.md - Update type-alias-impl-trait.md - Update README.md --- src/tests/ui.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index 09dc476d6..f7e62e1ec 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -499,7 +499,7 @@ This directive takes comma-separated issue numbers as arguments, or `"unknown"`: - `//@ known-bug: rust-lang/chalk#123456` (allows arbitrary text before the `#`, which is useful when the issue is on another repo) - `//@ known-bug: unknown` - (when there is no known issue yet; preferrably open one if it does not already exist) + (when there is no known issue yet; preferably open one if it does not already exist) Do not include [error annotations](#error-annotations) in a test with `known-bug`. The test should still include other normal directives and From 36d9c58a62ec09e404edbbabf9da9f3bf3b261d6 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 30 Jun 2025 06:15:08 +0200 Subject: [PATCH 368/447] build-fail directive: make explanation more uniform The last part of the paragraph did not fit --- src/tests/ui.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index 09dc476d6..65bd89baf 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -453,9 +453,9 @@ even run the resulting program. Just add one of the following - `//@ check-fail` — compilation should fail (the codegen phase is skipped). This is the default for UI tests. - `//@ build-fail` — compilation should fail during the codegen phase. - This will run `rustc` twice, once to verify that it compiles successfully - without the codegen phase, then a second time the full compile should - fail. + This will run `rustc` twice: + - First time is to ensure that the compile succeeds without the codegen phase + - Second time is to ensure that the full compile fails - `//@ run-fail` — compilation should succeed, but running the resulting binary should fail. From c760af1801f31ac90540719b7bbc73436e977651 Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 29 Jun 2025 21:24:25 -0700 Subject: [PATCH 369/447] update AST-to-HIR lowering examples for conditionals and loops - `for` loops now use two `match`es for all of their bindings. I'm not sure this is the most helpful way of conveying that, but it's about as informative as before while staying brief. - `while let` and `if let` don't use `match`; they use `let` expressions in their conditions. Since `if let` no longer has significantly different desugaring and having a whole bullet point for `while` would feel redundant with `for`, I've removed those examples. --- src/hir/lowering.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/hir/lowering.md b/src/hir/lowering.md index 02c69b860..c0057a69c 100644 --- a/src/hir/lowering.md +++ b/src/hir/lowering.md @@ -7,10 +7,8 @@ of such structures include but are not limited to * Parenthesis * Removed without replacement, the tree structure makes order explicit -* `for` loops and `while (let)` loops - * Converted to `loop` + `match` and some `let` bindings -* `if let` - * Converted to `match` +* `for` loops + * Converted to `match` + `loop` + `match` * Universal `impl Trait` * Converted to generic arguments (but with some flags, to know that the user didn't write them) From 8e56733060a96a37f961c42c8f551a7ad9ce697b Mon Sep 17 00:00:00 2001 From: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:08:26 +0200 Subject: [PATCH 370/447] document optional jobs --- src/tests/ci.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tests/ci.md b/src/tests/ci.md index 96e4edc17..894c89b3d 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -148,6 +148,13 @@ for example `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try b glob patterns, you might want to wrap them in backticks (`` ` ``) to avoid GitHub rendering the pattern as Markdown. +The job pattern needs to match one or more jobs defined in the `auto` or `optional` sections +of [`jobs.yml`]: + +- `auto` jobs are executed before a commit is merged into the `master` branch. +- `optional` jobs are executed only when explicitly requested via a try build. + They are typically used for tier 2 and tier 3 targets. + > **Using `try-job` PR description directives** > > 1. Identify which set of try-jobs you would like to exercise. You can From 60e5cfc668dca3476b7956828ea61c40ec6cfd0c Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 1 Jul 2025 18:47:50 +0000 Subject: [PATCH 371/447] Rename mingw-* CI jobs to pr-* --- src/tests/ci.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/ci.md b/src/tests/ci.md index 96e4edc17..1ed790ba0 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -66,8 +66,8 @@ kinds of builds (sets of jobs). ### Pull Request builds After each push to a pull request, a set of `pr` jobs are executed. Currently, -these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `mingw-check-1`, `mingw-check-2` -and `mingw-check-tidy` jobs, all running on Linux. These execute a relatively short +these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `pr-check-1`, `pr-check-2` +and `pr-check-tidy` jobs, all running on Linux. These execute a relatively short (~40 minutes) and lightweight test suite that should catch common issues. More specifically, they run a set of lints, they try to perform a cross-compile check build to Windows mingw (without producing any artifacts) and they test the From c8ae1f7451c702377358631121eeae06efb2df99 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 2 Jul 2025 08:43:10 +0000 Subject: [PATCH 372/447] Rename mingw-check-tidy to tidy --- src/tests/ci.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ci.md b/src/tests/ci.md index 1ed790ba0..eba101a13 100644 --- a/src/tests/ci.md +++ b/src/tests/ci.md @@ -67,7 +67,7 @@ kinds of builds (sets of jobs). After each push to a pull request, a set of `pr` jobs are executed. Currently, these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `pr-check-1`, `pr-check-2` -and `pr-check-tidy` jobs, all running on Linux. These execute a relatively short +and `tidy` jobs, all running on Linux. These execute a relatively short (~40 minutes) and lightweight test suite that should catch common issues. More specifically, they run a set of lints, they try to perform a cross-compile check build to Windows mingw (without producing any artifacts) and they test the From 6265c4594562dde3dbb65cf295253f4ffada8ec3 Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Wed, 2 Jul 2025 16:16:33 -0700 Subject: [PATCH 373/447] update coherence example Signed-off-by: Emmanuel Ferdman --- src/solve/opaque-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solve/opaque-types.md b/src/solve/opaque-types.md index 6898ef3aa..8880962d6 100644 --- a/src/solve/opaque-types.md +++ b/src/solve/opaque-types.md @@ -56,7 +56,7 @@ Finally, we check whether the item bounds of the opaque hold for the expected ty [source][item-bounds-ck]. [norm]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L13 -[coherence-example]: https://github.com/rust-lang/rust/blob/master/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs +[coherence-example]: https://github.com/rust-lang/rust/blob/master/tests/ui/type-alias-impl-trait/coherence/coherence_different_hidden_ty.rs [placeholder-ck]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L33 [check-storage]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L51-L52 [eq-prev]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L51-L59 From 8c8c510d0a6ee8a5382d4981cdd6dd062222aca9 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 2 Jul 2025 15:56:59 +0200 Subject: [PATCH 374/447] minicore: use core's `diagnostic::on_unimplemented` messages --- src/tests/minicore.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tests/minicore.md b/src/tests/minicore.md index def9aaf87..23b772790 100644 --- a/src/tests/minicore.md +++ b/src/tests/minicore.md @@ -39,6 +39,12 @@ If you find a `core` item to be missing from the [`minicore`] stub, consider adding it to the test auxiliary if it's likely to be used or is already needed by more than one test. +## Staying in sync with `core` + +The `minicore` items must be kept up to date with `core`. For consistent +diagnostic output between using `core` and `minicore`, any `diagnostic` +attributes (e.g. `on_unimplemented`) should be replicated exactly in `minicore`. + ## Example codegen test that uses `minicore` ```rust,no_run From 68ea5d75043695532a08ed460fbdf8600b537999 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Thu, 3 Jul 2025 15:30:30 -0700 Subject: [PATCH 375/447] adjust docs, after splitting up autodiff into two forward and reverse macros --- src/autodiff/internals.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/autodiff/internals.md b/src/autodiff/internals.md index 0093ef044..c1b31a0e4 100644 --- a/src/autodiff/internals.md +++ b/src/autodiff/internals.md @@ -2,11 +2,11 @@ The `std::autodiff` module in Rust allows differentiable programming: ```rust #![feature(autodiff)] -use std::autodiff::autodiff; +use std::autodiff::*; // f(x) = x * x, f'(x) = 2.0 * x // bar therefore returns (x * x, 2.0 * x) -#[autodiff(bar, Reverse, Active, Active)] +#[autodiff_reverse(bar, Active, Active)] fn foo(x: f32) -> f32 { x * x } fn main() { From f00758e2ea60da9ef25048c4e323b1dc93bd3586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 4 Jul 2025 10:37:42 +0200 Subject: [PATCH 376/447] Add josh-sync config file --- josh-sync.toml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 josh-sync.toml diff --git a/josh-sync.toml b/josh-sync.toml new file mode 100644 index 000000000..7882051e2 --- /dev/null +++ b/josh-sync.toml @@ -0,0 +1,3 @@ +org = "rust-lang" +repo = "rustc-dev-guide" +path = "src/doc/rustc-dev-guide" From 9d42abe88290e1c962f7283795950b3bb78d3b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 4 Jul 2025 11:07:45 +0200 Subject: [PATCH 377/447] Prepare for merging from rust-lang/rust This updates the rust-version file to c96a69059ecc618b519da385a6ccd03155aa0237. --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index c986141b6..e444613e6 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -bc4376fa73b636eb6f2c7d48b1f731d70f022c4b +c96a69059ecc618b519da385a6ccd03155aa0237 From 02bad6b5fbb19c8c87f56d9428748d197b2b3218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 4 Jul 2025 11:41:19 +0200 Subject: [PATCH 378/447] Remove `josh-sync` tooling and update README --- README.md | 35 +--- josh-sync/Cargo.lock | 430 ------------------------------------------ josh-sync/Cargo.toml | 9 - josh-sync/README.md | 4 - josh-sync/src/main.rs | 41 ---- josh-sync/src/sync.rs | 275 --------------------------- 6 files changed, 5 insertions(+), 789 deletions(-) delete mode 100644 josh-sync/Cargo.lock delete mode 100644 josh-sync/Cargo.toml delete mode 100644 josh-sync/README.md delete mode 100644 josh-sync/src/main.rs delete mode 100644 josh-sync/src/sync.rs diff --git a/README.md b/README.md index 0425c15f8..f11290e44 100644 --- a/README.md +++ b/README.md @@ -72,49 +72,24 @@ including the `` marker at the place where you want the TOC. ## Synchronizing josh subtree with rustc -This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the following commands to synchronize the subtree in both directions. +This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. -You'll need to install `josh-proxy` locally via - -``` -cargo install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04 -``` -Older versions of `josh-proxy` may not round trip commits losslessly so it is important to install this exact version. +You can install the tool using `cargo install --locked --git https://github.com/rust-lang/josh-sync`. ### Pull changes from `rust-lang/rust` into this repository 1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide` 2) Run the pull command ``` - cargo run --manifest-path josh-sync/Cargo.toml rustc-pull + rustc-josh-sync pull ``` 3) Push the branch to your fork and create a PR into `rustc-dev-guide` + - If you have `gh` CLI installed, `rustc-josh-sync` can create the PR for you. ### Push changes from this repository into `rust-lang/rust` -NOTE: If you use Git protocol to push to your fork of `rust-lang/rust`, -ensure that you have this entry in your Git config, -else the 2 steps that follow would prompt for a username and password: - -``` -[url "git@github.com:"] -insteadOf = "https://github.com/" -``` - 1) Run the push command to create a branch named `` in a `rustc` fork under the `` account ``` - cargo run --manifest-path josh-sync/Cargo.toml rustc-push + rustc-josh-sync push ``` 2) Create a PR from `` into `rust-lang/rust` - -#### Minimal git config - -For simplicity (ease of implementation purposes), the josh-sync script simply calls out to system git. This means that the git invocation may be influenced by global (or local) git configuration. - -You may observe "Nothing to pull" even if you *know* rustc-pull has something to pull if your global git config sets `fetch.prunetags = true` (and possibly other configurations may cause unexpected outcomes). - -To minimize the likelihood of this happening, you may wish to keep a separate *minimal* git config that *only* has `[user]` entries from global git config, then repoint system git to use the minimal git config instead. E.g. - -``` -GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull -``` diff --git a/josh-sync/Cargo.lock b/josh-sync/Cargo.lock deleted file mode 100644 index a8183a740..000000000 --- a/josh-sync/Cargo.lock +++ /dev/null @@ -1,430 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "anstream" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" - -[[package]] -name = "anstyle-parse" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" -dependencies = [ - "anstyle", - "windows-sys 0.59.0", -] - -[[package]] -name = "anyhow" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "4.5.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" - -[[package]] -name = "colorchoice" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" - -[[package]] -name = "directories" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "josh-sync" -version = "0.0.0" -dependencies = [ - "anyhow", - "clap", - "directories", - "xshell", -] - -[[package]] -name = "libc" -version = "0.2.169" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags", - "libc", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "proc-macro2" -version = "1.0.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "syn" -version = "2.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "unicode-ident" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "xshell" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e7290c623014758632efe00737145b6867b66292c42167f2ec381eb566a373d" -dependencies = [ - "xshell-macros", -] - -[[package]] -name = "xshell-macros" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac00cd3f8ec9c1d33fb3e7958a82df6989c42d747bd326c822b1d625283547" diff --git a/josh-sync/Cargo.toml b/josh-sync/Cargo.toml deleted file mode 100644 index 1f8bf2a00..000000000 --- a/josh-sync/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "josh-sync" -edition = "2024" - -[dependencies] -anyhow = "1.0.95" -clap = { version = "4.5.21", features = ["derive"] } -directories = "5" -xshell = "0.2.6" diff --git a/josh-sync/README.md b/josh-sync/README.md deleted file mode 100644 index a3dd876e8..000000000 --- a/josh-sync/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Git josh sync -This utility serves for syncing the josh git subtree to and from the rust-lang/rust repository. - -See CLI help for usage. diff --git a/josh-sync/src/main.rs b/josh-sync/src/main.rs deleted file mode 100644 index aeedee5be..000000000 --- a/josh-sync/src/main.rs +++ /dev/null @@ -1,41 +0,0 @@ -use clap::Parser; - -use crate::sync::{GitSync, RustcPullError}; - -mod sync; - -#[derive(clap::Parser)] -enum Args { - /// Pull changes from the main `rustc` repository. - /// This creates new commits that should be then merged into `rustc-dev-guide`. - RustcPull, - /// Push changes from `rustc-dev-guide` to the given `branch` of a `rustc` fork under the given - /// GitHub `username`. - /// The pushed branch should then be merged into the `rustc` repository. - RustcPush { branch: String, github_username: String }, -} - -fn main() -> anyhow::Result<()> { - let args = Args::parse(); - let sync = GitSync::from_current_dir()?; - match args { - Args::RustcPull => { - if let Err(error) = sync.rustc_pull(None) { - match error { - RustcPullError::NothingToPull => { - eprintln!("Nothing to pull"); - std::process::exit(2); - } - RustcPullError::PullFailed(error) => { - eprintln!("Pull failure: {error:?}"); - std::process::exit(1); - } - } - } - } - Args::RustcPush { github_username, branch } => { - sync.rustc_push(github_username, branch)?; - } - } - Ok(()) -} diff --git a/josh-sync/src/sync.rs b/josh-sync/src/sync.rs deleted file mode 100644 index ed38d1403..000000000 --- a/josh-sync/src/sync.rs +++ /dev/null @@ -1,275 +0,0 @@ -use std::io::Write; -use std::ops::Not; -use std::path::PathBuf; -use std::time::Duration; -use std::{env, net, process}; - -use anyhow::{Context, anyhow, bail}; -use xshell::{Shell, cmd}; - -/// Used for rustc syncs. -const JOSH_FILTER: &str = ":/src/doc/rustc-dev-guide"; -const JOSH_PORT: u16 = 42042; -const UPSTREAM_REPO: &str = "rust-lang/rust"; - -pub enum RustcPullError { - /// No changes are available to be pulled. - NothingToPull, - /// A rustc-pull has failed, probably a git operation error has occurred. - PullFailed(anyhow::Error), -} - -impl From for RustcPullError -where - E: Into, -{ - fn from(error: E) -> Self { - Self::PullFailed(error.into()) - } -} - -pub struct GitSync { - dir: PathBuf, -} - -/// This code was adapted from the miri repository -/// (https://github.com/rust-lang/miri/blob/6a68a79f38064c3bc30617cca4bdbfb2c336b140/miri-script/src/commands.rs#L236). -impl GitSync { - pub fn from_current_dir() -> anyhow::Result { - Ok(Self { dir: std::env::current_dir()? }) - } - - pub fn rustc_pull(&self, commit: Option) -> Result<(), RustcPullError> { - let sh = Shell::new()?; - sh.change_dir(&self.dir); - let commit = commit.map(Ok).unwrap_or_else(|| { - let rust_repo_head = - cmd!(sh, "git ls-remote https://github.com/{UPSTREAM_REPO}/ HEAD").read()?; - rust_repo_head - .split_whitespace() - .next() - .map(|front| front.trim().to_owned()) - .ok_or_else(|| anyhow!("Could not obtain Rust repo HEAD from remote.")) - })?; - // Make sure the repo is clean. - if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() { - return Err(anyhow::anyhow!( - "working directory must be clean before performing rustc pull" - ) - .into()); - } - // Make sure josh is running. - let josh = Self::start_josh()?; - let josh_url = - format!("http://localhost:{JOSH_PORT}/{UPSTREAM_REPO}.git@{commit}{JOSH_FILTER}.git"); - - let previous_base_commit = sh.read_file("rust-version")?.trim().to_string(); - if previous_base_commit == commit { - return Err(RustcPullError::NothingToPull); - } - - // Update rust-version file. As a separate commit, since making it part of - // the merge has confused the heck out of josh in the past. - // We pass `--no-verify` to avoid running git hooks. - // We do this before the merge so that if there are merge conflicts, we have - // the right rust-version file while resolving them. - sh.write_file("rust-version", format!("{commit}\n"))?; - const PREPARING_COMMIT_MESSAGE: &str = "Preparing for merge from rustc"; - cmd!(sh, "git commit rust-version --no-verify -m {PREPARING_COMMIT_MESSAGE}") - .run() - .context("FAILED to commit rust-version file, something went wrong")?; - - // Fetch given rustc commit. - cmd!(sh, "git fetch {josh_url}") - .run() - .inspect_err(|_| { - // Try to un-do the previous `git commit`, to leave the repo in the state we found it. - cmd!(sh, "git reset --hard HEAD^") - .run() - .expect("FAILED to clean up again after failed `git fetch`, sorry for that"); - }) - .context("FAILED to fetch new commits, something went wrong (committing the rust-version file has been undone)")?; - - // This should not add any new root commits. So count those before and after merging. - let num_roots = || -> anyhow::Result { - Ok(cmd!(sh, "git rev-list HEAD --max-parents=0 --count") - .read() - .context("failed to determine the number of root commits")? - .parse::()?) - }; - let num_roots_before = num_roots()?; - - let sha = - cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout; - - // Merge the fetched commit. - const MERGE_COMMIT_MESSAGE: &str = "Merge from rustc"; - cmd!(sh, "git merge FETCH_HEAD --no-verify --no-ff -m {MERGE_COMMIT_MESSAGE}") - .run() - .context("FAILED to merge new commits, something went wrong")?; - - let current_sha = - cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout; - if current_sha == sha { - cmd!(sh, "git reset --hard HEAD^") - .run() - .expect("FAILED to clean up after creating the preparation commit"); - eprintln!( - "No merge was performed, no changes to pull were found. Rolled back the preparation commit." - ); - return Err(RustcPullError::NothingToPull); - } - - // Check that the number of roots did not increase. - if num_roots()? != num_roots_before { - return Err(anyhow::anyhow!( - "Josh created a new root commit. This is probably not the history you want." - ) - .into()); - } - - drop(josh); - Ok(()) - } - - pub fn rustc_push(&self, github_user: String, branch: String) -> anyhow::Result<()> { - let sh = Shell::new()?; - sh.change_dir(&self.dir); - let base = sh.read_file("rust-version")?.trim().to_owned(); - // Make sure the repo is clean. - if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() { - bail!("working directory must be clean before running `rustc-push`"); - } - // Make sure josh is running. - let josh = Self::start_josh()?; - let josh_url = - format!("http://localhost:{JOSH_PORT}/{github_user}/rust.git{JOSH_FILTER}.git"); - - // Find a repo we can do our preparation in. - if let Ok(rustc_git) = env::var("RUSTC_GIT") { - // If rustc_git is `Some`, we'll use an existing fork for the branch updates. - sh.change_dir(rustc_git); - } else { - // Otherwise, do this in the local repo. - println!( - "This will pull a copy of the rust-lang/rust history into this checkout, growing it by about 1GB." - ); - print!( - "To avoid that, abort now and set the `RUSTC_GIT` environment variable to an existing rustc checkout. Proceed? [y/N] " - ); - std::io::stdout().flush()?; - let mut answer = String::new(); - std::io::stdin().read_line(&mut answer)?; - if answer.trim().to_lowercase() != "y" { - std::process::exit(1); - } - }; - // Prepare the branch. Pushing works much better if we use as base exactly - // the commit that we pulled from last time, so we use the `rust-version` - // file to find out which commit that would be. - println!("Preparing {github_user}/rust (base: {base})..."); - if cmd!(sh, "git fetch https://github.com/{github_user}/rust {branch}") - .ignore_stderr() - .read() - .is_ok() - { - println!( - "The branch '{branch}' seems to already exist in 'https://github.com/{github_user}/rust'. Please delete it and try again." - ); - std::process::exit(1); - } - cmd!(sh, "git fetch https://github.com/{UPSTREAM_REPO} {base}").run()?; - cmd!(sh, "git push https://github.com/{github_user}/rust {base}:refs/heads/{branch}") - .ignore_stdout() - .ignore_stderr() // silence the "create GitHub PR" message - .run()?; - println!(); - - // Do the actual push. - sh.change_dir(&self.dir); - println!("Pushing changes..."); - cmd!(sh, "git push {josh_url} HEAD:{branch}").run()?; - println!(); - - // Do a round-trip check to make sure the push worked as expected. - cmd!(sh, "git fetch {josh_url} {branch}").ignore_stderr().read()?; - let head = cmd!(sh, "git rev-parse HEAD").read()?; - let fetch_head = cmd!(sh, "git rev-parse FETCH_HEAD").read()?; - if head != fetch_head { - bail!( - "Josh created a non-roundtrip push! Do NOT merge this into rustc!\n\ - Expected {head}, got {fetch_head}." - ); - } - println!( - "Confirmed that the push round-trips back to rustc-dev-guide properly. Please create a rustc PR:" - ); - println!( - // Open PR with `subtree update` title to silence the `no-merges` triagebot check - " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=rustc-dev-guide+subtree+update&body=r?+@ghost" - ); - - drop(josh); - Ok(()) - } - - fn start_josh() -> anyhow::Result { - // Determine cache directory. - let local_dir = { - let user_dirs = - directories::ProjectDirs::from("org", "rust-lang", "rustc-dev-guide-josh").unwrap(); - user_dirs.cache_dir().to_owned() - }; - - // Start josh, silencing its output. - let mut cmd = process::Command::new("josh-proxy"); - cmd.arg("--local").arg(local_dir); - cmd.arg("--remote").arg("https://github.com"); - cmd.arg("--port").arg(JOSH_PORT.to_string()); - cmd.arg("--no-background"); - cmd.stdout(process::Stdio::null()); - cmd.stderr(process::Stdio::null()); - let josh = cmd.spawn().context("failed to start josh-proxy, make sure it is installed")?; - - // Create a wrapper that stops it on drop. - struct Josh(process::Child); - impl Drop for Josh { - fn drop(&mut self) { - #[cfg(unix)] - { - // Try to gracefully shut it down. - process::Command::new("kill") - .args(["-s", "INT", &self.0.id().to_string()]) - .output() - .expect("failed to SIGINT josh-proxy"); - // Sadly there is no "wait with timeout"... so we just give it some time to finish. - std::thread::sleep(Duration::from_millis(100)); - // Now hopefully it is gone. - if self.0.try_wait().expect("failed to wait for josh-proxy").is_some() { - return; - } - } - // If that didn't work (or we're not on Unix), kill it hard. - eprintln!( - "I have to kill josh-proxy the hard way, let's hope this does not break anything." - ); - self.0.kill().expect("failed to SIGKILL josh-proxy"); - } - } - - // Wait until the port is open. We try every 10ms until 1s passed. - for _ in 0..100 { - // This will generally fail immediately when the port is still closed. - let josh_ready = net::TcpStream::connect_timeout( - &net::SocketAddr::from(([127, 0, 0, 1], JOSH_PORT)), - Duration::from_millis(1), - ); - if josh_ready.is_ok() { - return Ok(Josh(josh)); - } - // Not ready yet. - std::thread::sleep(Duration::from_millis(10)); - } - bail!("Even after waiting for 1s, josh-proxy is still not available.") - } -} From 2045165e80e94e316ae3efa4d31fd4f8d169b0e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 4 Jul 2025 11:44:58 +0200 Subject: [PATCH 379/447] Update CI workflow to use rustc-josh-sync --- .github/workflows/rustc-pull.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index 1e430d8b4..7190fc733 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -24,11 +24,10 @@ jobs: run: rustup update stable - uses: Swatinem/rust-cache@v2 with: - workspaces: "josh-sync" # Cache the josh directory with checked out rustc - cache-directories: "/home/runner/.cache/rustc-dev-guide-josh" - - name: Install josh - run: RUSTFLAGS="--cap-lints warn" cargo install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04 + cache-directories: "/home/runner/.cache/rustc-josh" + - name: Install rustc-josh-sync + run: cargo install --locked --git https://github.com/rust-lang/josh-sync - name: Setup bot git name and email run: | git config --global user.name 'The rustc-dev-guide Cronjob Bot' @@ -38,7 +37,7 @@ jobs: # Turn off -e to disable early exit shell: bash {0} run: | - cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull + rustc-josh-sync pull exitcode=$? # If no pull was performed, we want to mark this job as successful, From 6851554e7a9c0396b6002d66d5fef2c88ccfde13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 4 Jul 2025 13:14:23 +0200 Subject: [PATCH 380/447] Document `rustc-josh-sync` --- README.md | 20 +------------- src/external-repos.md | 62 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index f11290e44..5932da467 100644 --- a/README.md +++ b/README.md @@ -74,22 +74,4 @@ including the `` marker at the place where you want the TOC. This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. -You can install the tool using `cargo install --locked --git https://github.com/rust-lang/josh-sync`. - -### Pull changes from `rust-lang/rust` into this repository - -1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide` -2) Run the pull command - ``` - rustc-josh-sync pull - ``` -3) Push the branch to your fork and create a PR into `rustc-dev-guide` - - If you have `gh` CLI installed, `rustc-josh-sync` can create the PR for you. - -### Push changes from this repository into `rust-lang/rust` - -1) Run the push command to create a branch named `` in a `rustc` fork under the `` account - ``` - rustc-josh-sync push - ``` -2) Create a PR from `` into `rust-lang/rust` +You can find a guide on how to perform the synchronization [here](./src/external-repos.md#synchronizing-a-josh-subtree). diff --git a/src/external-repos.md b/src/external-repos.md index f3170c922..a19b1116d 100644 --- a/src/external-repos.md +++ b/src/external-repos.md @@ -9,7 +9,7 @@ There are three main ways we use dependencies: As a general rule: - Use crates.io for libraries that could be useful for others in the ecosystem - Use subtrees for tools that depend on compiler internals and need to be updated if there are breaking -changes + changes - Use submodules for tools that are independent of the compiler ## External Dependencies (subtrees) @@ -23,6 +23,8 @@ The following external projects are managed using some form of a `subtree`: * [rust-analyzer](https://github.com/rust-lang/rust-analyzer) * [rustc_codegen_cranelift](https://github.com/rust-lang/rustc_codegen_cranelift) * [rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide) +* [compiler-builtins](https://github.com/rust-lang/compiler-builtins) +* [stdarch](https://github.com/rust-lang/stdarch) In contrast to `submodule` dependencies (see below for those), the `subtree` dependencies are just regular files and directories which can @@ -34,20 +36,57 @@ implement a new tool feature or test, that should happen in one collective rustc `subtree` dependencies are currently managed by two distinct approaches: * Using `git subtree` - * `clippy` ([sync guide](https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html#performing-the-sync-from-rust-langrust-to-clippy)) - * `portable-simd` ([sync script](https://github.com/rust-lang/portable-simd/blob/master/subtree-sync.sh)) - * `rustfmt` - * `rustc_codegen_cranelift` ([sync script](https://github.com/rust-lang/rustc_codegen_cranelift/blob/113af154d459e41b3dc2c5d7d878e3d3a8f33c69/scripts/rustup.sh#L7)) + * `clippy` ([sync guide](https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html#performing-the-sync-from-rust-langrust-to-clippy)) + * `portable-simd` ([sync script](https://github.com/rust-lang/portable-simd/blob/master/subtree-sync.sh)) + * `rustfmt` + * `rustc_codegen_cranelift` ([sync script](https://github.com/rust-lang/rustc_codegen_cranelift/blob/113af154d459e41b3dc2c5d7d878e3d3a8f33c69/scripts/rustup.sh#L7)) * Using the [josh] tool - * `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo)) - * `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147)) - * `rustc-dev-guide` ([sync guide](https://github.com/rust-lang/rustc-dev-guide#synchronizing-josh-subtree-with-rustc)) + * `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo)) + * `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147)) + * `rustc-dev-guide` + * `compiler-builtins` + * `stdarch` -The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh, you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. If you want to migrate a repository dependency from `git subtree` or `git submodule` to josh, you can check out [this guide](https://hackmd.io/7pOuxnkdQDaL1Y1FQr65xg). +### Josh subtrees -Below you can find a guide on how to perform push and pull synchronization with the main rustc repo using `git subtree`, although these instructions might differ repo from repo. +The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh, you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. We provide a helper [`rustc-josh-sync`][josh-sync] tool to help with the synchronization, it is described [below](#synchronizing-a-josh-subtree). -### Synchronizing a subtree +### Synchronizing a Josh subtree + +We use a dedicated tool called [`rustc-josh-sync`][josh-sync] for performing Josh subtree updates. +Currently, we are migrating Josh repositories to it. So far, it is used in: + +- rustc-dev-guide + +To use the tool, first install it with `cargo install --locked --git https://github. +com/rust-lang/josh-sync`. + +Both pulls (synchronize changes from rust-lang/rust into the subtree) and pushes (synchronize +changes from the subtree to rust-lang/rust) are performed from the subtree repository (so first +switch to its repository checkout directory in your terminal). + +#### Performing pull +1) Checkout a new branch that will be used to create a PR into the subtree +2) Run the pull command + ``` + rustc-josh-sync pull + ``` +3) Push the branch to your fork and create a PR into the subtree repository + - If you have `gh` CLI installed, `rustc-josh-sync` can create the PR for you. + +#### Performing push + +1) Run the push command to create a branch named `` in a `rustc` fork under the `` account + ``` + rustc-josh-sync push + ``` +2) Create a PR from `` into `rust-lang/rust` + +### Creating a new Josh subtree dependency + +If you want to migrate a repository dependency from `git subtree` or `git submodule` to josh, you can check out [this guide](https://hackmd.io/7pOuxnkdQDaL1Y1FQr65xg). + +### Synchronizing a git subtree Periodically the changes made to subtree based dependencies need to be synchronized between this repository and the upstream tool repositories. @@ -129,3 +168,4 @@ the week leading up to the beta cut. [toolstate website]: https://rust-lang-nursery.github.io/rust-toolstate/ [Toolstate chapter]: https://forge.rust-lang.org/infra/toolstate.html [josh]: https://josh-project.github.io/josh/intro.html +[josh-sync]: https://github.com/rust-lang/josh-sync From 885a151803892f5da14f1af188a1bd8fa35a76c1 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 4 Jul 2025 14:13:15 +0200 Subject: [PATCH 381/447] external-repos.md: small fixes --- src/external-repos.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/external-repos.md b/src/external-repos.md index a19b1116d..fc40b5d2b 100644 --- a/src/external-repos.md +++ b/src/external-repos.md @@ -49,7 +49,7 @@ implement a new tool feature or test, that should happen in one collective rustc ### Josh subtrees -The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh, you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. We provide a helper [`rustc-josh-sync`][josh-sync] tool to help with the synchronization, it is described [below](#synchronizing-a-josh-subtree). +The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh; you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. We provide a helper [`rustc-josh-sync`][josh-sync] tool to help with the synchronization, described [below](#synchronizing-a-josh-subtree). ### Synchronizing a Josh subtree @@ -58,8 +58,7 @@ Currently, we are migrating Josh repositories to it. So far, it is used in: - rustc-dev-guide -To use the tool, first install it with `cargo install --locked --git https://github. -com/rust-lang/josh-sync`. +To use the tool, first install it with `cargo install --locked --git https://github.com/rust-lang/josh-sync`. Both pulls (synchronize changes from rust-lang/rust into the subtree) and pushes (synchronize changes from the subtree to rust-lang/rust) are performed from the subtree repository (so first From 9813a6eb79512a2d548762a712a0c18931508c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 8 Jul 2025 08:57:05 +0200 Subject: [PATCH 382/447] Mention that stdarch is managed by josh-sync --- src/external-repos.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/external-repos.md b/src/external-repos.md index fc40b5d2b..0f7322357 100644 --- a/src/external-repos.md +++ b/src/external-repos.md @@ -43,9 +43,9 @@ implement a new tool feature or test, that should happen in one collective rustc * Using the [josh] tool * `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo)) * `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147)) - * `rustc-dev-guide` + * `rustc-dev-guide` ([josh sync](#synchronizing-a-josh-subtree)) * `compiler-builtins` - * `stdarch` + * `stdarch` ([josh sync](#synchronizing-a-josh-subtree)) ### Josh subtrees @@ -57,6 +57,7 @@ We use a dedicated tool called [`rustc-josh-sync`][josh-sync] for performing Jos Currently, we are migrating Josh repositories to it. So far, it is used in: - rustc-dev-guide +- stdarch To use the tool, first install it with `cargo install --locked --git https://github.com/rust-lang/josh-sync`. From bdd6961d3239d1cbef4d18691c9cfaebf22e0098 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 9 Jul 2025 07:13:44 +0200 Subject: [PATCH 383/447] use a consistent (and recommended) invocation ./x is recommended over running ./x.py directly, and is the more commonly-used invocation of bootstrap in the guide --- src/autodiff/installation.md | 10 +++++----- src/offload/installation.md | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/autodiff/installation.md b/src/autodiff/installation.md index c9b28dc43..92e79b2f3 100644 --- a/src/autodiff/installation.md +++ b/src/autodiff/installation.md @@ -13,7 +13,7 @@ cd rust Afterwards you can build rustc using: ```bash -./x.py build --stage 1 library +./x build --stage 1 library ``` Afterwards rustc toolchain link will allow you to use it through cargo: @@ -25,10 +25,10 @@ rustup toolchain install nightly # enables -Z unstable-options You can then run our test cases: ```bash -./x.py test --stage 1 tests/codegen/autodiff -./x.py test --stage 1 tests/pretty/autodiff -./x.py test --stage 1 tests/ui/autodiff -./x.py test --stage 1 tests/ui/feature-gates/feature-gate-autodiff.rs +./x test --stage 1 tests/codegen/autodiff +./x test --stage 1 tests/pretty/autodiff +./x test --stage 1 tests/ui/autodiff +./x test --stage 1 tests/ui/feature-gates/feature-gate-autodiff.rs ``` Autodiff is still experimental, so if you want to use it in your own projects, you will need to add `lto="fat"` to your Cargo.toml diff --git a/src/offload/installation.md b/src/offload/installation.md index 2536af09a..8cfec44ec 100644 --- a/src/offload/installation.md +++ b/src/offload/installation.md @@ -13,7 +13,7 @@ cd rust Afterwards you can build rustc using: ```bash -./x.py build --stage 1 library +./x build --stage 1 library ``` Afterwards rustc toolchain link will allow you to use it through cargo: @@ -40,7 +40,7 @@ This gives you a working LLVM build. ## Testing run ``` -./x.py test --stage 1 tests/codegen/gpu_offload +./x test --stage 1 tests/codegen/gpu_offload ``` ## Usage From 68e9ce34fa5735a17e7571fa47f95edee8c44500 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 9 Jul 2025 07:28:16 +0200 Subject: [PATCH 384/447] tweak some git clone commands - --depth=1 is more useful for once-off uses, like on ci - .git postfix on github repo url is not needed --- src/autodiff/installation.md | 8 ++++---- src/offload/installation.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/autodiff/installation.md b/src/autodiff/installation.md index 92e79b2f3..a550f6d23 100644 --- a/src/autodiff/installation.md +++ b/src/autodiff/installation.md @@ -6,7 +6,7 @@ In the near future, `std::autodiff` should become available in nightly builds fo First you need to clone and configure the Rust repository: ```bash -git clone --depth=1 git@github.com:rust-lang/rust.git +git clone git@github.com:rust-lang/rust cd rust ./configure --enable-llvm-link-shared --enable-llvm-plugins --enable-llvm-enzyme --release-channel=nightly --enable-llvm-assertions --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs ``` @@ -45,7 +45,7 @@ apt install wget vim python3 git curl libssl-dev pkg-config lld ninja-build cmak ``` Then build rustc in a slightly altered way: ```bash -git clone --depth=1 https://github.com/rust-lang/rust.git +git clone https://github.com/rust-lang/rust cd rust ./configure --enable-llvm-link-shared --enable-llvm-plugins --enable-llvm-enzyme --release-channel=nightly --enable-llvm-assertions --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs ./x dist @@ -66,7 +66,7 @@ We recommend that approach, if you just want to use any of them and have no expe However, if you prefer to just build Enzyme without Rust, then these instructions might help. ```bash -git clone --depth=1 git@github.com:llvm/llvm-project.git +git clone git@github.com:llvm/llvm-project cd llvm-project mkdir build cd build @@ -77,7 +77,7 @@ ninja install This gives you a working LLVM build, now we can continue with building Enzyme. Leave the `llvm-project` folder, and execute the following commands: ```bash -git clone git@github.com:EnzymeAD/Enzyme.git +git clone git@github.com:EnzymeAD/Enzyme cd Enzyme/enzyme mkdir build cd build diff --git a/src/offload/installation.md b/src/offload/installation.md index 8cfec44ec..1962314c7 100644 --- a/src/offload/installation.md +++ b/src/offload/installation.md @@ -6,7 +6,7 @@ In the future, `std::offload` should become available in nightly builds for user First you need to clone and configure the Rust repository: ```bash -git clone --depth=1 git@github.com:rust-lang/rust.git +git clone git@github.com:rust-lang/rust cd rust ./configure --enable-llvm-link-shared --release-channel=nightly --enable-llvm-assertions --enable-offload --enable-enzyme --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs ``` @@ -26,7 +26,7 @@ rustup toolchain install nightly # enables -Z unstable-options ## Build instruction for LLVM itself ```bash -git clone --depth=1 git@github.com:llvm/llvm-project.git +git clone git@github.com:llvm/llvm-project cd llvm-project mkdir build cd build From 319e4c62796ff7b3067d38074ebb40c9d4a8dc83 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 9 Jul 2025 22:49:41 +0200 Subject: [PATCH 385/447] add missing word --- src/tests/misc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/misc.md b/src/tests/misc.md index c0288b3dd..39f881748 100644 --- a/src/tests/misc.md +++ b/src/tests/misc.md @@ -9,7 +9,7 @@ for testing: - `RUSTC_BOOTSTRAP=1` will "cheat" and bypass usual stability checking, allowing you to use unstable features and cli flags on a stable `rustc`. -- `RUSTC_BOOTSTRAP=-1` will force a given `rustc` to pretend that is a stable +- `RUSTC_BOOTSTRAP=-1` will force a given `rustc` to pretend it is a stable compiler, even if it's actually a nightly `rustc`. This is useful because some behaviors of the compiler (e.g. diagnostics) can differ depending on whether the compiler is nightly or not. From a54c0032e6ef6d5d31b1f4ad085ad1d5947ca1d0 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 9 Jul 2025 23:02:16 +0200 Subject: [PATCH 386/447] distcheck had only one possible invocation That is, calling it an example is misleading --- src/tests/intro.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/intro.md b/src/tests/intro.md index c55d60f4a..e97574f02 100644 --- a/src/tests/intro.md +++ b/src/tests/intro.md @@ -116,7 +116,9 @@ This requires building all of the documentation, which might take a while. `distcheck` verifies that the source distribution tarball created by the build system will unpack, build, and run all tests. -> Example: `./x test distcheck` +```console +./x test distcheck +``` ### Tool tests From 6e12d8a2b4354ba6a3339f5d7edcb25b7b9fbddd Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 9 Jul 2025 23:03:37 +0200 Subject: [PATCH 387/447] do not invent a name Nowhere else is this called "Dist check" --- src/tests/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/intro.md b/src/tests/intro.md index c55d60f4a..84f99e946 100644 --- a/src/tests/intro.md +++ b/src/tests/intro.md @@ -111,7 +111,7 @@ and it can be invoked so: This requires building all of the documentation, which might take a while. -### Dist check +### `distcheck` `distcheck` verifies that the source distribution tarball created by the build system will unpack, build, and run all tests. From 6f6b339f6c33db82d89f336bab363e8bb25a6585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 10 Jul 2025 09:56:59 +0200 Subject: [PATCH 388/447] Mention that compiler-builtins is now using `rustc-josh-sync` --- src/external-repos.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/external-repos.md b/src/external-repos.md index 0f7322357..68986a0bc 100644 --- a/src/external-repos.md +++ b/src/external-repos.md @@ -44,7 +44,7 @@ implement a new tool feature or test, that should happen in one collective rustc * `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo)) * `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147)) * `rustc-dev-guide` ([josh sync](#synchronizing-a-josh-subtree)) - * `compiler-builtins` + * `compiler-builtins` ([josh sync](#synchronizing-a-josh-subtree)) * `stdarch` ([josh sync](#synchronizing-a-josh-subtree)) ### Josh subtrees @@ -56,6 +56,7 @@ The [josh] tool is an alternative to git subtrees, which manages git history in We use a dedicated tool called [`rustc-josh-sync`][josh-sync] for performing Josh subtree updates. Currently, we are migrating Josh repositories to it. So far, it is used in: +- compiler-builtins - rustc-dev-guide - stdarch From 82c5c43133349e92b27b23de6b5955b2c1c4a104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 10 Jul 2025 10:02:39 +0200 Subject: [PATCH 389/447] Migrate rustc-pull to CI workflow from `josh-sync` --- .github/workflows/rustc-pull.yml | 111 +++---------------------------- 1 file changed, 9 insertions(+), 102 deletions(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index 7190fc733..ad570ee45 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -9,105 +9,12 @@ on: jobs: pull: if: github.repository == 'rust-lang/rustc-dev-guide' - runs-on: ubuntu-latest - outputs: - pr_url: ${{ steps.update-pr.outputs.pr_url }} - permissions: - contents: write - pull-requests: write - steps: - - uses: actions/checkout@v4 - with: - # We need the full history for josh to work - fetch-depth: '0' - - name: Install stable Rust toolchain - run: rustup update stable - - uses: Swatinem/rust-cache@v2 - with: - # Cache the josh directory with checked out rustc - cache-directories: "/home/runner/.cache/rustc-josh" - - name: Install rustc-josh-sync - run: cargo install --locked --git https://github.com/rust-lang/josh-sync - - name: Setup bot git name and email - run: | - git config --global user.name 'The rustc-dev-guide Cronjob Bot' - git config --global user.email 'github-actions@github.com' - - name: Perform rustc-pull - id: rustc-pull - # Turn off -e to disable early exit - shell: bash {0} - run: | - rustc-josh-sync pull - exitcode=$? - - # If no pull was performed, we want to mark this job as successful, - # but we do not want to perform the follow-up steps. - if [ $exitcode -eq 0 ]; then - echo "pull_result=pull-finished" >> $GITHUB_OUTPUT - elif [ $exitcode -eq 2 ]; then - echo "pull_result=skipped" >> $GITHUB_OUTPUT - exitcode=0 - fi - - exit ${exitcode} - - name: Push changes to a branch - if: ${{ steps.rustc-pull.outputs.pull_result == 'pull-finished' }} - run: | - # Update a sticky branch that is used only for rustc pulls - BRANCH="rustc-pull" - git switch -c $BRANCH - git push -u origin $BRANCH --force - - name: Create pull request - id: update-pr - if: ${{ steps.rustc-pull.outputs.pull_result == 'pull-finished' }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Check if an open pull request for an rustc pull update already exists - # If it does, the previous push has just updated it - # If not, we create it now - RESULT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | length' --json title` - if [[ "$RESULT" -eq 0 ]]; then - echo "Creating new pull request" - PR_URL=`gh pr create -B master --title 'Rustc pull update' --body 'Latest update from rustc.'` - echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT - else - PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title` - echo "Updating pull request ${PR_URL}" - echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT - fi - send-zulip-message: - needs: [pull] - if: ${{ !cancelled() }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Compute message - id: create-message - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - if [ "${{ needs.pull.result }}" == "failure" ]; then - WORKFLOW_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - echo "message=Rustc pull sync failed. Check out the [workflow URL]($WORKFLOW_URL)." >> $GITHUB_OUTPUT - else - CREATED_AT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].createdAt' --json createdAt,title` - PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title` - week_ago=$(date +%F -d '7 days ago') - - # If there is an open PR that is at least a week old, post a message about it - if [[ -n $DATE_GH && $DATE_GH < $week_ago ]]; then - echo "message=A PR with a Rustc pull has been opened for more a week. Check out the [PR](${PR_URL})." >> $GITHUB_OUTPUT - fi - fi - - name: Send a Zulip message about updated PR - if: ${{ steps.create-message.outputs.message != '' }} - uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 - with: - api-key: ${{ secrets.ZULIP_API_TOKEN }} - email: "rustc-dev-guide-gha-notif-bot@rust-lang.zulipchat.com" - organization-url: "https://rust-lang.zulipchat.com" - to: 196385 - type: "stream" - topic: "Subtree sync automation" - content: ${{ steps.create-message.outputs.message }} + uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main + with: + 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 }} From e394ebe3121610a823cf0e976feba5c30ebd29e3 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 10 Jul 2025 18:23:23 +0530 Subject: [PATCH 390/447] update rust-dev-guide to point about new command execution summary report under bootstrap profiling section --- src/building/bootstrapping/debugging-bootstrap.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/building/bootstrapping/debugging-bootstrap.md b/src/building/bootstrapping/debugging-bootstrap.md index ed2678504..c9c0d64a6 100644 --- a/src/building/bootstrapping/debugging-bootstrap.md +++ b/src/building/bootstrapping/debugging-bootstrap.md @@ -168,10 +168,17 @@ For `#[instrument]`, it's recommended to: ### Profiling bootstrap -You can use the `COMMAND` tracing target to trace execution of most commands spawned by bootstrap. If you also use the `BOOTSTRAP_PROFILE=1` environment variable, bootstrap will generate a Chrome JSON trace file, which can be visualized in Chrome's `chrome://tracing` page or on https://ui.perfetto.dev. +You can set the `BOOTSTRAP_PROFILE=1` environment variable to enable command execution profiling during bootstrap. This generates: + +* A Chrome trace file (for visualization in `chrome://tracing` or [Perfetto](https://ui.perfetto.dev)) if tracing is enabled via `BOOTSTRAP_TRACING=COMMAND=trace` +* A plain-text summary file, `bootstrap-profile-{pid}.txt`, listing all commands sorted by execution time (slowest first), along with cache hits and working directories + +Note: the `.txt` report is always generated when `BOOTSTRAP_PROFILE=1` is set — tracing is not required. + +Example usage: ```bash -$ BOOTSTRAP_TRACING=COMMAND=trace BOOTSTRAP_PROFILE=1 ./x build library +$ BOOTSTRAP_PROFILE=1 BOOTSTRAP_TRACING=COMMAND=trace ./x build library ``` ### rust-analyzer integration? From 222682fa5701816193b81387f628cf10352cface Mon Sep 17 00:00:00 2001 From: lolbinarycat Date: Fri, 11 Jul 2025 13:39:39 -0500 Subject: [PATCH 391/447] directives.md: build-aux-docs does not work with aux-crate --- src/tests/directives.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 839076b80..63aa08c38 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -59,7 +59,7 @@ not be exhaustive. Directives can generally be found by browsing the | `aux-crate` | Like `aux-build` but makes available as extern prelude | All except `run-make` | `=` | | `aux-codegen-backend` | Similar to `aux-build` but pass the compiled dylib to `-Zcodegen-backend` when building the main file | `ui-fulldeps` | Path to codegen backend file | | `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 | All except `run-make` | N/A | +| `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. From 557ffa14d8e0625c0c318f8d1f68578540f5b49f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sat, 12 Jul 2025 19:36:22 +0200 Subject: [PATCH 392/447] Compiletest: Simplify {Html,Json}DocCk directive handling --- src/rustdoc-internals/rustdoc-test-suite.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rustdoc-internals/rustdoc-test-suite.md b/src/rustdoc-internals/rustdoc-test-suite.md index b05318ce9..4f44cf170 100644 --- a/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/rustdoc-internals/rustdoc-test-suite.md @@ -55,6 +55,9 @@ Similar to shell commands, directives can extend across multiple lines if their last char is `\`. In this case, the start of the next line should be `//`, with no `@`. +Similar to compiletest directives, besides a space you can also use a colon `:` to separate +the directive name and the arguments, however a space is preferred for HtmlDocCk directives. + Use the special string `{{channel}}` in XPaths, `PATTERN` arguments and [snapshot files](#snapshot) if you'd like to refer to the URL `https://doc.rust-lang.org/CHANNEL` where `CHANNEL` refers to the current release channel (e.g, `stable` or `nightly`). From 2b862a022c157deb35731653686138e7d5f5cbcc Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Tue, 8 Jul 2025 17:58:49 +0800 Subject: [PATCH 393/447] Remove mentions of `./x suggest` and `suggest-tests` in rustc-dev-guide --- src/SUMMARY.md | 1 - src/building/quickstart.md | 3 -- src/building/suggested.md | 17 ----------- src/tests/suggest-tests.md | 59 -------------------------------------- 4 files changed, 80 deletions(-) delete mode 100644 src/tests/suggest-tests.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 7f2f32c62..651e2925a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -35,7 +35,6 @@ - [Cranelift codegen backend](./tests/codegen-backend-tests/cg_clif.md) - [GCC codegen backend](./tests/codegen-backend-tests/cg_gcc.md) - [Performance testing](./tests/perf.md) - - [Suggest tests tool](./tests/suggest-tests.md) - [Misc info](./tests/misc.md) - [Debugging the compiler](./compiler-debugging.md) - [Using the tracing/logging instrumentation](./tracing.md) diff --git a/src/building/quickstart.md b/src/building/quickstart.md index 9a8ab353e..97314d803 100644 --- a/src/building/quickstart.md +++ b/src/building/quickstart.md @@ -61,9 +61,6 @@ and check the output. Use `--bless` if you've made a change and want to update the `.stderr` files with the new output. -> `./x suggest` can also be helpful for suggesting which tests to run after a -> change. - Congrats, you are now ready to make a change to the compiler! If you have more questions, [the full chapter](./how-to-build-and-run.md) might contain the answers, and if it doesn't, feel free to ask for help on diff --git a/src/building/suggested.md b/src/building/suggested.md index bfb2f4d10..7f626314f 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -270,23 +270,6 @@ run the tests at some later time. You can then use `git bisect` to track down is that you are left with a fairly fine-grained set of commits at the end, all of which build and pass tests. This often helps reviewing. -## `x suggest` - -The `x suggest` subcommand suggests (and runs) a subset of the extensive -`rust-lang/rust` tests based on files you have changed. This is especially -useful for new contributors who have not mastered the arcane `x` flags yet and -more experienced contributors as a shorthand for reducing mental effort. In all -cases it is useful not to run the full tests (which can take on the order of -tens of minutes) and just run a subset which are relevant to your changes. For -example, running `tidy` and `linkchecker` is useful when editing Markdown files, -whereas UI tests are much less likely to be helpful. While `x suggest` is a -useful tool, it does not guarantee perfect coverage (just as PR CI isn't a -substitute for bors). See the [dedicated chapter](../tests/suggest-tests.md) for -more information and contribution instructions. - -Please note that `x suggest` is in a beta state currently and the tests that it -will suggest are limited. - ## Configuring `rustup` to use nightly Some parts of the bootstrap process uses pinned, nightly versions of tools like diff --git a/src/tests/suggest-tests.md b/src/tests/suggest-tests.md deleted file mode 100644 index 663e8a5af..000000000 --- a/src/tests/suggest-tests.md +++ /dev/null @@ -1,59 +0,0 @@ -# Suggest tests tool - -This chapter is about the internals of and contribution instructions for the -`suggest-tests` tool. For a high-level overview of the tool, see [this -section](../building/suggested.md#x-suggest). This tool is currently in a beta -state and is tracked by [this](https://github.com/rust-lang/rust/issues/109933) -issue on Github. Currently the number of tests it will suggest are very limited -in scope, we are looking to expand this (contributions welcome!). - -## Internals - -The tool is defined in a separate crate -([`src/tools/suggest-tests`](https://github.com/rust-lang/rust/blob/master/src/tools/suggest-tests)) -which outputs suggestions which are parsed by a shim in bootstrap -([`src/bootstrap/src/core/build_steps/suggest.rs`](https://github.com/rust-lang/rust/blob/master/src/bootstrap/src/core/build_steps/suggest.rs)). -The only notable thing the bootstrap shim does is (when invoked with the `--run` -flag) use bootstrap's internal mechanisms to create a new `Builder` and uses it -to invoke the suggested commands. The `suggest-tests` crate is where the fun -happens, two kinds of suggestions are defined: "static" and "dynamic" -suggestions. - -### Static suggestions - -Defined -[here](https://github.com/rust-lang/rust/blob/master/src/tools/suggest-tests/src/static_suggestions.rs). -Static suggestions are simple: they are just -[globs](https://crates.io/crates/glob) which map to a `x` command. In -`suggest-tests`, this is implemented with a simple `macro_rules` macro. - -### Dynamic suggestions - -Defined -[here](https://github.com/rust-lang/rust/blob/master/src/tools/suggest-tests/src/dynamic_suggestions.rs). -These are more complicated than static suggestions and are implemented as -functions with the following signature: `fn(&Path) -> Vec`. In other -words, each suggestion takes a path to a modified file and (after running -arbitrary Rust code) can return any number of suggestions, or none. Dynamic -suggestions are useful for situations where fine-grained control over -suggestions is needed. For example, modifications to the `compiler/xyz/` path -should trigger the `x test compiler/xyz` suggestion. In the future, dynamic -suggestions might even read file contents to determine if (what) tests should -run. - -## Adding a suggestion - -The following steps should serve as a rough guide to add suggestions to -`suggest-tests` (very welcome!): - -1. Determine the rules for your suggestion. Is it simple and operates only on a - single path or does it match globs? Does it need fine-grained control over - the resulting command or does "one size fit all"? -2. Based on the previous step, decide if your suggestion should be implemented - as either static or dynamic. -3. Implement the suggestion. If it is dynamic then a test is highly recommended, - to verify that your logic is correct and to give an example of the - suggestion. See the - [tests.rs](https://github.com/rust-lang/rust/blob/master/src/tools/suggest-tests/src/tests.rs) - file. -4. Open a PR implementing your suggestion. **(TODO: add example PR)** From 3ca42fde464882304299e78d6c798d6e9015650f Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 16 Jul 2025 21:29:16 +0200 Subject: [PATCH 394/447] go over invariants again :3 Co-authored-by: Boxy --- src/solve/invariants.md | 81 ++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/src/solve/invariants.md b/src/solve/invariants.md index fd12b1957..2f5a134f4 100644 --- a/src/solve/invariants.md +++ b/src/solve/invariants.md @@ -11,10 +11,8 @@ It is important to know about the things you can assume while working on - and w type system, so here's an incomplete and unofficial list of invariants of the core type system: -- ✅: this invariant mostly holds, with some weird exceptions, you can rely on it outside -of these cases -- ❌: this invariant does not hold, either due to bugs or by design, you must not rely on -it for soundness or have to be incredibly careful when doing so +- ✅: this invariant mostly holds, with some weird exceptions or current bugs +- ❌: this invariant does not hold, and is unlikely to do so in the future; do not rely on it for soundness or have to be incredibly careful when doing so ### `wf(X)` implies `wf(normalize(X))` ✅ @@ -23,6 +21,8 @@ well-formed after normalizing said aliases. We rely on this as otherwise we would have to re-check for well-formedness for these types. +This currently does not hold due to a type system unsoundness: [#84533](https://github.com/rust-lang/rust/issues/84533). + ### Structural equality modulo regions implies semantic equality ✅ If you have a some type and equate it to itself after replacing any regions with unique @@ -36,7 +36,7 @@ If this invariant is broken MIR typeck ends up failing with an ICE. TODO: this invariant is formulated in a weird way and needs to be elaborated. Pretty much: I would like this check to only fail if there's a solver bug: -https://github.com/rust-lang/rust/blob/2ffeb4636b4ae376f716dc4378a7efb37632dc2d/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs#L391-L407 +https://github.com/rust-lang/rust/blob/2ffeb4636b4ae376f716dc4378a7efb37632dc2d/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs#L391-L407 We should readd this check and see where it breaks :3 If we prove some goal/equate types/whatever, apply the resulting inference constraints, and then redo the original action, the result should be the same. @@ -73,40 +73,47 @@ Many of the currently known unsound issues end up relying on this invariant bein It is however very difficult to imagine a sound type system without this invariant, so the issue is that the invariant is broken, not that we incorrectly rely on it. -### Generic goals and their instantiations have the same result ✅ +### The type system is complete ❌ + +The type system is not complete, it often adds unnecessary inference constraints, and errors +even though the goal could hold. + +- method selection +- opaque type inference +- handling type outlives constraints +- preferring `ParamEnv` candidates over `Impl` candidates during candidate selection +in the trait solver + +### Goals keep their result from HIR typeck afterwards ✅ -Pretty much: If we successfully typecheck a generic function concrete instantiations -of that function should also typeck. We should not get errors post-monomorphization. -We can however get overflow errors at that point. +Having a goal which succeeds during HIR typeck but fails when being reevaluated during MIR borrowck causes ICE, e.g. [#140211](https://github.com/rust-lang/rust/issues/140211). -TODO: example for overflow error post-monomorphization +Having a goal which succeeds during HIR typeck but fails after being instantiated is unsound, e.g. [#140212](https://github.com/rust-lang/rust/issues/140212). + +It is interesting that we allow some incompleteness in the trait solver while still maintaining this limitation. It would be nice if there was a clear way to separate the "allowed incompleteness" from behavior which would break this invariant. + +#### Normalization must not change results This invariant is relied on to allow the normalization of generic aliases. Breaking it can easily result in unsoundness, e.g. [#57893](https://github.com/rust-lang/rust/issues/57893) +#### Goals may still overflow after instantiation + +As they start to hit the recursion limit. We also have diverging aliases which are scuffed. It's unclear how these should be handled :3 + ### Trait goals in empty environments are proven by a unique impl ✅ If a trait goal holds with an empty environment, there should be a unique `impl`, either user-defined or builtin, which is used to prove that goal. This is -necessary to select a unique method. +necessary to select unique methods and associated items. We do however break this invariant in few cases, some of which are due to bugs, some by design: - *marker traits* are allowed to overlap as they do not have associated items - *specialization* allows specializing impls to overlap with their parent - the builtin trait object trait implementation can overlap with a user-defined impl: -[#57893] +[#57893](https://github.com/rust-lang/rust/issues/57893) -### The type system is complete ❌ - -The type system is not complete, it often adds unnecessary inference constraints, and errors -even though the goal could hold. - -- method selection -- opaque type inference -- handling type outlives constraints -- preferring `ParamEnv` candidates over `Impl` candidates during candidate selection -in the trait solver #### The type system is complete during the implicit negative overlap check in coherence ✅ @@ -121,18 +128,19 @@ We have to be careful as it is quite easy to break: - generalization of aliases - generalization during subtyping binders (luckily not exploitable in coherence) -### Trait solving must be (free) lifetime agnostic ✅ +### Trait solving must not depend on lifetimes being different ✅ + +If a goal holds with lifetimes being different, it must also hold with these lifetimes being the same. We otherwise get post-monomorphization errors during codegen or unsoundness due to invalid vtables. + +We could also just get inconsistent behavior when first proving a goal with different lifetimes which are later constrained to be equal. -Trait solving during codegen should have the same result as during typeck. As we erase -all free regions during codegen we must not rely on them during typeck. A noteworthy example -is special behavior for `'static`. +### Trait solving in bodies must not depend on lifetimes being equal ✅ We also have to be careful with relying on equality of regions in the trait solver. This is fine for codegen, as we treat all erased regions as equal. We can however lose equality information from HIR to MIR typeck. -The new solver "uniquifies regions" during canonicalization, canonicalizing `u32: Trait<'x, 'x>` -as `exists<'0, '1> u32: Trait<'0, '1>`, to make it harder to rely on this property. +This currently does not hold with the new solver: [trait-system-refactor-initiative#27](https://github.com/rust-lang/trait-system-refactor-initiative/issues/27). ### Removing ambiguity makes strictly more things compile ❌ @@ -146,9 +154,16 @@ changes, breaking existing projects. Two types being equal in the type system must mean that they have the same `TypeId` after instantiating their generic parameters with concrete -arguments. This currently does not hold: [#97156]. +arguments. We can otherwise use their different `TypeId`s to impact trait selection. + +We lookup types using structural equality during codegen, but this shouldn't necessarily be unsound +- may result in redundant method codegen or backend type check errors? +- we also rely on it in CTFE assertions + +### Semantically different types have different `TypeId`s ✅ + +Semantically different `'static` types need different `TypeId`s to avoid transmutes, +for example `for<'a> fn(&'a str)` vs `fn(&'static str)` must have a different `TypeId`. + -[#57893]: https://github.com/rust-lang/rust/issues/57893 -[#97156]: https://github.com/rust-lang/rust/issues/97156 -[#114936]: https://github.com/rust-lang/rust/issues/114936 -[coherence]: ../coherence.md +[coherence]: ../coherence.md From 88382c698fbf9617e599b68d38cc05248132d561 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 17 Jul 2025 05:42:53 +0200 Subject: [PATCH 395/447] some improvements to "Invariants of the type system" --- src/solve/invariants.md | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/solve/invariants.md b/src/solve/invariants.md index 2f5a134f4..8ec15f339 100644 --- a/src/solve/invariants.md +++ b/src/solve/invariants.md @@ -4,10 +4,10 @@ FIXME: This file talks about invariants of the type system as a whole, not only There are a lot of invariants - things the type system guarantees to be true at all times - which are desirable or expected from other languages and type systems. Unfortunately, quite -a few of them do not hold in Rust right now. This is either a fundamental to its design or -caused by bugs and something that may change in the future. +a few of them do not hold in Rust right now. This is either fundamental to its design or +caused by bugs, and something that may change in the future. -It is important to know about the things you can assume while working on - and with - the +It is important to know about the things you can assume while working on, and with, the type system, so here's an incomplete and unofficial list of invariants of the core type system: @@ -29,14 +29,15 @@ If you have a some type and equate it to itself after replacing any regions with inference variables in both the lhs and rhs, the now potentially structurally different types should still be equal to each other. -Needed to prevent goals from succeeding in HIR typeck and then failing in MIR borrowck. -If this invariant is broken MIR typeck ends up failing with an ICE. +This is needed to prevent goals from succeeding in HIR typeck and then failing in MIR borrowck. +If this invariant is broken, MIR typeck ends up failing with an ICE. ### Applying inference results from a goal does not change its result ❌ TODO: this invariant is formulated in a weird way and needs to be elaborated. Pretty much: I would like this check to only fail if there's a solver bug: -https://github.com/rust-lang/rust/blob/2ffeb4636b4ae376f716dc4378a7efb37632dc2d/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs#L391-L407 We should readd this check and see where it breaks :3 +. +We should readd this check and see where it breaks :3 If we prove some goal/equate types/whatever, apply the resulting inference constraints, and then redo the original action, the result should be the same. @@ -75,8 +76,8 @@ the issue is that the invariant is broken, not that we incorrectly rely on it. ### The type system is complete ❌ -The type system is not complete, it often adds unnecessary inference constraints, and errors -even though the goal could hold. +The type system is not complete. +It often adds unnecessary inference constraints, and errors even though the goal could hold. - method selection - opaque type inference @@ -95,11 +96,13 @@ It is interesting that we allow some incompleteness in the trait solver while st #### Normalization must not change results This invariant is relied on to allow the normalization of generic aliases. Breaking -it can easily result in unsoundness, e.g. [#57893](https://github.com/rust-lang/rust/issues/57893) +it can easily result in unsoundness, e.g. [#57893](https://github.com/rust-lang/rust/issues/57893). #### Goals may still overflow after instantiation -As they start to hit the recursion limit. We also have diverging aliases which are scuffed. It's unclear how these should be handled :3 +This happens they start to hit the recursion limit. +We also have diverging aliases which are scuffed. +It's unclear how these should be handled :3 ### Trait goals in empty environments are proven by a unique impl ✅ @@ -107,8 +110,7 @@ If a trait goal holds with an empty environment, there should be a unique `impl` either user-defined or builtin, which is used to prove that goal. This is necessary to select unique methods and associated items. -We do however break this invariant in few cases, some of which are due to bugs, -some by design: +We do however break this invariant in a few cases, some of which are due to bugs, some by design: - *marker traits* are allowed to overlap as they do not have associated items - *specialization* allows specializing impls to overlap with their parent - the builtin trait object trait implementation can overlap with a user-defined impl: @@ -117,11 +119,12 @@ some by design: #### The type system is complete during the implicit negative overlap check in coherence ✅ -For more on overlap checking: [coherence] +For more on overlap checking, see [Coherence chapter]. -During the implicit negative overlap check in coherence we must never return *error* for -goals which can be proven. This would allow for overlapping impls with potentially different -associated items, breaking a bunch of other invariants. +During the implicit negative overlap check in coherence, +we must never return *error* for goals which can be proven. +This would allow for overlapping impls with potentially different associated items, +breaking a bunch of other invariants. This invariant is currently broken in many different ways while actually something we rely on. We have to be careful as it is quite easy to break: @@ -147,8 +150,8 @@ This currently does not hold with the new solver: [trait-system-refactor-initiat Ideally we *should* not rely on ambiguity for things to compile. Not doing that will cause future improvements to be breaking changes. -Due to *incompleteness* this is not the case and improving inference can result in inference -changes, breaking existing projects. +Due to *incompleteness* this is not the case, +and improving inference can result in inference changes, breaking existing projects. ### Semantic equality implies structural equality ✅ @@ -166,4 +169,4 @@ Semantically different `'static` types need different `TypeId`s to avoid transmu for example `for<'a> fn(&'a str)` vs `fn(&'static str)` must have a different `TypeId`. -[coherence]: ../coherence.md +[coherence chapter]: ../coherence.md From 2ed53819e5df1474e63260d10eed180f2295d428 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 17 Jul 2025 04:14:28 +0000 Subject: [PATCH 396/447] Prepare for merging from rust-lang/rust This updates the rust-version file to fd2eb391d032181459773f3498c17b198513e0d0. --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index e444613e6..3f10132b6 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -c96a69059ecc618b519da385a6ccd03155aa0237 +fd2eb391d032181459773f3498c17b198513e0d0 From d4ba14a073b2e996603bf0b9844076281e41fe5a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 17 Jul 2025 06:32:23 +0200 Subject: [PATCH 397/447] copy-paste convenience --- src/external-repos.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/external-repos.md b/src/external-repos.md index 68986a0bc..ecc65b26a 100644 --- a/src/external-repos.md +++ b/src/external-repos.md @@ -60,7 +60,10 @@ Currently, we are migrating Josh repositories to it. So far, it is used in: - rustc-dev-guide - stdarch -To use the tool, first install it with `cargo install --locked --git https://github.com/rust-lang/josh-sync`. +To install the tool: +``` +cargo install --locked --git https://github.com/rust-lang/josh-sync +``` Both pulls (synchronize changes from rust-lang/rust into the subtree) and pushes (synchronize changes from the subtree to rust-lang/rust) are performed from the subtree repository (so first From 73bf010bc88738e906af50668071c5fd444f8389 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 13 Jul 2025 16:49:19 +0800 Subject: [PATCH 398/447] parse `const trait Trait` --- src/effects.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/effects.md b/src/effects.md index c7aa27146..87b0103a7 100644 --- a/src/effects.md +++ b/src/effects.md @@ -67,10 +67,8 @@ in [`wfcheck::check_impl`]. Here's an example: ```rust -#[const_trait] -trait Bar {} -#[const_trait] -trait Foo: ~const Bar {} +const trait Bar {} +const trait Foo: ~const Bar {} // `const_conditions` contains `HostEffect(Self: Bar, maybe)` impl const Bar for () {} @@ -85,8 +83,7 @@ predicates of the trait method, and we attempt to prove the predicates of the impl method. We do the same for `const_conditions`: ```rust -#[const_trait] -trait Foo { +const trait Foo { fn hi(); } From 9b4e1dd06a47bee18cfc383cec53c62422d78a66 Mon Sep 17 00:00:00 2001 From: Yiqun Liu Date: Fri, 18 Jul 2025 19:06:50 +0800 Subject: [PATCH 399/447] fix typos --- src/serialization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/serialization.md b/src/serialization.md index 47667061e..8eb37bbe2 100644 --- a/src/serialization.md +++ b/src/serialization.md @@ -75,7 +75,7 @@ impl Decodable for MyStruct { rustc has a lot of [arena allocated types]. Deserializing these types isn't possible without access to the arena that they need to be allocated on. -The [`TyDecoder`] and [`TyEncoder`] traits are supertraits of [`Decoder`] and [`Encoder`] that allow access to a [`TyCtxt`]. +The [`TyDecoder`] and [`TyEncoder`] traits are subtraits of [`Decoder`] and [`Encoder`] that allow access to a [`TyCtxt`]. Types which contain `arena` allocated types can then bound the type parameter of their [`Encodable`] and [`Decodable`] implementations with these traits. From 73a513c372193a2aea56bf779edb6b3b1bff59db Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Wed, 25 Jun 2025 07:56:40 +0200 Subject: [PATCH 400/447] tests: Require `run-fail` ui tests to have an exit code (`SIGABRT` not ok) And introduce two new directives for ui tests: * `run-crash` * `run-fail-or-crash` Normally a `run-fail` ui test like tests that panic shall not be terminated by a signal like `SIGABRT`. So begin having that as a hard requirement. Some of our current tests do terminate by a signal/crash however. Introduce and use `run-crash` for those tests. Note that Windows crashes are not handled by signals but by certain high bits set on the process exit code. Example exit code for crash on Windows: `0xc000001d`. Because of this, we define "crash" on all platforms as "not exit with success and not exit with a regular failure code in the range 1..=127". Some tests behave differently on different targets: * Targets without unwind support will abort (crash) instead of exit with failure code 101 after panicking. As a special case, allow crashes for `run-fail` tests for such targets. * Different sanitizer implementations handle detected memory problems differently. Some abort (crash) the process while others exit with failure code 1. Introduce and use `run-fail-or-crash` for such tests. --- src/tests/directives.md | 6 ++++-- src/tests/ui.md | 20 +++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 63aa08c38..6685add46 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -75,8 +75,10 @@ expectations](ui.md#controlling-passfail-expectations). | `check-fail` | Building (no codegen) should fail | `ui`, `crashes` | N/A | | `build-pass` | Building should pass | `ui`, `crashes`, `codegen`, `incremental` | N/A | | `build-fail` | Building should fail | `ui`, `crashes` | N/A | -| `run-pass` | Running the test binary should pass | `ui`, `crashes`, `incremental` | N/A | -| `run-fail` | Running the test binary should fail | `ui`, `crashes` | N/A | +| `run-pass` | Program must exit with code `0` | `ui`, `crashes`, `incremental` | N/A | +| `run-fail` | Program must exit with code `1..=127` | `ui`, `crashes` | N/A | +| `run-crash` | Program must crash | `ui` | N/A | +| `run-fail-or-crash` | Program must `run-fail` or `run-crash` | `ui` | N/A | | `ignore-pass` | Ignore `--pass` flag | `ui`, `crashes`, `codegen`, `incremental` | N/A | | `dont-check-failure-status` | Don't check exact failure status (i.e. `1`) | `ui`, `incremental` | N/A | | `failure-status` | Check | `ui`, `crashes` | Any `u16` | diff --git a/src/tests/ui.md b/src/tests/ui.md index 4fce5838b..9bfc60e08 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -448,7 +448,7 @@ even run the resulting program. Just add one of the following - `//@ build-pass` — compilation and linking should succeed but do not run the resulting binary. - `//@ run-pass` — compilation should succeed and running the resulting - binary should also succeed. + binary should make it exit with code 0 which indicates success. - Fail directives: - `//@ check-fail` — compilation should fail (the codegen phase is skipped). This is the default for UI tests. @@ -457,10 +457,20 @@ even run the resulting program. Just add one of the following - First time is to ensure that the compile succeeds without the codegen phase - Second time is to ensure that the full compile fails - `//@ run-fail` — compilation should succeed, but running the resulting - binary should fail. - -For `run-pass` and `run-fail` tests, by default the output of the program itself -is not checked. + binary should make it exit with a code in the range `1..=127` which + indicates regular failure. On targets without unwind support, crashes + are also accepted. + - `//@ run-crash` — compilation should succeed, but running the resulting + binary should fail with a crash. Crashing is defined as "not exiting with + a code in the range `0..=127`". Example on Linux: Termination by `SIGABRT` + or `SIGSEGV`. Example on Windows: Exiting with the code for + `STATUS_ILLEGAL_INSTRUCTION` (`0xC000001D`). + - `//@ run-fail-or-crash` — compilation should succeed, but running the + resulting binary should either `run-fail` or `run-crash`. Useful if a test + crashes on some targets but just fails on others. + +For `run-pass`. `run-fail`, `run-crash` and `run-fail-or-crash` tests, by +default the output of the program itself is not checked. If you want to check the output of running the program, include the `check-run-results` directive. This will check for a `.run.stderr` and From 6c4ac45b007f03e229f4e32ce43efe9e3f52d205 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Jul 2025 11:52:54 +0200 Subject: [PATCH 401/447] Add new `ignore-backends` tests annotations --- src/tests/directives.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/directives.md b/src/tests/directives.md index 6685add46..15655d1bb 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -205,6 +205,7 @@ settings: on `wasm32-unknown-unknown` target because the target does not support the `proc-macro` crate type. - `needs-target-std` — ignores if target platform does not have std support. +- `ignore-backends` — ignores the listed backends, separated by whitespace characters. The following directives will check LLVM support: From 22fa0c852cf6f36ad492b72fa8e8018cf47ccfdb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Jul 2025 12:05:08 +0200 Subject: [PATCH 402/447] Add new `needs-backends` tests annotations --- src/tests/directives.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/directives.md b/src/tests/directives.md index 15655d1bb..5c3ae359b 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -206,6 +206,7 @@ settings: `proc-macro` crate type. - `needs-target-std` — ignores if target platform does not have std support. - `ignore-backends` — ignores the listed backends, separated by whitespace characters. +- `needs-backends` — only runs the test if current codegen backend is listed. The following directives will check LLVM support: From cf395fe6b95d6203a7ee0bf08f048d6bc07efccc Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 21 Jul 2025 04:17:44 +0000 Subject: [PATCH 403/447] Prepare for merging from rust-lang/rust This updates the rust-version file to 460259d14de0274b97b8801e08cb2fe5f16fdac5. --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 3f10132b6..f6b7efe51 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -fd2eb391d032181459773f3498c17b198513e0d0 +460259d14de0274b97b8801e08cb2fe5f16fdac5 From 72c8958bc8c1f83d15240504fd94b6ac2df4b18f Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 21 Jul 2025 10:53:11 +0200 Subject: [PATCH 404/447] fix some typos --- src/building/suggested.md | 2 +- src/hir/ambig-unambig-ty-and-consts.md | 4 ++-- src/rustdoc-internals/rustdoc-test-suite.md | 2 +- src/tests/compiletest.md | 2 +- src/ty_module/instantiating_binders.md | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/building/suggested.md b/src/building/suggested.md index 7f626314f..c046161e7 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -162,7 +162,7 @@ create a `.vim/coc-settings.json`. The settings can be edited with [`src/etc/rust_analyzer_settings.json`]. Another way is without a plugin, and creating your own logic in your -configuration. The following code will work for any checkout of rust-lang/rust (newer than Febuary 2025): +configuration. The following code will work for any checkout of rust-lang/rust (newer than February 2025): ```lua local function expand_config_variables(option) diff --git a/src/hir/ambig-unambig-ty-and-consts.md b/src/hir/ambig-unambig-ty-and-consts.md index 709027883..d4f504ad2 100644 --- a/src/hir/ambig-unambig-ty-and-consts.md +++ b/src/hir/ambig-unambig-ty-and-consts.md @@ -38,7 +38,7 @@ Note that places 3 and 4 would never actually be possible to encounter as we alw This has a few failure modes: - People may write visitors which check for `GenericArg::Infer` but forget to check for `hir::TyKind/ConstArgKind::Infer`, only handling infers in ambig positions by accident. - People may write visitors which check for `hir::TyKind/ConstArgKind::Infer` but forget to check for `GenericArg::Infer`, only handling infers in unambig positions by accident. -- People may write visitors which check for `GenerArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenerigArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`. +- People may write visitors which check for `GenericArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenericArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`. - People may write visitors which check for *only* `TyKind::Infer` and not `ConstArgKind::Infer` forgetting that there are also inferred const arguments (and vice versa). To make writing HIR visitors less error prone when caring about inferred types/consts we have a relatively complex system: @@ -60,4 +60,4 @@ This has a number of benefits: [ambig_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.AmbigArg.html [visit_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_ty [visit_const_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_const_arg -[visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer \ No newline at end of file +[visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer diff --git a/src/rustdoc-internals/rustdoc-test-suite.md b/src/rustdoc-internals/rustdoc-test-suite.md index 4f44cf170..3ec5ebd79 100644 --- a/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/rustdoc-internals/rustdoc-test-suite.md @@ -20,7 +20,7 @@ Internally, [`compiletest`] invokes the supplementary checker script [`htmldocck Directives to HtmlDocCk are assertions that place constraints on the generated HTML. They look similar to those given to `compiletest` in that they take the form of `//@` comments -but ultimately, they are completey distinct and processed by different programs. +but ultimately, they are completely distinct and processed by different programs. [XPath] is used to query parts of the HTML document tree. diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index ded30234e..aa99347b2 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -29,7 +29,7 @@ on if or how to run the test, what behavior to expect, and more. See [directives](directives.md) and the test suite documentation below for more details on these annotations. -See the [Adding new tests](adding.md) and [Best practies](best-practices.md) +See the [Adding new tests](adding.md) and [Best practices](best-practices.md) chapters for a tutorial on creating a new test and advice on writing a good test, and the [Running tests](running.md) chapter on how to run the test suite. diff --git a/src/ty_module/instantiating_binders.md b/src/ty_module/instantiating_binders.md index e3f091ca4..0d1108c72 100644 --- a/src/ty_module/instantiating_binders.md +++ b/src/ty_module/instantiating_binders.md @@ -77,7 +77,7 @@ This end result is incorrect as we had two separate binders introducing their ow While in theory we could make this work it would be quite involved and more complex than the current setup, we would have to: - "rewrite" bound variables to have a higher `DebruijnIndex` whenever instantiating a `Binder`/`EarlyBinder` with a `Bound` ty/const/region -- When inferring an inference variable to a bound var, if that bound var is from a binder enterred after creating the infer var, we would have to lower the `DebruijnIndex` of the var. +- When inferring an inference variable to a bound var, if that bound var is from a binder entered after creating the infer var, we would have to lower the `DebruijnIndex` of the var. - Separately track what binder an inference variable was created inside of, also what the innermost binder it can name parameters from (currently we only have to track the latter) - When resolving inference variables rewrite any bound variables according to the current binder depth of the infcx - Maybe more (while writing this list items kept getting added so it seems naive to think this is exhaustive) From 51eeb80d8a7746ccb71fdda25e0642920f2c5880 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 21 Jul 2025 12:19:20 +0200 Subject: [PATCH 405/447] add rdg push git config entry for git protocol pushers (again) --- src/external-repos.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/external-repos.md b/src/external-repos.md index ecc65b26a..667cca317 100644 --- a/src/external-repos.md +++ b/src/external-repos.md @@ -80,6 +80,16 @@ switch to its repository checkout directory in your terminal). #### Performing push +> NOTE: +> If you use Git protocol to push to your fork of `rust-lang/rust`, +> ensure that you have this entry in your Git config, +> else the 2 steps that follow would prompt for a username and password: +> +> ``` +> [url "git@github.com:"] +> insteadOf = "https://github.com/" +> ``` + 1) Run the push command to create a branch named `` in a `rustc` fork under the `` account ``` rustc-josh-sync push From d79787c75cd5e2b61e62a2a446a55ade22e25f15 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 21 Jul 2025 13:25:14 +0200 Subject: [PATCH 406/447] already documented elsewhere --- src/external-repos.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/external-repos.md b/src/external-repos.md index 667cca317..75774e345 100644 --- a/src/external-repos.md +++ b/src/external-repos.md @@ -81,14 +81,7 @@ switch to its repository checkout directory in your terminal). #### Performing push > NOTE: -> If you use Git protocol to push to your fork of `rust-lang/rust`, -> ensure that you have this entry in your Git config, -> else the 2 steps that follow would prompt for a username and password: -> -> ``` -> [url "git@github.com:"] -> insteadOf = "https://github.com/" -> ``` +> Before you proceed, look at some guidance related to Git [on josh-sync README], 1) Run the push command to create a branch named `` in a `rustc` fork under the `` account ``` @@ -183,3 +176,4 @@ the week leading up to the beta cut. [Toolstate chapter]: https://forge.rust-lang.org/infra/toolstate.html [josh]: https://josh-project.github.io/josh/intro.html [josh-sync]: https://github.com/rust-lang/josh-sync +[on josh-sync README]: https://github.com/rust-lang/josh-sync#git-peculiarities From 3f0e0833a596305a6b1e99c0eee16bd8bd101cf4 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 21 Jul 2025 13:55:55 +0200 Subject: [PATCH 407/447] typo --- src/external-repos.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/external-repos.md b/src/external-repos.md index 75774e345..44d4b5b4b 100644 --- a/src/external-repos.md +++ b/src/external-repos.md @@ -81,7 +81,7 @@ switch to its repository checkout directory in your terminal). #### Performing push > NOTE: -> Before you proceed, look at some guidance related to Git [on josh-sync README], +> Before you proceed, look at some guidance related to Git [on josh-sync README]. 1) Run the push command to create a branch named `` in a `rustc` fork under the `` account ``` From 277a5c478769824badfbef5b20cbc1187f5cf1bf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 21 Jul 2025 14:22:51 +0200 Subject: [PATCH 408/447] Rename `tests/assembly` into `tests/assembly-llvm` --- src/asm.md | 4 ++-- src/tests/compiletest.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/asm.md b/src/asm.md index eec9d448b..3d93d5a4c 100644 --- a/src/asm.md +++ b/src/asm.md @@ -155,9 +155,9 @@ can't know ahead of time whether a function will require a frame/base pointer. Various tests for inline assembly are available: -- `tests/assembly/asm` +- `tests/assembly-llvm/asm` - `tests/ui/asm` - `tests/codegen/asm-*` Every architecture supported by inline assembly must have exhaustive tests in -`tests/assembly/asm` which test all combinations of register classes and types. +`tests/assembly-llvm/asm` which test all combinations of register classes and types. diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index aa99347b2..6a60e7118 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -307,7 +307,7 @@ If you need to work with `#![no_std]` cross-compiling tests, consult the ### Assembly tests -The tests in [`tests/assembly`] test LLVM assembly output. They compile the test +The tests in [`tests/assembly-llvm`] test LLVM assembly output. They compile the test with the `--emit=asm` flag to emit a `.s` file with the assembly output. They then run the LLVM [FileCheck] tool. @@ -324,7 +324,7 @@ See also the [codegen tests](#codegen-tests) for a similar set of tests. If you need to work with `#![no_std]` cross-compiling tests, consult the [`minicore` test auxiliary](./minicore.md) chapter. -[`tests/assembly`]: https://github.com/rust-lang/rust/tree/master/tests/assembly +[`tests/assembly-llvm`]: https://github.com/rust-lang/rust/tree/master/tests/assembly-llvm ### Codegen-units tests From 0da12448f61a915869fdc917c86eac3a9bec0b8d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 21 Jul 2025 14:34:12 +0200 Subject: [PATCH 409/447] Rename `tests/codegen` into `tests/codegen-llvm` --- src/asm.md | 2 +- src/autodiff/installation.md | 2 +- src/llvm-coverage-instrumentation.md | 4 ++-- src/offload/installation.md | 2 +- src/profile-guided-optimization.md | 2 +- src/sanitizers.md | 4 ++-- src/tests/compiletest.md | 6 +++--- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/asm.md b/src/asm.md index 3d93d5a4c..1bb493e73 100644 --- a/src/asm.md +++ b/src/asm.md @@ -157,7 +157,7 @@ Various tests for inline assembly are available: - `tests/assembly-llvm/asm` - `tests/ui/asm` -- `tests/codegen/asm-*` +- `tests/codegen-llvm/asm-*` Every architecture supported by inline assembly must have exhaustive tests in `tests/assembly-llvm/asm` which test all combinations of register classes and types. diff --git a/src/autodiff/installation.md b/src/autodiff/installation.md index a550f6d23..ddbb3a054 100644 --- a/src/autodiff/installation.md +++ b/src/autodiff/installation.md @@ -25,7 +25,7 @@ rustup toolchain install nightly # enables -Z unstable-options You can then run our test cases: ```bash -./x test --stage 1 tests/codegen/autodiff +./x test --stage 1 tests/codegen-llvm/autodiff ./x test --stage 1 tests/pretty/autodiff ./x test --stage 1 tests/ui/autodiff ./x test --stage 1 tests/ui/feature-gates/feature-gate-autodiff.rs diff --git a/src/llvm-coverage-instrumentation.md b/src/llvm-coverage-instrumentation.md index 28e0e7a90..880363b94 100644 --- a/src/llvm-coverage-instrumentation.md +++ b/src/llvm-coverage-instrumentation.md @@ -117,7 +117,7 @@ human-readable coverage report. > directive, so they will be skipped if the profiler runtime has not been > [enabled in `bootstrap.toml`](#recommended-configtoml-settings). -Finally, the [`tests/codegen/instrument-coverage/testprog.rs`] test compiles a simple Rust program +Finally, the [`tests/codegen-llvm/instrument-coverage/testprog.rs`] test compiles a simple Rust program with `-C instrument-coverage` and compares the compiled program's LLVM IR to expected LLVM IR instructions and structured data for a coverage-enabled program, including various checks for Coverage Map-related metadata and the LLVM @@ -136,4 +136,4 @@ and `mir-opt` tests can be refreshed by running: [`tests/coverage`]: https://github.com/rust-lang/rust/tree/master/tests/coverage [`src/tools/coverage-dump`]: https://github.com/rust-lang/rust/tree/master/src/tools/coverage-dump [`tests/coverage-run-rustdoc`]: https://github.com/rust-lang/rust/tree/master/tests/coverage-run-rustdoc -[`tests/codegen/instrument-coverage/testprog.rs`]: https://github.com/rust-lang/rust/blob/master/tests/mir-opt/coverage/instrument_coverage.rs +[`tests/codegen-llvm/instrument-coverage/testprog.rs`]: https://github.com/rust-lang/rust/blob/master/tests/mir-opt/coverage/instrument_coverage.rs diff --git a/src/offload/installation.md b/src/offload/installation.md index 1962314c7..1e792de3c 100644 --- a/src/offload/installation.md +++ b/src/offload/installation.md @@ -40,7 +40,7 @@ This gives you a working LLVM build. ## Testing run ``` -./x test --stage 1 tests/codegen/gpu_offload +./x test --stage 1 tests/codegen-llvm/gpu_offload ``` ## Usage diff --git a/src/profile-guided-optimization.md b/src/profile-guided-optimization.md index d279786ac..2fa810210 100644 --- a/src/profile-guided-optimization.md +++ b/src/profile-guided-optimization.md @@ -132,7 +132,7 @@ There is also a [codegen test][codegen-test] that checks that some expected instrumentation artifacts show up in LLVM IR. [rmake-tests]: https://github.com/rust-lang/rust/tree/master/tests/run-make -[codegen-test]: https://github.com/rust-lang/rust/blob/master/tests/codegen/pgo-instrumentation.rs +[codegen-test]: https://github.com/rust-lang/rust/blob/master/tests/codegen-llvm/pgo-instrumentation.rs ## Additional information diff --git a/src/sanitizers.md b/src/sanitizers.md index 664b4feac..29d9056c1 100644 --- a/src/sanitizers.md +++ b/src/sanitizers.md @@ -76,7 +76,7 @@ implementation: ## Testing sanitizers Sanitizers are validated by code generation tests in -[`tests/codegen/sanitize*.rs`][test-cg] and end-to-end functional tests in +[`tests/codegen-llvm/sanitize*.rs`][test-cg] and end-to-end functional tests in [`tests/ui/sanitizer/`][test-ui] directory. Testing sanitizer functionality requires the sanitizer runtimes (built when @@ -85,7 +85,7 @@ sanitizer. When sanitizer is unsupported on given target, sanitizers tests will be ignored. This behaviour is controlled by compiletest `needs-sanitizer-*` directives. -[test-cg]: https://github.com/rust-lang/rust/tree/master/tests/codegen +[test-cg]: https://github.com/rust-lang/rust/tree/master/tests/codegen-llvm [test-ui]: https://github.com/rust-lang/rust/tree/master/tests/ui/sanitizer ## Enabling sanitizer on a new target diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index 6a60e7118..a108dfdef 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -68,7 +68,7 @@ The following test suites are available, with links for more information: | [`pretty`](#pretty-printer-tests) | Check pretty printing | | [`incremental`](#incremental-tests) | Check incremental compilation behavior | | [`debuginfo`](#debuginfo-tests) | Check debuginfo generation running debuggers | -| [`codegen`](#codegen-tests) | Check code generation | +| [`codegen-*`](#codegen-tests) | Check code generation | | [`codegen-units`](#codegen-units-tests) | Check codegen unit partitioning | | [`assembly`](#assembly-tests) | Check assembly output | | [`mir-opt`](#mir-opt-tests) | Check MIR generation and optimizations | @@ -290,7 +290,7 @@ For example, `./x test tests/debuginfo -- --debugger gdb` will only test GDB com ### Codegen tests -The tests in [`tests/codegen`] test LLVM code generation. They compile the test +The tests in [`tests/codegen-llvm`] test LLVM code generation. They compile the test with the `--emit=llvm-ir` flag to emit LLVM IR. They then run the LLVM [FileCheck] tool. The test is annotated with various `// CHECK` comments to check the generated code. See the [FileCheck] documentation for a tutorial and @@ -301,7 +301,7 @@ See also the [assembly tests](#assembly-tests) for a similar set of tests. If you need to work with `#![no_std]` cross-compiling tests, consult the [`minicore` test auxiliary](./minicore.md) chapter. -[`tests/codegen`]: https://github.com/rust-lang/rust/tree/master/tests/codegen +[`tests/codegen-llvm`]: https://github.com/rust-lang/rust/tree/master/tests/codegen-llvm [FileCheck]: https://llvm.org/docs/CommandGuide/FileCheck.html From 776fa0a09c2d83c3b81dbb7e21b0b15bd5405368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 23 Jul 2025 09:42:33 +0200 Subject: [PATCH 410/447] Update josh sync documentation Now all our Josh subtrees should be using josh-sync. --- src/external-repos.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/external-repos.md b/src/external-repos.md index 44d4b5b4b..5fb7eeee8 100644 --- a/src/external-repos.md +++ b/src/external-repos.md @@ -40,27 +40,24 @@ implement a new tool feature or test, that should happen in one collective rustc * `portable-simd` ([sync script](https://github.com/rust-lang/portable-simd/blob/master/subtree-sync.sh)) * `rustfmt` * `rustc_codegen_cranelift` ([sync script](https://github.com/rust-lang/rustc_codegen_cranelift/blob/113af154d459e41b3dc2c5d7d878e3d3a8f33c69/scripts/rustup.sh#L7)) -* Using the [josh] tool - * `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo)) - * `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147)) - * `rustc-dev-guide` ([josh sync](#synchronizing-a-josh-subtree)) - * `compiler-builtins` ([josh sync](#synchronizing-a-josh-subtree)) - * `stdarch` ([josh sync](#synchronizing-a-josh-subtree)) +* Using the [josh](#synchronizing-a-josh-subtree) tool + * `miri` + * `rust-analyzer` + * `rustc-dev-guide` + * `compiler-builtins` + * `stdarch` ### Josh subtrees -The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh; you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. We provide a helper [`rustc-josh-sync`][josh-sync] tool to help with the synchronization, described [below](#synchronizing-a-josh-subtree). +The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh. We provide a helper [`rustc-josh-sync`][josh-sync] tool to help with the synchronization, described [below](#synchronizing-a-josh-subtree). ### Synchronizing a Josh subtree We use a dedicated tool called [`rustc-josh-sync`][josh-sync] for performing Josh subtree updates. -Currently, we are migrating Josh repositories to it. So far, it is used in: +The commands below can be used for all our Josh subtrees, although note that `miri` +requires you to perform some [additional steps](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo) during pulls. -- compiler-builtins -- rustc-dev-guide -- stdarch - -To install the tool: +You can install the tool using the following command: ``` cargo install --locked --git https://github.com/rust-lang/josh-sync ``` From 93af4af95759ec9d113e07b7bbf3d91ce70174c3 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 24 Jul 2025 04:15:31 +0000 Subject: [PATCH 411/447] Prepare for merging from rust-lang/rust This updates the rust-version file to efd420c770bb179537c01063e98cb6990c439654. --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index f6b7efe51..ce9f984e6 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -460259d14de0274b97b8801e08cb2fe5f16fdac5 +efd420c770bb179537c01063e98cb6990c439654 From 4c0d7c01705ea872dbc9e061a4d7148faa37f354 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 22 Jul 2025 21:42:50 -0400 Subject: [PATCH 412/447] Rename tests/ui/SUMMARY.md and update rustc dev guide on error-pattern --- src/tests/ui.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index 9bfc60e08..b1feef9ed 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -309,7 +309,8 @@ fn main((ؼ Use `//~?` to match an error without line information. `//~?` is precise and will not match errors if their line information is available. -It should be preferred to using `error-pattern`, which is imprecise and non-exhaustive. +For tests wishing to match against compiler diagnostics, error annotations should +be preferred over //@ error-pattern, //@ error-pattern is imprecise and non-exhaustive. ```rust,ignore //@ compile-flags: --print yyyy @@ -347,8 +348,6 @@ fn main() { } ``` -Use of `error-pattern` is not recommended in general. - For strict testing of compile time output, try to use the line annotations `//~` as much as possible, including `//~?` annotations for diagnostics without spans. @@ -359,7 +358,8 @@ Some of the compiler messages can stay uncovered by annotations in this mode. For checking runtime output, `//@ check-run-results` may be preferable. -Only use `error-pattern` if none of the above works. +Only use `error-pattern` if none of the above works, such as when finding a +specific string pattern in a runtime panic output. Line annotations `//~` and `error-pattern` are compatible and can be used in the same test. From 7f7280e8671b38511cae2de9ae577ba4cf59ba4e Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 23 Jan 2025 20:14:53 +0000 Subject: [PATCH 413/447] Add stabilization template and revise docs --- src/implementing_new_features.md | 19 +++++++++ src/stabilization_guide.md | 62 ++++++++++++---------------- src/stabilization_report_template.md | 54 ++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 36 deletions(-) create mode 100644 src/stabilization_report_template.md diff --git a/src/implementing_new_features.md b/src/implementing_new_features.md index 5d0e875cb..10d404c6a 100644 --- a/src/implementing_new_features.md +++ b/src/implementing_new_features.md @@ -206,3 +206,22 @@ tests/ui/feature-gates/ --bless`. [here]: ./stabilization_guide.md [tracking issue]: #tracking-issues [add-feature-gate]: ./feature-gates.md#adding-a-feature-gate + +## Call for testing + +Once the implementation is complete, the feature will be available to nightly users, but not yet part of stable Rust. This is a good time to write a blog post on [one of the Rust blogs](https://github.com/rust-lang/blog.rust-lang.org/) and issue a call for testing (here are two example [blog](https://blog.rust-lang.org/inside-rust/2024/08/09/async-closures-call-for-testing.html) [posts](https://blog.rust-lang.org/2024/09/05/impl-trait-capture-rules.html) to give you the idea). The post should highlight how the feature works, what areas you'd like people to play with, and how they can supply feedback. + +## Affiliated work + +Once the feature is supported by rustc, there is other associated work that needs to be done to give users a complete experience: + +* Extending rustfmt to format any new syntax; +* Extending rust-analyzer; +* Documenting the feature in the Rust reference; +* ... + +## Stabilization + +The final step in the feature lifecycle is [stabilization][stab], which is when the feature becomes available to all Rust users. At this point, backwards incompatible changes are no longer permitted (modulo soundness bugs and inference changes; see the lang team's [defined semver policies](https://rust-lang.github.io/rfcs/1122-language-semver.html) for full details). To learn more about stabilization, see the [stabilization guide][stab]. + +[stab]: ./stabilization_guide.md diff --git a/src/stabilization_guide.md b/src/stabilization_guide.md index f875c6874..213280cce 100644 --- a/src/stabilization_guide.md +++ b/src/stabilization_guide.md @@ -43,44 +43,14 @@ has completed. Meanwhile, we can proceed to the next step. ## Write a stabilization report -Find the tracking issue of the feature, and create a short -stabilization report. Essentially this would be a brief summary -of the feature plus some links to test cases showing it works -as expected, along with a list of edge cases that came up -and were considered. This is a minimal "due diligence" that -we do before stabilizing. - -The report should contain: - -- A summary, showing examples (e.g. code snippets) what is - enabled by this feature. -- Links to test cases in our test suite regarding this feature - and describe the feature's behavior on encountering edge cases. -- Links to the documentations (the PRs we have made in the - previous steps). -- Any other relevant information. -- The resolutions of any unresolved questions if the stabilization - is for an RFC. - -Examples of stabilization reports can be found in -[rust-lang/rust#44494][report1] and [rust-lang/rust#28237][report2] (these links -will bring you directly to the comment containing the stabilization report). - -[report1]: https://github.com/rust-lang/rust/issues/44494#issuecomment-360191474 -[report2]: https://github.com/rust-lang/rust/issues/28237#issuecomment-363374130 - -## FCP - -If any member of the team responsible for tracking this -feature agrees with stabilizing this feature, they will -start the FCP (final-comment-period) process by commenting +Author a stabilization report using the [template found in this repository][srt]. +Stabilization reports summarize the work that has been done since the RFC. +The [template][srt] includes a series of questions that aim to surface interconnections between this feature and the various Rust teams (lang, types, etc) and also to identify items that are commonly overlooked. -```text -@rfcbot fcp merge -``` +[srt]: ./stabilization_report_template.md -The rest of the team members will review the proposal. If the final -decision is to stabilize, we proceed to do the actual code modification. +The stabilization report is typically posted as the main comment on the stabilization PR (see the next section). +If you'd like to develop the stabilization report incrementally, we recommend adding it to ## Stabilization PR @@ -194,3 +164,23 @@ if something { /* XXX */ } [Rust by Example]: https://github.com/rust-lang/rust-by-example [`Unstable Book`]: https://doc.rust-lang.org/unstable-book/index.html [`src/doc/unstable-book`]: https://github.com/rust-lang/rust/tree/master/src/doc/unstable-book + +## Lang team nomination + +When you feel the PR is ready for consideration by the lang team, you can [nominate the PR](https://lang-team.rust-lang.org/how_to/nominate.html) to get it on the list for discussion in the next meeting. You should also cc the other interacting teams to review the report: + +* `@rust-lang/types`, to look for type system interactions +* `@rust-lang/compiler`, to vouch for implementation quality +* `@rust-lang/opsem`, but only if this feature interacts with unsafe code and can create undefined behavior +* `@rust-lang/libs-api`, but only if there are additions to the standard library + +## FCP proposed on the PR + +Finally, some member of the team responsible for tracking this feature agrees with stabilizing this feature, will +start the FCP (final-comment-period) process by commenting + +```text +@rfcbot fcp merge +``` + +The rest of the team members will review the proposal. If the final decision is to stabilize, the PR will be reviewed by the compiler team like any other PR. diff --git a/src/stabilization_report_template.md b/src/stabilization_report_template.md new file mode 100644 index 000000000..28d5ce0cc --- /dev/null +++ b/src/stabilization_report_template.md @@ -0,0 +1,54 @@ +# Stabilization report template + +> **What is this?** This is a template to use for [stabilization reports](./stabilization_guide.md). It consists of a series of questions that aim to provide the information most commonly needed and to help reviewers be more likely to identify potential problems up front. Not all parts of the template will apply to all stabilizations. Feel free to put N/A if a question doesn't seem to apply to your case. + +## General design + +### What is the RFC for this feature and what changes have occurred to the user-facing design since the RFC was finalized? + +### What behavior are we committing to that has been controversial? Summarize the major arguments pro/con. + +### Are there extensions to this feature that remain unstable? How do we know that we are not accidentally committing to those? + +## Has a call-for-testing period been conducted? If so, what feedback was received? + +## Implementation quality + +### Summarize the major parts of the implementation and provide links into the code (or to PRs) + +An example for async closures: https://rustc-dev-guide.rust-lang.org/coroutine-closures.html + +### Summarize existing test coverage of this feature + +- What does the test coverage landscape for this feature look like? + - (Positive/negative) Behavioral tests? + - (Positive/negative) Interface tests? (e.g. compiler cli interface) + - Maybe link to test folders or individual tests (ui/codegen/assembly/run-make tests, etc.) + - Are there any (intentional/unintentional) gaps in test coverage? + +### What outstanding bugs in the issue tracker involve this feature? Are they stabilization-blocking? + +### Summarize contributors to the feature by name for recognition and assuredness that people involved in the feature agree with stabilization + +### What FIXMEs are still in the code for that feature and why is it ok to leave them there? + +### Which tools need to be adjusted to support this feature. Has this work been done? + +*Consider rustdoc, clippy, rust-analyzer, rustfmt, rustup, docs.rs.* + +## Type system and execution rules + +### What compilation-time checks are done that are needed to prevent undefined behavior? + +(Be sure to link to tests demonstrating that these tests are being done.) + +### Can users use this feature to introduce undefined behavior? (Describe.) + +### What updates are needed to the reference/specification? (link to PRs when they exist) + +## Common interactions + +### Does this feature introduce new expressions and can they produce temporaries? What are the lifetimes of those temporaries? + +### What other unstable features may be exposed by this feature? + From 8ed6b36f52adbb43e3b9cb109164d7c32446371a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 23 Jan 2025 16:48:34 -0500 Subject: [PATCH 414/447] Address review feedback Co-authored-by: lcnr Co-authored-by: Ralf Jung Co-authored-by: waffle --- src/implementing_new_features.md | 2 +- src/stabilization_guide.md | 2 +- src/stabilization_report_template.md | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/implementing_new_features.md b/src/implementing_new_features.md index 10d404c6a..0b153d98a 100644 --- a/src/implementing_new_features.md +++ b/src/implementing_new_features.md @@ -209,7 +209,7 @@ tests/ui/feature-gates/ --bless`. ## Call for testing -Once the implementation is complete, the feature will be available to nightly users, but not yet part of stable Rust. This is a good time to write a blog post on [one of the Rust blogs](https://github.com/rust-lang/blog.rust-lang.org/) and issue a call for testing (here are two example [blog](https://blog.rust-lang.org/inside-rust/2024/08/09/async-closures-call-for-testing.html) [posts](https://blog.rust-lang.org/2024/09/05/impl-trait-capture-rules.html) to give you the idea). The post should highlight how the feature works, what areas you'd like people to play with, and how they can supply feedback. +Once the implementation is complete, the feature will be available to nightly users, but not yet part of stable Rust. This is a good time to write a blog post on [one of the Rust blogs](https://github.com/rust-lang/blog.rust-lang.org/) and issue a call for testing (here are three [example](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push.html) [blog](https://blog.rust-lang.org/inside-rust/2024/08/09/async-closures-call-for-testing.html) [posts](https://blog.rust-lang.org/2024/09/05/impl-trait-capture-rules.html) to give you the idea). The post should highlight how the feature works, what areas you'd like people to play with, and how they can supply feedback. ## Affiliated work diff --git a/src/stabilization_guide.md b/src/stabilization_guide.md index 213280cce..f993bcac8 100644 --- a/src/stabilization_guide.md +++ b/src/stabilization_guide.md @@ -52,7 +52,7 @@ The [template][srt] includes a series of questions that aim to surface interconn The stabilization report is typically posted as the main comment on the stabilization PR (see the next section). If you'd like to develop the stabilization report incrementally, we recommend adding it to -## Stabilization PR +## Stabilization PR for a language feature *This is for stabilizing language features. If you are stabilizing a library feature, see [the stabilization chapter of the std dev guide][std-guide-stabilization] instead.* diff --git a/src/stabilization_report_template.md b/src/stabilization_report_template.md index 28d5ce0cc..b5d3fc68b 100644 --- a/src/stabilization_report_template.md +++ b/src/stabilization_report_template.md @@ -28,10 +28,10 @@ An example for async closures: https://rustc-dev-guide.rust-lang.org/coroutine-c ### What outstanding bugs in the issue tracker involve this feature? Are they stabilization-blocking? -### Summarize contributors to the feature by name for recognition and assuredness that people involved in the feature agree with stabilization - ### What FIXMEs are still in the code for that feature and why is it ok to leave them there? +### Summarize contributors to the feature by name for recognition and assuredness that people involved in the feature agree with stabilization + ### Which tools need to be adjusted to support this feature. Has this work been done? *Consider rustdoc, clippy, rust-analyzer, rustfmt, rustup, docs.rs.* @@ -42,7 +42,7 @@ An example for async closures: https://rustc-dev-guide.rust-lang.org/coroutine-c (Be sure to link to tests demonstrating that these tests are being done.) -### Can users use this feature to introduce undefined behavior? (Describe.) +### Can users use this feature to introduce undefined behavior, or use this feature to break the abstraction of Rust and expose the underlying assembly-level implementation? (Describe.) ### What updates are needed to the reference/specification? (link to PRs when they exist) From 9c95d86caa40d38762379146de32bbad63324fb4 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 19 Jun 2025 17:33:15 +0800 Subject: [PATCH 415/447] Address review feedback - Address Call for Testing review feedback - Address Affiliated work review feedback - Drop "stabilization is easy" part - Fix broken feature gate examples - Elaborate on stabilization report summarization aspects - Recommend waiting a bit for team nominations - Make Stabilization Template markdown copy friendly - Register stabilization report template - Drop unfinished sentence - Clarify stabilization report template is for language features - Add test coverage elaboration - Add UB checks / opt question - Amend test coverage explanation - Mention OSS nightly users --- src/SUMMARY.md | 3 +- src/implementing_new_features.md | 32 ++++++-- src/stabilization_guide.md | 33 +++++---- src/stabilization_report_template.md | 107 ++++++++++++++++++++------- 4 files changed, 124 insertions(+), 51 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 651e2925a..e3c0d50fc 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -53,7 +53,8 @@ - [Walkthrough: a typical contribution](./walkthrough.md) - [Implementing new language features](./implementing_new_features.md) - [Stability attributes](./stability.md) -- [Stabilizing Features](./stabilization_guide.md) +- [Stabilizing language features](./stabilization_guide.md) + - [Stabilization report template](./stabilization_report_template.md) - [Feature Gates](./feature-gates.md) - [Coding conventions](./conventions.md) - [Procedures for breaking changes](./bug-fix-procedure.md) diff --git a/src/implementing_new_features.md b/src/implementing_new_features.md index 0b153d98a..0f02e1e9f 100644 --- a/src/implementing_new_features.md +++ b/src/implementing_new_features.md @@ -209,19 +209,39 @@ tests/ui/feature-gates/ --bless`. ## Call for testing -Once the implementation is complete, the feature will be available to nightly users, but not yet part of stable Rust. This is a good time to write a blog post on [one of the Rust blogs](https://github.com/rust-lang/blog.rust-lang.org/) and issue a call for testing (here are three [example](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push.html) [blog](https://blog.rust-lang.org/inside-rust/2024/08/09/async-closures-call-for-testing.html) [posts](https://blog.rust-lang.org/2024/09/05/impl-trait-capture-rules.html) to give you the idea). The post should highlight how the feature works, what areas you'd like people to play with, and how they can supply feedback. +Once the implementation is complete, the feature will be available to nightly users, but not yet part of stable Rust. This is a good time to write a blog post on [the main Rust blog][rust-blog] and issue a **Call for Testing**. + +Some example Call for Testing blog posts: + +1. [The push for GATs stabilization](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push/) +2. [Changes to `impl Trait` in Rust 2024](https://blog.rust-lang.org/2024/09/05/impl-trait-capture-rules.html) +3. [Async Closures MVP: Call for Testing!](https://blog.rust-lang.org/inside-rust/2024/08/09/async-closures-call-for-testing/) + +Alternatively, [*This Week in Rust*][twir] has a [call-for-testing section][twir-cft]. Example: + +- [Call for testing on boolean literals as cfg predicates](https://github.com/rust-lang/rust/issues/131204#issuecomment-2569314526). + +Which option to choose might depend on how significant the language change is, though note that [*This Week in Rust*][twir]'s Call for Testing section might be less visible than a dedicated post on the main Rust blog. ## Affiliated work -Once the feature is supported by rustc, there is other associated work that needs to be done to give users a complete experience: +Once the feature is supported by rustc, there is other associated work that needs to be done to give users a complete experience. Think of it as the *language toolchain* developer experience, which doesn't only comprise of the language or compiler in isolation. -* Extending rustfmt to format any new syntax; -* Extending rust-analyzer; -* Documenting the feature in the Rust reference; -* ... +- Documenting the language feature in the [Rust Reference][reference]. +- (If applicable) Extending [`rustfmt`] to format any new syntax. +- (If applicable) Extending [`rust-analyzer`]. This can depend on the nature of the language feature, as some features don't need to be blocked on *full* support. + - A blocking concern is when a language feature degrades the user experience simply by existing before its support is implemented in [`rust-analyzer`]. + - Example blocking concern: new syntax that [`rust-analyzer`] can't parse -> bogus diagnostics, type inference changes -> bogus diagnostics. ## Stabilization The final step in the feature lifecycle is [stabilization][stab], which is when the feature becomes available to all Rust users. At this point, backwards incompatible changes are no longer permitted (modulo soundness bugs and inference changes; see the lang team's [defined semver policies](https://rust-lang.github.io/rfcs/1122-language-semver.html) for full details). To learn more about stabilization, see the [stabilization guide][stab]. + [stab]: ./stabilization_guide.md +[rust-blog]: https://github.com/rust-lang/blog.rust-lang.org/ +[twir]: https://github.com/rust-lang/this-week-in-rust +[twir-cft]: https://this-week-in-rust.org/blog/2025/01/22/this-week-in-rust-583/#calls-for-testing +[`rustfmt`]: https://github.com/rust-lang/rustfmt +[`rust-analyzer`]: https://github.com/rust-lang/rust-analyzer +[reference]: https://github.com/rust-lang/reference diff --git a/src/stabilization_guide.md b/src/stabilization_guide.md index f993bcac8..98a6fcf8c 100644 --- a/src/stabilization_guide.md +++ b/src/stabilization_guide.md @@ -44,24 +44,24 @@ has completed. Meanwhile, we can proceed to the next step. ## Write a stabilization report Author a stabilization report using the [template found in this repository][srt]. -Stabilization reports summarize the work that has been done since the RFC. -The [template][srt] includes a series of questions that aim to surface interconnections between this feature and the various Rust teams (lang, types, etc) and also to identify items that are commonly overlooked. + +Stabilization reports summarize: + +- The main design decisions and deviations since the RFC was accepted, particularly decisions that were FCP'd or otherwise accepted by the language team. + - Quite often, the final stabilized language feature can have significant design deviations from the original RFC text. +- The work that has been done since the RFC was accepted, acknowledging the main contributors that helped drive the language feature forward. + +The [*Stabilization Template*][srt] includes a series of questions that aim to surface interconnections between this feature and the various Rust teams (lang, types, etc) and also to identify items that are commonly overlooked. [srt]: ./stabilization_report_template.md The stabilization report is typically posted as the main comment on the stabilization PR (see the next section). -If you'd like to develop the stabilization report incrementally, we recommend adding it to ## Stabilization PR for a language feature *This is for stabilizing language features. If you are stabilizing a library feature, see [the stabilization chapter of the std dev guide][std-guide-stabilization] instead.* -Once we have decided to stabilize a feature, we need to have -a PR that actually makes that stabilization happen. These kinds -of PRs are a great way to get involved in Rust, as they take -you on a little tour through the source code. - Here is a general guide to how to stabilize a feature -- every feature is different, of course, so some features may require steps beyond what this guide talks about. @@ -121,8 +121,7 @@ same `compiler/rustc_ast_passes/src/feature_gate.rs`. For example, you might see code like this: ```rust,ignore -gate_feature_post!(&self, pub_restricted, span, - "`pub(restricted)` syntax is experimental"); +gate_all!(pub_restricted, "`pub(restricted)` syntax is experimental"); ``` This `gate_feature_post!` macro prints an error if the @@ -132,7 +131,7 @@ now that `#[pub_restricted]` is stable. For more subtle features, you may find code like this: ```rust,ignore -if self.tcx.sess.features.borrow().pub_restricted { /* XXX */ } +if self.tcx.features().async_fn_in_dyn_trait() { /* XXX */ } ``` This `pub_restricted` field (obviously named after the feature) @@ -165,14 +164,16 @@ if something { /* XXX */ } [`Unstable Book`]: https://doc.rust-lang.org/unstable-book/index.html [`src/doc/unstable-book`]: https://github.com/rust-lang/rust/tree/master/src/doc/unstable-book -## Lang team nomination +## Team nominations -When you feel the PR is ready for consideration by the lang team, you can [nominate the PR](https://lang-team.rust-lang.org/how_to/nominate.html) to get it on the list for discussion in the next meeting. You should also cc the other interacting teams to review the report: +After the stabilization PR is opened with the stabilization report, wait a bit for potential immediate comments. When such immediate comments "simmer down" and you feel the PR is ready for consideration by the lang team, you can [nominate the PR](https://lang-team.rust-lang.org/how_to/nominate.html) to get it on the list for discussion in the next meeting. You should also cc the other interacting teams when applicable to review the language feature being stabilized and the stabilization report: * `@rust-lang/types`, to look for type system interactions -* `@rust-lang/compiler`, to vouch for implementation quality -* `@rust-lang/opsem`, but only if this feature interacts with unsafe code and can create undefined behavior -* `@rust-lang/libs-api`, but only if there are additions to the standard library +* `@rust-lang/compiler`, to review implementation robustness +* `@rust-lang/opsem`, if this feature interacts with unsafe code and can create undefined behavior +* `@rust-lang/libs-api`, if there are additions to the standard library that affects standard library API or their guarantees + +If you are not an organization member, you can simply ask your assigned reviewer to cc the relevant teams on your behalf. ## FCP proposed on the PR diff --git a/src/stabilization_report_template.md b/src/stabilization_report_template.md index b5d3fc68b..90437ee7a 100644 --- a/src/stabilization_report_template.md +++ b/src/stabilization_report_template.md @@ -1,54 +1,105 @@ # Stabilization report template -> **What is this?** This is a template to use for [stabilization reports](./stabilization_guide.md). It consists of a series of questions that aim to provide the information most commonly needed and to help reviewers be more likely to identify potential problems up front. Not all parts of the template will apply to all stabilizations. Feel free to put N/A if a question doesn't seem to apply to your case. +> **What is this?** +> +> This is a template to use for [stabilization reports](./stabilization_guide.md) of **language features**. It consists of a series of questions that aim to provide the information most commonly needed and to help reviewers be more likely to identify potential problems up front. Not all parts of the template will apply to all stabilizations. Feel free to put N/A if a question doesn't seem to apply to your case. +> +> You can copy the following template after the separator and edit it as Markdown, replacing the *TODO* placeholders with answers. -## General design +--- -### What is the RFC for this feature and what changes have occurred to the user-facing design since the RFC was finalized? +> ## General design -### What behavior are we committing to that has been controversial? Summarize the major arguments pro/con. +> ### What is the RFC for this feature and what changes have occurred to the user-facing design since the RFC was finalized? -### Are there extensions to this feature that remain unstable? How do we know that we are not accidentally committing to those? +*TODO* -## Has a call-for-testing period been conducted? If so, what feedback was received? +> ### What behavior are we committing to that has been controversial? Summarize the major arguments pro/con. -## Implementation quality +*TODO* -### Summarize the major parts of the implementation and provide links into the code (or to PRs) +> ### Are there extensions to this feature that remain unstable? How do we know that we are not accidentally committing to those? -An example for async closures: https://rustc-dev-guide.rust-lang.org/coroutine-closures.html +*TODO* -### Summarize existing test coverage of this feature +> ## Has a Call for Testing period been conducted? If so, what feedback was received? +> +> Does any OSS nightly users use this feature? For instance, a useful indication might be "search for `#![feature(FEATURE_NAME)]` and had `N` results". -- What does the test coverage landscape for this feature look like? - - (Positive/negative) Behavioral tests? - - (Positive/negative) Interface tests? (e.g. compiler cli interface) - - Maybe link to test folders or individual tests (ui/codegen/assembly/run-make tests, etc.) - - Are there any (intentional/unintentional) gaps in test coverage? +*TODO* -### What outstanding bugs in the issue tracker involve this feature? Are they stabilization-blocking? +> ## Implementation quality -### What FIXMEs are still in the code for that feature and why is it ok to leave them there? +*TODO* -### Summarize contributors to the feature by name for recognition and assuredness that people involved in the feature agree with stabilization +> ### Summarize the major parts of the implementation and provide links into the code (or to PRs) +> +> An example for async closures: . -### Which tools need to be adjusted to support this feature. Has this work been done? +*TODO* -*Consider rustdoc, clippy, rust-analyzer, rustfmt, rustup, docs.rs.* +> ### Summarize existing test coverage of this feature +> +> Consider what the "edges" of this feature are. We're particularly interested in seeing tests that assure us about exactly what nearby things we're not stabilizing. +> +> Within each test, include a comment at the top describing the purpose of the test and what set of invariants it intends to demonstrate. This is a great help to those reviewing the tests at stabilization time. +> +> - What does the test coverage landscape for this feature look like? +> - Tests for compiler errors when you use the feature wrongly or make mistakes? +> - Tests for the feature itself: +> - Limits of the feature (so failing compilation) +> - Exercises of edge cases of the feature +> - Tests that checks the feature works as expected (where applicable, `//@ run-pass`). +> - Are there any intentional gaps in test coverage? +> +> Link to test folders or individual tests (ui/codegen/assembly/run-make tests, etc.). -## Type system and execution rules +*TODO* -### What compilation-time checks are done that are needed to prevent undefined behavior? +> ### What outstanding bugs in the issue tracker involve this feature? Are they stabilization-blocking? -(Be sure to link to tests demonstrating that these tests are being done.) +*TODO* -### Can users use this feature to introduce undefined behavior, or use this feature to break the abstraction of Rust and expose the underlying assembly-level implementation? (Describe.) +> ### What FIXMEs are still in the code for that feature and why is it ok to leave them there? -### What updates are needed to the reference/specification? (link to PRs when they exist) +*TODO* -## Common interactions +> ### Summarize contributors to the feature by name for recognition and assuredness that people involved in the feature agree with stabilization -### Does this feature introduce new expressions and can they produce temporaries? What are the lifetimes of those temporaries? +*TODO* -### What other unstable features may be exposed by this feature? +> ### Which tools need to be adjusted to support this feature. Has this work been done? +> +> Consider rustdoc, clippy, rust-analyzer, rustfmt, rustup, docs.rs. +*TODO* + +> ## Type system and execution rules + +> ### What compilation-time checks are done that are needed to prevent undefined behavior? +> +> (Be sure to link to tests demonstrating that these tests are being done.) + +*TODO* + +> ### Does the feature's implementation need checks to prevent UB or is it sound by default and needs opt in in places to perform the dangerous/unsafe operations? If it is not sound by default, what is the rationale? + +*TODO* + +> ### Can users use this feature to introduce undefined behavior, or use this feature to break the abstraction of Rust and expose the underlying assembly-level implementation? (Describe.) + +*TODO* + +> ### What updates are needed to the reference/specification? (link to PRs when they exist) + +*TODO* + +> ## Common interactions + +> ### Does this feature introduce new expressions and can they produce temporaries? What are the lifetimes of those temporaries? + +*TODO* + +> ### What other unstable features may be exposed by this feature? + +*TODO* From d3fba5ef3bf9982557b93937d196b8b8fe6655ff Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 23 Jul 2025 06:16:25 +0000 Subject: [PATCH 416/447] Revise content on lang feature processes Let's revise both the new content in this PR as well as the remaining text in the relevant chapters so as to better describe our current processes related to language features and their stabilizations. For the new stabilization report template, based on reviewing its early use and well as reviewing earlier stabilization reports, we've revised it editorially and added questions designed to capture additional details to which we commonly want people to speak. --- src/implementing_new_features.md | 201 +++++++-------------- src/stabilization_guide.md | 141 ++++++--------- src/stabilization_report_template.md | 254 ++++++++++++++++++++++----- 3 files changed, 333 insertions(+), 263 deletions(-) diff --git a/src/implementing_new_features.md b/src/implementing_new_features.md index 0f02e1e9f..76cf2386c 100644 --- a/src/implementing_new_features.md +++ b/src/implementing_new_features.md @@ -2,145 +2,91 @@ -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. +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].** +**NOTE: This section is for *language* features, not *library* features, which use [a different process].** -See also [the Rust Language Design Team's procedures][lang-propose] for -proposing changes to the language. +See also [the Rust Language Design Team's procedures][lang-propose] for proposing changes to the language. [a different process]: ./stability.md [lang-propose]: https://lang-team.rust-lang.org/how_to/propose.html ## The @rfcbot FCP process -When the change is small and uncontroversial, then it can be done -with just writing a PR and getting an r+ from someone who knows that -part of the code. However, if the change is potentially controversial, -it would be a bad idea to push it without consensus from the rest -of the team (both in the "distributed system" sense to make sure -you don't break anything you don't know about, and in the social -sense to avoid PR fights). - -If such a change seems to be too small to require a full formal RFC process -(e.g., a small standard library addition, a big refactoring of the code, a -"technically-breaking" change, or a "big bugfix" that basically amounts to a -small feature) but is still too controversial or big to get by with a single r+, -you can propose a final comment period (FCP). Or, if you're not on the relevant -team (and thus don't have @rfcbot permissions), ask someone who is to start one; -unless they have a concern themselves, they should. - -Again, the FCP process is only needed if you need consensus – if you -don't think anyone would have a problem with your change, it's OK to -get by with only an r+. For example, it is OK to add or modify -unstable command-line flags or attributes without an FCP for -compiler development or standard library use, as long as you don't -expect them to be in wide use in the nightly ecosystem. -Some teams have lighter weight processes that they use in scenarios -like this; for example, the compiler team recommends -filing a Major Change Proposal ([MCP][mcp]) as a lightweight way to -garner support and feedback without requiring full consensus. +When the change is small, uncontroversial, non-breaking, and does not affect the stable language in any user-observable ways or add any new unstable features, then it can be done with just writing a PR and getting an r+ from someone who knows that part of the code. However, if not, more must be done. Even for compiler-internal work, it would be a bad idea to push a controversial change without consensus from the rest of the team (both in the "distributed system" sense to make sure you don't break anything you don't know about, and in the social sense to avoid PR fights). + +For changes that need the consensus of a team, we us the process of proposing a final comment period (FCP). If you're not on the relevant team (and thus don't have @rfcbot permissions), ask someone who is to start one; unless they have a concern themselves, they should. + +The FCP process is only needed if you need consensus – if no processes require consensus for your change and you don't think anyone would have a problem with it, it's OK to rely on only an r+. For example, it is OK to add or modify unstable command-line flags or attributes in the reserved compiler-internal `rustc_` namespace without an FCP for compiler development or standard library use, as long as you don't expect them to be in wide use in the nightly ecosystem. Some teams have lighter weight processes that they use in scenarios like this; for example, the compiler team recommends filing a Major Change Proposal ([MCP][mcp]) as a lightweight way to garner support and feedback without requiring full consensus. [mcp]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp -You don't need to have the implementation fully ready for r+ to propose an FCP, -but it is generally a good idea to have at least a proof -of concept so that people can see what you are talking about. +You don't need to have the implementation fully ready for r+ to propose an FCP, but it is generally a good idea to have at least a proof of concept so that people can see what you are talking about. -When an FCP is proposed, it requires all members of the team to sign off the -FCP. After they all do so, there's a 10-day-long "final comment period" (hence -the name) where everybody can comment, and if no concerns are raised, the -PR/issue gets FCP approval. +When an FCP is proposed, it requires all members of the team to sign off on the FCP. After they all do so, there's a 10-day-long "final comment period" (hence the name) where everybody can comment, and if no concerns are raised, the PR/issue gets FCP approval. ## The logistics of writing features -There are a few "logistic" hoops you might need to go through in -order to implement a feature in a working way. +There are a few "logistical" hoops you might need to go through in order to implement a feature in a working way. ### Warning Cycles -In some cases, a feature or bugfix might break some existing programs -in some edge cases. In that case, you might want to do a crater run -to assess the impact and possibly add a future-compatibility lint, -similar to those used for -[edition-gated lints](diagnostics.md#edition-gated-lints). +In some cases, a feature or bugfix might break some existing programs in some edge cases. In that case, you'll want to do a crater run to assess the impact and possibly add a future-compatibility lint, similar to those used for [edition-gated lints](diagnostics.md#edition-gated-lints). ### Stability -We [value the stability of Rust]. Code that works and runs on stable -should (mostly) not break. Because of that, we don't want to release -a feature to the world with only team consensus and code review - -we want to gain real-world experience on using that feature on nightly, -and we might want to change the feature based on that experience. - -To allow for that, we must make sure users don't accidentally depend -on that new feature - otherwise, especially if experimentation takes -time or is delayed and the feature takes the trains to stable, -it would end up de facto stable and we'll not be able to make changes -in it without breaking people's code. - -The way we do that is that we make sure all new features are feature -gated - they can't be used without enabling a feature gate -(`#[feature(foo)]`), which can't be done in a stable/beta compiler. -See the [stability in code] section for the technical details. - -Eventually, after we gain enough experience using the feature, -make the necessary changes, and are satisfied, we expose it to -the world using the stabilization process described [here]. -Until then, the feature is not set in stone: every part of the -feature can be changed, or the feature might be completely -rewritten or removed. Features are not supposed to gain tenure -by being unstable and unchanged for a year. +We [value the stability of Rust]. Code that works and runs on stable should (mostly) not break. Because of that, we don't want to release a feature to the world with only team consensus and code review - we want to gain real-world experience on using that feature on nightly, and we might want to change the feature based on that experience. + +To allow for that, we must make sure users don't accidentally depend on that new feature - otherwise, especially if experimentation takes time or is delayed and the feature takes the trains to stable, it would end up de facto stable and we'll not be able to make changes in it without breaking people's code. + +The way we do that is that we make sure all new features are feature gated - they can't be used without enabling a feature gate (`#[feature(foo)]`), which can't be done in a stable/beta compiler. See the [stability in code] section for the technical details. + +Eventually, after we gain enough experience using the feature, make the necessary changes, and are satisfied, we expose it to the world using the stabilization process described [here]. Until then, the feature is not set in stone: every part of the feature can be changed, or the feature might be completely rewritten or removed. Features do not gain tenure by being unstable and unchanged for long periods of time. ### Tracking Issues -To keep track of the status of an unstable feature, the -experience we get while using it on nightly, and of the -concerns that block its stabilization, every feature-gate -needs a tracking issue. General discussions about the feature should be done on the tracking issue. +To keep track of the status of an unstable feature, the experience we get while using it on +nightly, and of the concerns that block its stabilization, every feature-gate needs a tracking +issue. When creating issues and PRs related to the feature, reference this tracking issue, and when there are updates about the feature's progress, post those to the tracking issue. -For features that have an RFC, you should use the RFC's -tracking issue for the feature. +For features that are part of an accept RFC or approved lang experiment, use the tracking issue for that. -For other features, you'll have to make a tracking issue -for that feature. The issue title should be "Tracking issue -for YOUR FEATURE". Use the ["Tracking Issue" issue template][template]. +For other features, create a tracking issue for that feature. The issue title should be "Tracking issue for YOUR FEATURE". Use the ["Tracking Issue" issue template][template]. [template]: https://github.com/rust-lang/rust/issues/new?template=tracking_issue.md +### Lang experiments + +To land in the compiler, features that have user-visible effects on the language (even unstable ones) must either be part of an accepted RFC or an approved [lang experiment]. + +To propose a new lang experiment, open an issue in `rust-lang/rust` that describes the motivation and the intended solution. If it's accepted, this issue will become the tracking issue for the experiment, so use the tracking issue [template] while also including these other details. Nominate the issue for the lang team and CC `@rust-lang/lang` and `@rust-lang/lang-advisors`. When the experiment is approved, the tracking issue will be marked as `B-experimental`. + +Feature flags related to a lang experiment must be marked as `incomplete` until an RFC is accepted for the feature. + +[lang experiment]: https://lang-team.rust-lang.org/how_to/experiment.html + ## Stability in code -The below steps needs to be followed in order to implement -a new unstable feature: +The below steps needs to be followed in order to implement a new unstable feature: -1. Open a [tracking issue] - - if you have an RFC, you can use the tracking issue for the RFC. +1. Open or identify the [tracking issue]. For features that are part of an accept RFC or approved lang experiment, use the tracking issue for that. - The tracking issue should be labeled with at least `C-tracking-issue`. - For a language feature, a label `F-feature_name` should be added as well. + Label the tracking issue with `C-tracking-issue` and the relevant `F-feature_name` label (adding that label if needed). -1. Pick a name for the feature gate (for RFCs, use the name - in the RFC). +1. Pick a name for the feature gate (for RFCs, use the name in the RFC). 1. Add the feature name to `rustc_span/src/symbol.rs` in the `Symbols {...}` block. Note that this block must be in alphabetical order. -1. Add a feature gate declaration to `rustc_feature/src/unstable.rs` in the unstable - `declare_features` block. +1. Add a feature gate declaration to `rustc_feature/src/unstable.rs` in the unstable `declare_features` block. ```rust ignore /// description of feature (unstable, $feature_name, "CURRENT_RUSTC_VERSION", Some($tracking_issue_number)) ``` - If you haven't yet - opened a tracking issue (e.g. because you want initial feedback on whether the feature is likely - to be accepted), you can temporarily use `None` - but make sure to update it before the PR is - merged! + If you haven't yet opened a tracking issue (e.g. because you want initial feedback on whether the feature is likely to be accepted), you can temporarily use `None` - but make sure to update it before the PR is merged! For example: @@ -149,9 +95,7 @@ a new unstable feature: (unstable, non_ascii_idents, "CURRENT_RUSTC_VERSION", Some(55467), None), ``` - Features can be marked as incomplete, and trigger the warn-by-default [`incomplete_features` - lint] - by setting their type to `incomplete`: + Features can be marked as incomplete, and trigger the warn-by-default [`incomplete_features` lint] by setting their type to `incomplete`: [`incomplete_features` lint]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#incomplete-features @@ -160,42 +104,27 @@ a new unstable feature: (incomplete, deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121), None), ``` - To avoid [semantic merge conflicts], please use `CURRENT_RUSTC_VERSION` instead of `1.70` or - another explicit version number. + Feature flags related to a lang experiment must be marked as `incomplete` until an RFC is accepted for the feature. + + To avoid [semantic merge conflicts], use `CURRENT_RUSTC_VERSION` instead of `1.70` or another explicit version number. [semantic merge conflicts]: https://bors.tech/essay/2017/02/02/pitch/ -1. Prevent usage of the new feature unless the feature gate is set. - You can check it in most places in the compiler using the - expression `tcx.features().$feature_name()` +1. Prevent usage of the new feature unless the feature gate is set. You can check it in most places in the compiler using the expression `tcx.features().$feature_name()`. + + If the feature gate is not set, you should either maintain the pre-feature behavior or raise an error, depending on what makes sense. Errors should generally use [`rustc_session::parse::feature_err`]. For an example of adding an error, see [#81015]. - If the feature gate is not set, you should either maintain - the pre-feature behavior or raise an error, depending on - what makes sense. Errors should generally use [`rustc_session::parse::feature_err`]. - For an example of adding an error, see [#81015]. + For features introducing new syntax, pre-expansion gating should be used instead. During parsing, when the new syntax is parsed, the symbol must be inserted to the current crate's [`GatedSpans`] via `self.sess.gated_span.gate(sym::my_feature, span)`. - For features introducing new syntax, pre-expansion gating should be used instead. - During parsing, when the new syntax is parsed, the symbol must be inserted to the - current crate's [`GatedSpans`] via `self.sess.gated_span.gate(sym::my_feature, span)`. - - After being inserted to the gated spans, the span must be checked in the - [`rustc_ast_passes::feature_gate::check_crate`] function, which actually denies - features. Exactly how it is gated depends on the exact type of feature, but most - likely will use the `gate_all!()` macro. + After being inserted to the gated spans, the span must be checked in the [`rustc_ast_passes::feature_gate::check_crate`] function, which actually denies features. Exactly how it is gated depends on the exact type of feature, but most likely will use the `gate_all!()` macro. -1. Add a test to ensure the feature cannot be used without - a feature gate, by creating `tests/ui/feature-gates/feature-gate-$feature_name.rs`. - You can generate the corresponding `.stderr` file by running `./x test -tests/ui/feature-gates/ --bless`. +1. Add a test to ensure the feature cannot be used without a feature gate, by creating `tests/ui/feature-gates/feature-gate-$feature_name.rs`. You can generate the corresponding `.stderr` file by running `./x test tests/ui/feature-gates/ --bless`. -1. Add a section to the unstable book, in - `src/doc/unstable-book/src/language-features/$feature_name.md`. +1. Add a section to the unstable book, in `src/doc/unstable-book/src/language-features/$feature_name.md`. -1. Write a lot of tests for the new feature, preferably in `tests/ui/$feature_name/`. - PRs without tests will not be accepted! +1. Write a lot of tests for the new feature, preferably in `tests/ui/$feature_name/`. PRs without tests will not be accepted! -1. Get your PR reviewed and land it. You have now successfully - implemented a feature in Rust! +1. Get your PR reviewed and land it. You have now successfully implemented a feature in Rust! [`GatedSpans`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.GatedSpans.html [#81015]: https://github.com/rust-lang/rust/pull/81015 @@ -209,33 +138,33 @@ tests/ui/feature-gates/ --bless`. ## Call for testing -Once the implementation is complete, the feature will be available to nightly users, but not yet part of stable Rust. This is a good time to write a blog post on [the main Rust blog][rust-blog] and issue a **Call for Testing**. +Once the implementation is complete, the feature will be available to nightly users but not yet part of stable Rust. This is a good time to write a blog post on [the main Rust blog][rust-blog] and issue a "call for testing". -Some example Call for Testing blog posts: +Some earlier such blog posts include: 1. [The push for GATs stabilization](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push/) 2. [Changes to `impl Trait` in Rust 2024](https://blog.rust-lang.org/2024/09/05/impl-trait-capture-rules.html) 3. [Async Closures MVP: Call for Testing!](https://blog.rust-lang.org/inside-rust/2024/08/09/async-closures-call-for-testing/) -Alternatively, [*This Week in Rust*][twir] has a [call-for-testing section][twir-cft]. Example: +Alternatively, [*This Week in Rust*][twir] has a [section][twir-cft] for this. One example of this having been used is: -- [Call for testing on boolean literals as cfg predicates](https://github.com/rust-lang/rust/issues/131204#issuecomment-2569314526). +- [Call for testing on boolean literals as cfg predicates](https://github.com/rust-lang/rust/issues/131204#issuecomment-2569314526) -Which option to choose might depend on how significant the language change is, though note that [*This Week in Rust*][twir]'s Call for Testing section might be less visible than a dedicated post on the main Rust blog. +Which option to choose might depend on how significant the language change is, though note that the [*This Week in Rust*][twir] section might be less visible than a dedicated post on the main Rust blog. -## Affiliated work +## Polishing -Once the feature is supported by rustc, there is other associated work that needs to be done to give users a complete experience. Think of it as the *language toolchain* developer experience, which doesn't only comprise of the language or compiler in isolation. +Giving users a polished experience means more than just implementing the feature in rustc. We need to think about all of the tools and resources that we ship. This work includes: - Documenting the language feature in the [Rust Reference][reference]. -- (If applicable) Extending [`rustfmt`] to format any new syntax. -- (If applicable) Extending [`rust-analyzer`]. This can depend on the nature of the language feature, as some features don't need to be blocked on *full* support. - - A blocking concern is when a language feature degrades the user experience simply by existing before its support is implemented in [`rust-analyzer`]. - - Example blocking concern: new syntax that [`rust-analyzer`] can't parse -> bogus diagnostics, type inference changes -> bogus diagnostics. +- Extending [`rustfmt`] to format any new syntax (if applicable). +- Extending [`rust-analyzer`] (if applicable). The extent of this work can depend on the nature of the language feature, as some features don't need to be blocked on *full* support. + - When a language feature degrades the user experience simply by existing before support is implemented in [`rust-analyzer`], that may lead the lang team to raise a blocking concern. + - Examples of such might include new syntax that [`rust-analyzer`] can't parse or type inference changes it doesn't understand when those lead to bogus diagnostics. ## Stabilization -The final step in the feature lifecycle is [stabilization][stab], which is when the feature becomes available to all Rust users. At this point, backwards incompatible changes are no longer permitted (modulo soundness bugs and inference changes; see the lang team's [defined semver policies](https://rust-lang.github.io/rfcs/1122-language-semver.html) for full details). To learn more about stabilization, see the [stabilization guide][stab]. +The final step in the feature lifecycle is [stabilization][stab], which is when the feature becomes available to all Rust users. At this point, backward incompatible changes are generally no longer permitted (see the lang team's [defined semver policies](https://rust-lang.github.io/rfcs/1122-language-semver.html) for details). To learn more about stabilization, see the [stabilization guide][stab]. [stab]: ./stabilization_guide.md diff --git a/src/stabilization_guide.md b/src/stabilization_guide.md index 98a6fcf8c..f155272e5 100644 --- a/src/stabilization_guide.md +++ b/src/stabilization_guide.md @@ -1,90 +1,66 @@ # Request for stabilization -**NOTE**: this page is about stabilizing *language* features. -For stabilizing *library* features, see [Stabilizing a library feature]. +**NOTE**: This page is about stabilizing *language* features. For stabilizing *library* features, see [Stabilizing a library feature]. [Stabilizing a library feature]: ./stability.md#stabilizing-a-library-feature -Once an unstable feature has been well-tested with no outstanding -concern, anyone may push for its stabilization. It involves the -following steps: +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: -## Documentation PRs +## 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. + +[lang experiment]: https://lang-team.rust-lang.org/how_to/experiment.html -If any documentation for this feature exists, it should be -in the [`Unstable Book`], located at [`src/doc/unstable-book`]. -If it exists, the page for the feature gate should be removed. +## Documentation PRs -If there was documentation there, integrating it into the -existing documentation is needed. + -If there wasn't documentation there, it needs to be added. +The feature might be documented in the [`Unstable Book`], located at [`src/doc/unstable-book`]. Remove the page for the feature gate if it exists. Integrate any useful parts of that documentation in other places. -Places that may need updated documentation: +Places that may need updated documentation include: -- [The Reference]: This must be updated, in full detail. -- [The Book]: This may or may not need updating, depends. - If you're not sure, please open an issue on this repository - and it can be discussed. -- standard library documentation: As needed. Language features - often don't need this, but if it's a feature that changes - how good examples are written, such as when `?` was added - to the language, updating examples is important. -- [Rust by Example]: As needed. +- [The Reference]: This must be updated, in full detail, and a member of the lang-docs team must review and approve the PR before the stabilization can be merged. +- [The Book]: This is updated as needed. If you're not sure, please open an issue on this repository and it can be discussed. +- Standard library documentation: This is updated as needed. Language features often don't need this, but if it's a feature that changes how idiomatic examples are written, such as when `?` was added to the language, updating these in the library documentation is important. Review also the keyword documentation and ABI documentation in the standard library, as these sometimes needs updates for language changes. +- [Rust by Example]: This is updated as needed. -Prepare PRs to update documentation involving this new feature -for repositories mentioned above. Maintainers of these repositories -will keep these PRs open until the whole stabilization process -has completed. Meanwhile, we can proceed to the next step. +Prepare PRs to update documentation involving this new feature for the repositories mentioned above. Maintainers of these repositories will keep these PRs open until the whole stabilization process has completed. Meanwhile, we can proceed to the next step. ## Write a stabilization report Author a stabilization report using the [template found in this repository][srt]. -Stabilization reports summarize: +The stabilization reports summarizes: -- The main design decisions and deviations since the RFC was accepted, particularly decisions that were FCP'd or otherwise accepted by the language team. - - Quite often, the final stabilized language feature can have significant design deviations from the original RFC text. +- The main design decisions and deviations since the RFC was accepted, including both decisions that were FCP'd or otherwise accepted by the language team as well as those being presented to the lang team for the first time. + - Often, the final stabilized language feature has significant design deviations from the original RFC. That's OK, but these deviations must be highlighted and explained carefully. - The work that has been done since the RFC was accepted, acknowledging the main contributors that helped drive the language feature forward. -The [*Stabilization Template*][srt] includes a series of questions that aim to surface interconnections between this feature and the various Rust teams (lang, types, etc) and also to identify items that are commonly overlooked. +The [*Stabilization Template*][srt] includes a series of questions that aim to surface connections between this feature and lang's subteams (e.g. types, opsem, lang-docs, etc.) and to identify items that are commonly overlooked. [srt]: ./stabilization_report_template.md The stabilization report is typically posted as the main comment on the stabilization PR (see the next section). -## Stabilization PR for a language feature - -*This is for stabilizing language features. If you are stabilizing a library -feature, see [the stabilization chapter of the std dev guide][std-guide-stabilization] instead.* +## Stabilization PR -Here is a general guide to how to stabilize a feature -- -every feature is different, of course, so some features may -require steps beyond what this guide talks about. +Every feature is different, and some may require steps beyond what this guide discusses. -Note: Before we stabilize any feature, it's the rule that it -should appear in the documentation. +Before the stabilization will be considered by the lang team, there must be a complete PR to the Reference describing the feature, and before the stabilization PR will be merged, this PR must have been reviewed and approved by the lang-docs team. ### Updating the feature-gate listing -There is a central listing of unstable feature-gates in -[`compiler/rustc_feature/src/unstable.rs`]. Search for the `declare_features!` -macro. There should be an entry for the feature you are aiming -to stabilize, something like (this example is taken from -[rust-lang/rust#32409]: +There is a central listing of unstable feature-gates in [`compiler/rustc_feature/src/unstable.rs`]. Search for the `declare_features!` macro. There should be an entry for the feature you are aiming to stabilize, something like (this example is taken from [rust-lang/rust#32409]: ```rust,ignore // pub(restricted) visibilities (RFC 1422) (unstable, pub_restricted, "CURRENT_RUSTC_VERSION", Some(32409)), ``` -The above line should be moved to [`compiler/rustc_feature/src/accepted.rs`]. -Entries in the `declare_features!` call are sorted, so find the correct place. -When it is done, it should look like: +The above line should be moved to [`compiler/rustc_feature/src/accepted.rs`]. Entries in the `declare_features!` call are sorted, so find the correct place. When it is done, it should look like: ```rust,ignore // pub(restricted) visibilities (RFC 1422) @@ -92,41 +68,23 @@ When it is done, it should look like: // note that we changed this ``` -(Even though you will encounter version numbers in the file of past changes, -you should not put the rustc version you expect your stabilization to happen in, -but instead `CURRENT_RUSTC_VERSION`) +(Even though you will encounter version numbers in the file of past changes, you should not put the rustc version you expect your stabilization to happen in, but instead use `CURRENT_RUSTC_VERSION`.) ### Removing existing uses of the feature-gate -Next search for the feature string (in this case, `pub_restricted`) -in the codebase to find where it appears. Change uses of -`#![feature(XXX)]` from the `std` and any rustc crates (this includes test folders -under `library/` and `compiler/` but not the toplevel `tests/` one) to be -`#![cfg_attr(bootstrap, feature(XXX))]`. This includes the feature-gate -only for stage0, which is built using the current beta (this is -needed because the feature is still unstable in the current beta). +Next, search for the feature string (in this case, `pub_restricted`) in the codebase to find where it appears. Change uses of `#![feature(XXX)]` from the `std` and any rustc crates (this includes test folders under `library/` and `compiler/` but not the toplevel `tests/` one) to be `#![cfg_attr(bootstrap, feature(XXX))]`. This includes the feature-gate only for stage0, which is built using the current beta (this is needed because the feature is still unstable in the current beta). -Also, remove those strings from any tests (e.g. under `tests/`). If there are tests -specifically targeting the feature-gate (i.e., testing that the -feature-gate is required to use the feature, but nothing else), -simply remove the test. +Also, remove those strings from any tests (e.g. under `tests/`). If there are tests specifically targeting the feature-gate (i.e., testing that the feature-gate is required to use the feature, but nothing else), simply remove the test. ### Do not require the feature-gate to use the feature -Most importantly, remove the code which flags an error if the -feature-gate is not present (since the feature is now considered -stable). If the feature can be detected because it employs some -new syntax, then a common place for that code to be is in the -same `compiler/rustc_ast_passes/src/feature_gate.rs`. -For example, you might see code like this: +Most importantly, remove the code which flags an error if the feature-gate is not present (since the feature is now considered stable). If the feature can be detected because it employs some new syntax, then a common place for that code to be is in `compiler/rustc_ast_passes/src/feature_gate.rs`. For example, you might see code like this: ```rust,ignore gate_all!(pub_restricted, "`pub(restricted)` syntax is experimental"); ``` -This `gate_feature_post!` macro prints an error if the -`pub_restricted` feature is not enabled. It is not needed -now that `#[pub_restricted]` is stable. +This `gate_feature_post!` macro prints an error if the `pub_restricted` feature is not enabled. It is not needed now that `#[pub_restricted]` is stable. For more subtle features, you may find code like this: @@ -134,11 +92,7 @@ For more subtle features, you may find code like this: if self.tcx.features().async_fn_in_dyn_trait() { /* XXX */ } ``` -This `pub_restricted` field (obviously named after the feature) -would ordinarily be false if the feature flag is not present -and true if it is. So transform the code to assume that the field -is true. In this case, that would mean removing the `if` and -leaving just the `/* XXX */`. +This `pub_restricted` field (named after the feature) would ordinarily be false if the feature flag is not present and true if it is. So transform the code to assume that the field is true. In this case, that would mean removing the `if` and leaving just the `/* XXX */`. ```rust,ignore if self.tcx.sess.features.borrow().pub_restricted { /* XXX */ } @@ -166,22 +120,37 @@ if something { /* XXX */ } ## Team nominations -After the stabilization PR is opened with the stabilization report, wait a bit for potential immediate comments. When such immediate comments "simmer down" and you feel the PR is ready for consideration by the lang team, you can [nominate the PR](https://lang-team.rust-lang.org/how_to/nominate.html) to get it on the list for discussion in the next meeting. You should also cc the other interacting teams when applicable to review the language feature being stabilized and the stabilization report: +When opening the stabilization PR, CC the lang team and its advisors (`@rust-lang/lang @rust-lang/lang-advisors`) and any other teams to whom the feature is relevant, e.g.: -* `@rust-lang/types`, to look for type system interactions -* `@rust-lang/compiler`, to review implementation robustness -* `@rust-lang/opsem`, if this feature interacts with unsafe code and can create undefined behavior -* `@rust-lang/libs-api`, if there are additions to the standard library that affects standard library API or their guarantees +- `@rust-lang/types`, for type system interactions. +- `@rust-lang/opsem`, for interactions with unsafe code. +- `@rust-lang/compiler`, for implementation robustness. +- `@rust-lang/libs-api`, for changes to the standard library API or its guarantees. +- `@rust-lang/lang-docs`, for questions about how this should be documented in the Reference. -If you are not an organization member, you can simply ask your assigned reviewer to cc the relevant teams on your behalf. +After the stabilization PR is opened with the stabilization report, wait a bit for any immediate comments. When such comments "simmer down" and you feel the PR is ready for consideration by the lang team, [nominate the PR](https://lang-team.rust-lang.org/how_to/nominate.html) to get it on the agenda for consideration in an upcoming lang meeting. -## FCP proposed on the PR +If you are not a `rust-lang` organization member, you can ask your assigned reviewer to CC the relevant teams on your behalf. -Finally, some member of the team responsible for tracking this feature agrees with stabilizing this feature, will -start the FCP (final-comment-period) process by commenting +## Propose FCP on the PR + +After the lang team and other relevant teams review the stabilization, and after you have answered any questions they may have had, a member of one of the teams may propose to accept the stabilization by commenting: ```text @rfcbot fcp merge ``` -The rest of the team members will review the proposal. If the final decision is to stabilize, the PR will be reviewed by the compiler team like any other PR. +Once enough team members have reviewed, the PR will move into a "final comment period" (FCP). If no new concerns are raised, this period will complete and the PR can be merged after implementation review in the usual way. + +## Reviewing and merging stabilizations + +On a stabilization, before giving it the `r+`, ensure that the PR: + +- Matches what the team proposed for stabilization and what is documented in the Reference PR. +- Includes any changes the team decided to request along the way in order to resolve or avoid concerns. +- Is otherwise exactly what is described in the stabilization report and in any relevant RFCs or prior lang FCPs. +- Does not expose on stable behaviors other than those specified, accepted for stabilization, and documented in the Reference. +- Has sufficient tests to convincingly demonstrate these things. +- Is accompanied by a PR to the Reference than has been reviewed and approved by a member of lang-docs. + +In particular, when reviewing the PR, keep an eye out for any user-visible details that the lang team failed to consider and specify. If you find one, describe it and nominate the PR for the lang team. diff --git a/src/stabilization_report_template.md b/src/stabilization_report_template.md index 90437ee7a..793f7d7e4 100644 --- a/src/stabilization_report_template.md +++ b/src/stabilization_report_template.md @@ -1,105 +1,277 @@ # Stabilization report template -> **What is this?** +## What is this? + +This is a template for [stabilization reports](./stabilization_guide.md) of **language features**. The questions aim to solicit the details most often needed. These details help reviewers to identify potential problems upfront. Not all parts of the template will apply to every stabilization. If a question doesn't apply, explain briefly why. + +Copy everything after the separator and edit it as Markdown. Replace each *TODO* with your answer. + +--- + +# Stabilization report + +## Summary + +> Remind us what this feature is and what value it provides. Tell the story of what led up to this stabilization. > -> This is a template to use for [stabilization reports](./stabilization_guide.md) of **language features**. It consists of a series of questions that aim to provide the information most commonly needed and to help reviewers be more likely to identify potential problems up front. Not all parts of the template will apply to all stabilizations. Feel free to put N/A if a question doesn't seem to apply to your case. +> E.g., see: > -> You can copy the following template after the separator and edit it as Markdown, replacing the *TODO* placeholders with answers. +> - [Stabilize AFIT/RPITIT](https://web.archive.org/web/20250329190642/https://github.com/rust-lang/rust/pull/115822) +> - [Stabilize RTN](https://web.archive.org/web/20250321214601/https://github.com/rust-lang/rust/pull/138424) +> - [Stabilize ATPIT](https://web.archive.org/web/20250124214256/https://github.com/rust-lang/rust/pull/120700) +> - [Stabilize opaque type precise capturing](https://web.archive.org/web/20250312173538/https://github.com/rust-lang/rust/pull/127672) ---- +*TODO* + +Tracking: + +- *TODO* (Link to tracking issue.) + +Reference PRs: + +- *TODO* (Link to Reference PRs.) + +cc @rust-lang/lang @rust-lang/lang-advisors + +### What is stabilized + +> Describe each behavior being stabilized and give a short example of code that will now be accepted. + +```rust +todo!() +``` + +### What isn't stabilized + +> Describe any parts of the feature not being stabilized. Talk about what we might want to do later and what doors are being left open for that. If what we're not stabilizing might lead to surprises for users, talk about that in particular. + +## Design + +### Reference + +> What updates are needed to the Reference? Link to each PR. If the Reference is missing content needed for describing this feature, discuss that. -> ## General design +- *TODO* -> ### What is the RFC for this feature and what changes have occurred to the user-facing design since the RFC was finalized? +### RFC history + +> What RFCs have been accepted for this feature? + +- *TODO* + +### Answers to unresolved questions + +> What questions were left unresolved by the RFC? How have they been answered? Link to any relevant lang decisions. *TODO* -> ### What behavior are we committing to that has been controversial? Summarize the major arguments pro/con. +### Post-RFC changes + +> What other user-visible changes have occurred since the RFC was accepted? Describe both changes that the lang team accepted (and link to those decisions) as well as changes that are being presented to the team for the first time in this stabilization report. *TODO* -> ### Are there extensions to this feature that remain unstable? How do we know that we are not accidentally committing to those? +### Key points + +> What decisions have been most difficult and what behaviors to be stabilized have proved most contentious? Summarize the major arguments on all sides and link to earlier documents and discussions. *TODO* -> ## Has a Call for Testing period been conducted? If so, what feedback was received? -> -> Does any OSS nightly users use this feature? For instance, a useful indication might be "search for `#![feature(FEATURE_NAME)]` and had `N` results". +### Nightly extensions + +> Are there extensions to this feature that remain unstable? How do we know that we are not accidentally committing to those? *TODO* -> ## Implementation quality +### Doors closed + +> What doors does this stabilization close for later changes to the language? E.g., does this stabilization make any other RFCs, lang experiments, or known in-flight proposals more difficult or impossible to do later? + +## Feedback + +### Call for testing + +> Has a "call for testing" been done? If so, what feedback was received? + +*TODO* + +### Nightly use + +> Do any known nightly users use this feature? Counting instances of `#![feature(FEATURE_NAME)]` on GitHub with grep might be informative. *TODO* -> ### Summarize the major parts of the implementation and provide links into the code (or to PRs) +## Implementation + +### Major parts + +> Summarize the major parts of the implementation and provide links into the code and to relevant PRs. +> +> See, e.g., this breakdown of the major parts of async closures: > -> An example for async closures: . +> - *TODO* -> ### Summarize existing test coverage of this feature +### Coverage + +> Summarize the test coverage of this feature. +> +> Consider what the "edges" of this feature are. We're particularly interested in seeing tests that assure us about exactly what nearby things we're not stabilizing. Tests should of course comprehensively demonstrate that the feature works. Think too about demonstrating the diagnostics seen when common mistakes are made and the feature is used incorrectly. > -> Consider what the "edges" of this feature are. We're particularly interested in seeing tests that assure us about exactly what nearby things we're not stabilizing. +> Within each test, include a comment at the top describing the purpose of the test and what set of invariants it intends to demonstrate. This is a great help to our review. > -> Within each test, include a comment at the top describing the purpose of the test and what set of invariants it intends to demonstrate. This is a great help to those reviewing the tests at stabilization time. +> Describe any known or intentional gaps in test coverage. > -> - What does the test coverage landscape for this feature look like? -> - Tests for compiler errors when you use the feature wrongly or make mistakes? -> - Tests for the feature itself: -> - Limits of the feature (so failing compilation) -> - Exercises of edge cases of the feature -> - Tests that checks the feature works as expected (where applicable, `//@ run-pass`). -> - Are there any intentional gaps in test coverage? +> Contextualize and link to test folders and individual tests. + +*TODO* + +### Outstanding bugs + +> What outstanding bugs involve this feature? List them. Should any block the stabilization? Discuss why or why not. + +*TODO* + +- *TODO* +- *TODO* +- *TODO* + +### Outstanding FIXMEs + +> What FIXMEs are still in the code for that feature and why is it OK to leave them there? + +*TODO* + +### Tool changes + +> What changes must be made to our other tools to support this feature. Has this work been done? Link to any relevant PRs and issues. + +- [ ] rustfmt + - *TODO* +- [ ] rust-analyzer + - *TODO* +- [ ] rustdoc (both JSON and HTML) + - *TODO* +- [ ] cargo + - *TODO* +- [ ] clippy + - *TODO* +- [ ] rustup + - *TODO* +- [ ] docs.rs + - *TODO* + +*TODO* + +### Breaking changes + +> If this stabilization represents a known breaking change, link to the crater report, the analysis of the crater report, and to all PRs we've made to ecosystem projects affected by this breakage. Discuss any limitations of what we're able to know about or to fix. + +*TODO* + +Crater report: + +- *TODO* + +Crater analysis: + +- *TODO* + +PRs to affected crates: + +- *TODO* +- *TODO* +- *TODO* + +## Type system, opsem + +### Compile-time checks + +> What compilation-time checks are done that are needed to prevent undefined behavior? > -> Link to test folders or individual tests (ui/codegen/assembly/run-make tests, etc.). +> Link to tests demonstrating that these checks are being done. *TODO* -> ### What outstanding bugs in the issue tracker involve this feature? Are they stabilization-blocking? +- *TODO* +- *TODO* +- *TODO* + +### Type system rules + +> What type system rules are enforced for this feature and what is the purpose of each? *TODO* -> ### What FIXMEs are still in the code for that feature and why is it ok to leave them there? +### Sound by default? + +> Does the feature's implementation need specific checks to prevent UB, or is it sound by default and need specific opt-in to perform the dangerous/unsafe operations? If it is not sound by default, what is the rationale? *TODO* -> ### Summarize contributors to the feature by name for recognition and assuredness that people involved in the feature agree with stabilization +### Breaks the AM? + +> Can users use this feature to introduce undefined behavior, or use this feature to break the abstraction of Rust and expose the underlying assembly-level implementation? Describe this if so. *TODO* -> ### Which tools need to be adjusted to support this feature. Has this work been done? -> -> Consider rustdoc, clippy, rust-analyzer, rustfmt, rustup, docs.rs. +## Common interactions + +### Temporaries + +> Does this feature introduce new expressions that can produce temporaries? What are the scopes of those temporaries? *TODO* -> ## Type system and execution rules +### Drop order -> ### What compilation-time checks are done that are needed to prevent undefined behavior? -> -> (Be sure to link to tests demonstrating that these tests are being done.) +> Does this feature raise questions about the order in which we should drop values? Talk about the decisions made here and how they're consistent with our earlier decisions. *TODO* -> ### Does the feature's implementation need checks to prevent UB or is it sound by default and needs opt in in places to perform the dangerous/unsafe operations? If it is not sound by default, what is the rationale? +### Pre-expansion / post-expansion + +> Does this feature raise questions about what should be accepted pre-expansion (e.g. in code covered by `#[cfg(false)]`) versus what should be accepted post-expansion? What decisions were made about this? *TODO* -> ### Can users use this feature to introduce undefined behavior, or use this feature to break the abstraction of Rust and expose the underlying assembly-level implementation? (Describe.) +### Edition hygiene + +> If this feature is gated on an edition, how do we decide, in the context of the edition hygiene of tokens, whether to accept or reject code. E.g., what token do we use to decide? *TODO* -> ### What updates are needed to the reference/specification? (link to PRs when they exist) +### SemVer implications + +> Does this feature create any new ways in which library authors must take care to prevent breaking downstreams when making minor-version releases? Describe these. Are these new hazards "major" or "minor" according to [RFC 1105](https://rust-lang.github.io/rfcs/1105-api-evolution.html)? *TODO* -> ## Common interactions +### Exposing other features -> ### Does this feature introduce new expressions and can they produce temporaries? What are the lifetimes of those temporaries? +> Are there any other unstable features whose behavior may be exposed by this feature in any way? What features present the highest risk of that? *TODO* -> ### What other unstable features may be exposed by this feature? +## History + +> List issues and PRs that are important for understanding how we got here. + +- *TODO* +- *TODO* +- *TODO* + +## Acknowledgments + +> Summarize contributors to the feature by name for recognition and so that those people are notified about the stabilization. Does anyone who worked on this *not* think it should be stabilized right now? We'd like to hear about that if so. *TODO* + +## Open items + +> List any known items that have not yet been completed and that should be before this is stabilized. + +- [ ] *TODO* +- [ ] *TODO* +- [ ] *TODO* From 3a02592e21fba8667180ae7545d541925cf5171d Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 28 Jul 2025 04:18:33 +0000 Subject: [PATCH 417/447] Prepare for merging from rust-lang/rust This updates the rust-version file to 2b5e239c6b86cde974b0ef0f8e23754fb08ff3c5. --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index ce9f984e6..b631041b6 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -efd420c770bb179537c01063e98cb6990c439654 +2b5e239c6b86cde974b0ef0f8e23754fb08ff3c5 From 28b963695c2b0e995ca8616ded24a81343d73458 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 28 Jul 2025 08:57:48 +0200 Subject: [PATCH 418/447] fix pauses --- src/tests/ui.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index b1feef9ed..8f872b3aa 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -320,8 +320,8 @@ be preferred over //@ error-pattern, //@ error-pattern is imprecise and non-exha ### `error-pattern` -The `error-pattern` [directive](directives.md) can be used for runtime messages, which don't -have a specific span, or in exceptional cases, for compile time messages. +The `error-pattern` [directive](directives.md) can be used for runtime messages which don't +have a specific span, or, in exceptional cases, for compile time messages. Let's think about this test: From d4019da19be0bf7503fb05ad4d0e925cd26e358e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 28 Jul 2025 09:09:41 +0200 Subject: [PATCH 419/447] reword to avoid using a term used in a confusing manner, "error annotations" --- src/tests/ui.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tests/ui.md b/src/tests/ui.md index 8f872b3aa..782f78d76 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -309,8 +309,9 @@ fn main((ؼ Use `//~?` to match an error without line information. `//~?` is precise and will not match errors if their line information is available. -For tests wishing to match against compiler diagnostics, error annotations should -be preferred over //@ error-pattern, //@ error-pattern is imprecise and non-exhaustive. +It should be preferred over `//@ error-pattern` +for tests wishing to match against compiler diagnostics, +due to `//@ error-pattern` being imprecise and non-exhaustive. ```rust,ignore //@ compile-flags: --print yyyy From 15ec3c54747395a5fd25d3a8695499ca5beb0da4 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 17 Jul 2025 06:09:15 +0200 Subject: [PATCH 420/447] avoid the need to specify if toc should be generated - this removes one external dependency, mdbook-toc - this steals code from rustc book --- .github/workflows/ci.yml | 4 +- README.md | 6 +-- book.toml | 11 +++-- pagetoc.css | 84 +++++++++++++++++++++++++++++++ pagetoc.js | 104 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 198 insertions(+), 11 deletions(-) create mode 100644 pagetoc.css create mode 100644 pagetoc.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index daf5223cb..6eabb999f 100644 --- a/.github/workflows/ci.yml +++ b/.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/README.md b/README.md index 5932da467..1ad895aed 100644 --- a/README.md +++ b/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 `` 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/book.toml b/book.toml index b84b1e754..daf237ed9 100644 --- a/book.toml +++ b/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/pagetoc.css b/pagetoc.css new file mode 100644 index 000000000..fa709194f --- /dev/null +++ b/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/pagetoc.js b/pagetoc.js new file mode 100644 index 000000000..927a5b107 --- /dev/null +++ b/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()); +} From 6f0ae3e918b9d6bb09761e7d9f4119f387f14675 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 28 Jul 2025 11:45:21 +0200 Subject: [PATCH 421/447] remove the markers --- src/asm.md | 2 -- src/backend/backend-agnostic.md | 2 -- src/backend/implicit-caller-location.md | 2 -- src/backend/monomorph.md | 2 -- src/backend/updating-llvm.md | 2 -- src/borrow_check/moves_and_initialization/move_paths.md | 2 -- src/borrow_check/region_inference.md | 2 -- src/borrow_check/region_inference/constraint_propagation.md | 2 -- src/borrow_check/region_inference/lifetime_parameters.md | 2 -- src/borrow_check/region_inference/member_constraints.md | 2 -- src/borrow_check/region_inference/placeholders_and_universes.md | 2 -- src/bug-fix-procedure.md | 2 -- src/building/bootstrapping/what-bootstrapping-does.md | 2 -- src/building/how-to-build-and-run.md | 2 -- src/building/new-target.md | 2 -- src/building/optimized-build.md | 2 -- src/building/suggested.md | 2 -- src/compiler-debugging.md | 2 -- src/compiler-src.md | 2 -- src/const-eval/interpret.md | 2 -- src/contributing.md | 2 -- src/coroutine-closures.md | 2 -- src/debugging-support-in-rustc.md | 2 -- src/diagnostics.md | 2 -- src/early_late_parameters.md | 2 -- src/getting-started.md | 2 -- src/git.md | 2 -- src/guides/editions.md | 2 -- src/hir.md | 2 -- src/implementing_new_features.md | 2 -- src/llvm-coverage-instrumentation.md | 2 -- src/macro-expansion.md | 2 -- src/mir/construction.md | 2 -- src/mir/dataflow.md | 2 -- src/mir/drop-elaboration.md | 2 -- src/mir/index.md | 2 -- src/name-resolution.md | 2 -- src/normalization.md | 2 -- src/overview.md | 2 -- src/panic-implementation.md | 2 -- src/profile-guided-optimization.md | 2 -- src/queries/incremental-compilation-in-detail.md | 2 -- src/queries/incremental-compilation.md | 2 -- src/queries/query-evaluation-model-in-detail.md | 2 -- src/queries/salsa.md | 2 -- src/query.md | 2 -- src/rustdoc-internals.md | 2 -- src/rustdoc-internals/search.md | 2 -- src/rustdoc.md | 2 -- src/stability.md | 2 -- src/stabilization_guide.md | 2 -- src/test-implementation.md | 2 -- src/tests/adding.md | 2 -- src/tests/compiletest.md | 2 -- src/tests/directives.md | 2 -- src/tests/intro.md | 2 -- src/tests/running.md | 2 -- src/tests/ui.md | 2 -- src/thir.md | 2 -- src/tracing.md | 2 -- src/traits/goals-and-clauses.md | 2 -- src/traits/lowering-to-logic.md | 2 -- src/traits/resolution.md | 2 -- src/ty.md | 2 -- src/type-inference.md | 2 -- src/typing_parameter_envs.md | 2 -- src/variance.md | 2 -- src/walkthrough.md | 2 -- 68 files changed, 136 deletions(-) diff --git a/src/asm.md b/src/asm.md index 1bb493e73..b5857d546 100644 --- a/src/asm.md +++ b/src/asm.md @@ -1,7 +1,5 @@ # Inline assembly - - ## Overview Inline assembly in rustc mostly revolves around taking an `asm!` macro invocation and plumbing it diff --git a/src/backend/backend-agnostic.md b/src/backend/backend-agnostic.md index 0f81d3cb4..2fdda4eda 100644 --- a/src/backend/backend-agnostic.md +++ b/src/backend/backend-agnostic.md @@ -1,7 +1,5 @@ # Backend Agnostic Codegen - - [`rustc_codegen_ssa`] provides an abstract interface for all backends to implement, namely LLVM, [Cranelift], and [GCC]. diff --git a/src/backend/implicit-caller-location.md b/src/backend/implicit-caller-location.md index c5ee00813..9ca4bcab0 100644 --- a/src/backend/implicit-caller-location.md +++ b/src/backend/implicit-caller-location.md @@ -1,7 +1,5 @@ # 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 diff --git a/src/backend/monomorph.md b/src/backend/monomorph.md index 7ebb4d2b1..e9d98597e 100644 --- a/src/backend/monomorph.md +++ b/src/backend/monomorph.md @@ -1,7 +1,5 @@ # 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 diff --git a/src/backend/updating-llvm.md b/src/backend/updating-llvm.md index 18c822aad..ebef15d40 100644 --- a/src/backend/updating-llvm.md +++ b/src/backend/updating-llvm.md @@ -1,7 +1,5 @@ # Updating LLVM - - Rust supports building against multiple LLVM versions: diff --git a/src/borrow_check/moves_and_initialization/move_paths.md b/src/borrow_check/moves_and_initialization/move_paths.md index ad9c75d62..95518fbc0 100644 --- a/src/borrow_check/moves_and_initialization/move_paths.md +++ b/src/borrow_check/moves_and_initialization/move_paths.md @@ -1,7 +1,5 @@ # 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: diff --git a/src/borrow_check/region_inference.md b/src/borrow_check/region_inference.md index 85e71b4fa..0d55ab955 100644 --- a/src/borrow_check/region_inference.md +++ b/src/borrow_check/region_inference.md @@ -1,7 +1,5 @@ # 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 4c30d25e0..c3f8c03cb 100644 --- a/src/borrow_check/region_inference/constraint_propagation.md +++ b/src/borrow_check/region_inference/constraint_propagation.md @@ -1,7 +1,5 @@ # 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 fadfac404..2d337dbc0 100644 --- a/src/borrow_check/region_inference/lifetime_parameters.md +++ b/src/borrow_check/region_inference/lifetime_parameters.md @@ -1,7 +1,5 @@ # 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 fd7c87ffc..2804c9772 100644 --- a/src/borrow_check/region_inference/member_constraints.md +++ b/src/borrow_check/region_inference/member_constraints.md @@ -1,7 +1,5 @@ # 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 91c8c4526..11fd2a5fc 100644 --- a/src/borrow_check/region_inference/placeholders_and_universes.md +++ b/src/borrow_check/region_inference/placeholders_and_universes.md @@ -1,7 +1,5 @@ # 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 55436261f..6b13c9702 100644 --- a/src/bug-fix-procedure.md +++ b/src/bug-fix-procedure.md @@ -1,7 +1,5 @@ # Procedures for breaking changes - - This page defines the best practices procedure for making bug fixes or soundness corrections in the compiler that can cause existing code to stop compiling. This text is based on diff --git a/src/building/bootstrapping/what-bootstrapping-does.md b/src/building/bootstrapping/what-bootstrapping-does.md index 2793ad438..da425d8d3 100644 --- a/src/building/bootstrapping/what-bootstrapping-does.md +++ b/src/building/bootstrapping/what-bootstrapping-does.md @@ -1,7 +1,5 @@ # What Bootstrapping does - - [*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/building/how-to-build-and-run.md b/src/building/how-to-build-and-run.md index d29cd1448..b07d3533f 100644 --- a/src/building/how-to-build-and-run.md +++ b/src/building/how-to-build-and-run.md @@ -1,7 +1,5 @@ # How to build and run the compiler - -
For `profile = "library"` users, or users who use `download-rustc = true | "if-unchanged"`, please be advised that diff --git a/src/building/new-target.md b/src/building/new-target.md index e11a2cd8e..436aec8ee 100644 --- a/src/building/new-target.md +++ b/src/building/new-target.md @@ -6,8 +6,6 @@ relevant to your desired goal. See also the associated documentation in the [target tier policy]. - - [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/building/optimized-build.md b/src/building/optimized-build.md index 62dfaca89..863ed9749 100644 --- a/src/building/optimized-build.md +++ b/src/building/optimized-build.md @@ -1,7 +1,5 @@ # Optimized build of the compiler - - 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/building/suggested.md b/src/building/suggested.md index c046161e7..35c7e935b 100644 --- a/src/building/suggested.md +++ b/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. - - ## Installing a pre-push hook CI will automatically fail your build if it doesn't pass `tidy`, our internal diff --git a/src/compiler-debugging.md b/src/compiler-debugging.md index 102e20207..edd2aa6c5 100644 --- a/src/compiler-debugging.md +++ b/src/compiler-debugging.md @@ -1,7 +1,5 @@ # Debugging the compiler - - This chapter contains a few tips to debug the compiler. These tips aim to be useful no matter what you are working on. Some of the other chapters have advice about specific parts of the compiler (e.g. the [Queries Debugging and diff --git a/src/compiler-src.md b/src/compiler-src.md index 00aa96226..d67bacb1b 100644 --- a/src/compiler-src.md +++ b/src/compiler-src.md @@ -1,7 +1,5 @@ # High-level overview of the compiler source - - Now that we have [seen what the compiler does][orgch], let's take a look at the structure of the [`rust-lang/rust`] repository, where the rustc source code lives. diff --git a/src/const-eval/interpret.md b/src/const-eval/interpret.md index 51a539de5..08382b12f 100644 --- a/src/const-eval/interpret.md +++ b/src/const-eval/interpret.md @@ -1,7 +1,5 @@ # Interpreter - - 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/contributing.md b/src/contributing.md index b3fcd79ec..963bef3af 100644 --- a/src/contributing.md +++ b/src/contributing.md @@ -1,7 +1,5 @@ # Contribution procedures - - ## Bug reports While bugs are unfortunate, they're a reality in software. We can't fix what we diff --git a/src/coroutine-closures.md b/src/coroutine-closures.md index 48cdba44a..2617c824a 100644 --- a/src/coroutine-closures.md +++ b/src/coroutine-closures.md @@ -1,7 +1,5 @@ # Async closures/"coroutine-closures" - - 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/debugging-support-in-rustc.md b/src/debugging-support-in-rustc.md index ac629934e..bd4f795ce 100644 --- a/src/debugging-support-in-rustc.md +++ b/src/debugging-support-in-rustc.md @@ -1,7 +1,5 @@ # Debugging support in the Rust compiler - - This document explains the state of debugging tools support in the Rust compiler (rustc). It gives an overview of GDB, LLDB, WinDbg/CDB, as well as infrastructure around Rust compiler to debug Rust code. diff --git a/src/diagnostics.md b/src/diagnostics.md index 33f5441d3..82191e0a6 100644 --- a/src/diagnostics.md +++ b/src/diagnostics.md @@ -1,7 +1,5 @@ # 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/early_late_parameters.md b/src/early_late_parameters.md index 3f94b0905..c472bdc2c 100644 --- a/src/early_late_parameters.md +++ b/src/early_late_parameters.md @@ -1,8 +1,6 @@ # Early vs Late bound parameters - - > **NOTE**: This chapter largely talks about early/late bound as being solely relevant when discussing function item types/function definitions. This is potentially not completely true, async blocks and closures should likely be discussed somewhat in this chapter. ## What does it mean to be "early" bound or "late" bound diff --git a/src/getting-started.md b/src/getting-started.md index d6c5c3ac8..04d2e3773 100644 --- a/src/getting-started.md +++ b/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. - - 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/git.md b/src/git.md index 8726ddfce..447c6fd45 100644 --- a/src/git.md +++ b/src/git.md @@ -1,7 +1,5 @@ # 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/guides/editions.md b/src/guides/editions.md index 9a92d4ebc..b65fbb13c 100644 --- a/src/guides/editions.md +++ b/src/guides/editions.md @@ -1,7 +1,5 @@ # Editions - - 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/hir.md b/src/hir.md index 72fb10701..38ba33112 100644 --- a/src/hir.md +++ b/src/hir.md @@ -1,7 +1,5 @@ # 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 diff --git a/src/implementing_new_features.md b/src/implementing_new_features.md index 76cf2386c..00bce8599 100644 --- a/src/implementing_new_features.md +++ b/src/implementing_new_features.md @@ -1,7 +1,5 @@ # Implementing new language features - - When you want to implement a new significant feature in the compiler, you need to go through this process to make sure everything goes smoothly. **NOTE: This section is for *language* features, not *library* features, which use [a different process].** diff --git a/src/llvm-coverage-instrumentation.md b/src/llvm-coverage-instrumentation.md index 880363b94..288b90f33 100644 --- a/src/llvm-coverage-instrumentation.md +++ b/src/llvm-coverage-instrumentation.md @@ -1,7 +1,5 @@ # LLVM source-based code coverage - - `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/macro-expansion.md b/src/macro-expansion.md index a90f71700..54d6d2b4e 100644 --- a/src/macro-expansion.md +++ b/src/macro-expansion.md @@ -1,7 +1,5 @@ # Macro expansion - - 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/mir/construction.md b/src/mir/construction.md index f2559a22b..8360d9ff1 100644 --- a/src/mir/construction.md +++ b/src/mir/construction.md @@ -1,7 +1,5 @@ # 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 85e57dd83..970e61196 100644 --- a/src/mir/dataflow.md +++ b/src/mir/dataflow.md @@ -1,7 +1,5 @@ # 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/drop-elaboration.md b/src/mir/drop-elaboration.md index 3b321fd44..4da612c83 100644 --- a/src/mir/drop-elaboration.md +++ b/src/mir/drop-elaboration.md @@ -1,7 +1,5 @@ # Drop elaboration - - ## Dynamic drops According to the [reference][reference-drop]: diff --git a/src/mir/index.md b/src/mir/index.md index f355875aa..8ba5f3ac8 100644 --- a/src/mir/index.md +++ b/src/mir/index.md @@ -1,7 +1,5 @@ # 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 diff --git a/src/name-resolution.md b/src/name-resolution.md index 719ebce85..2e96382f7 100644 --- a/src/name-resolution.md +++ b/src/name-resolution.md @@ -1,7 +1,5 @@ # Name resolution - - 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/normalization.md b/src/normalization.md index eb0962a41..53e20f1c0 100644 --- a/src/normalization.md +++ b/src/normalization.md @@ -1,7 +1,5 @@ # Aliases and Normalization - - ## 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/overview.md b/src/overview.md index 8a1a22fad..12b76828b 100644 --- a/src/overview.md +++ b/src/overview.md @@ -1,7 +1,5 @@ # 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 468190ffc..dba3f2146 100644 --- a/src/panic-implementation.md +++ b/src/panic-implementation.md @@ -1,7 +1,5 @@ # Panicking in Rust - - ## 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/profile-guided-optimization.md b/src/profile-guided-optimization.md index 2fa810210..4e3dadd40 100644 --- a/src/profile-guided-optimization.md +++ b/src/profile-guided-optimization.md @@ -1,7 +1,5 @@ # 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 18e0e25c5..46e38832e 100644 --- a/src/queries/incremental-compilation-in-detail.md +++ b/src/queries/incremental-compilation-in-detail.md @@ -1,7 +1,5 @@ # 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 6e5b4e8cc..731ff3287 100644 --- a/src/queries/incremental-compilation.md +++ b/src/queries/incremental-compilation.md @@ -1,7 +1,5 @@ # 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/query-evaluation-model-in-detail.md b/src/queries/query-evaluation-model-in-detail.md index 444e20bc5..c1a4373f7 100644 --- a/src/queries/query-evaluation-model-in-detail.md +++ b/src/queries/query-evaluation-model-in-detail.md @@ -1,7 +1,5 @@ # 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/queries/salsa.md b/src/queries/salsa.md index 1a7b7fa9a..dc7160edc 100644 --- a/src/queries/salsa.md +++ b/src/queries/salsa.md @@ -1,7 +1,5 @@ # 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/query.md b/src/query.md index 0ca1b360a..8377a7b2f 100644 --- a/src/query.md +++ b/src/query.md @@ -1,7 +1,5 @@ # Queries: demand-driven compilation - - As described in [Overview of the compiler], the Rust compiler is still (as of July 2021) transitioning from a traditional "pass-based" setup to a "demand-driven" system. The compiler query diff --git a/src/rustdoc-internals.md b/src/rustdoc-internals.md index 0234d4a92..4affbafe4 100644 --- a/src/rustdoc-internals.md +++ b/src/rustdoc-internals.md @@ -1,7 +1,5 @@ # Rustdoc Internals - - This page describes [`rustdoc`]'s passes and modes. For an overview of `rustdoc`, see the ["Rustdoc overview" chapter](./rustdoc.md). diff --git a/src/rustdoc-internals/search.md b/src/rustdoc-internals/search.md index 350643111..beff0a94c 100644 --- a/src/rustdoc-internals/search.md +++ b/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. - - ## Search index format `search.js` calls this Raw, because it turns it into diff --git a/src/rustdoc.md b/src/rustdoc.md index 52ae48c37..9290fcd3b 100644 --- a/src/rustdoc.md +++ b/src/rustdoc.md @@ -9,8 +9,6 @@ For more details about how rustdoc works, see the [Rustdoc internals]: ./rustdoc-internals.md - - `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/stability.md b/src/stability.md index 230925252..d0cee54ad 100644 --- a/src/stability.md +++ b/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). - - ## unstable The `#[unstable(feature = "foo", issue = "1234", reason = "lorem ipsum")]` diff --git a/src/stabilization_guide.md b/src/stabilization_guide.md index f155272e5..e399930fc 100644 --- a/src/stabilization_guide.md +++ b/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: - - ## 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/test-implementation.md b/src/test-implementation.md index e906dd29f..f09d73631 100644 --- a/src/test-implementation.md +++ b/src/test-implementation.md @@ -1,7 +1,5 @@ # The `#[test]` attribute - - Many Rust programmers rely on a built-in attribute called `#[test]`. All diff --git a/src/tests/adding.md b/src/tests/adding.md index 895eabfbd..e5c26bef1 100644 --- a/src/tests/adding.md +++ b/src/tests/adding.md @@ -1,7 +1,5 @@ # 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 preventing us from repeating the diff --git a/src/tests/compiletest.md b/src/tests/compiletest.md index a108dfdef..4980ed845 100644 --- a/src/tests/compiletest.md +++ b/src/tests/compiletest.md @@ -1,7 +1,5 @@ # Compiletest - - ## Introduction `compiletest` is the main test harness of the Rust test suite. It allows test diff --git a/src/tests/directives.md b/src/tests/directives.md index 5c3ae359b..a16be9b48 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -1,7 +1,5 @@ # Compiletest directives - - diff --git a/src/tests/intro.md b/src/tests/intro.md index 79b96c450..b90c16d60 100644 --- a/src/tests/intro.md +++ b/src/tests/intro.md @@ -1,7 +1,5 @@ # Testing the compiler - - The Rust project runs a wide variety of different tests, orchestrated by the build system (`./x test`). This section gives a brief overview of the different testing tools. Subsequent chapters dive into [running tests](running.md) and diff --git a/src/tests/running.md b/src/tests/running.md index 6526fe9c2..f6e313062 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -1,7 +1,5 @@ # Running tests - - 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/tests/ui.md b/src/tests/ui.md index 782f78d76..c1e67e1b7 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -1,7 +1,5 @@ # UI tests - - UI tests are a particular [test suite](compiletest.md#test-suites) of compiletest. diff --git a/src/thir.md b/src/thir.md index 73d09ad80..3d3dafaef 100644 --- a/src/thir.md +++ b/src/thir.md @@ -1,7 +1,5 @@ # The THIR - - 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 January 2024) used for diff --git a/src/tracing.md b/src/tracing.md index 0cfdf306e..5e5b81fc6 100644 --- a/src/tracing.md +++ b/src/tracing.md @@ -1,7 +1,5 @@ # Using tracing to debug the compiler - - 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/traits/goals-and-clauses.md b/src/traits/goals-and-clauses.md index 40fd4581b..2884ca5a0 100644 --- a/src/traits/goals-and-clauses.md +++ b/src/traits/goals-and-clauses.md @@ -1,7 +1,5 @@ # 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) diff --git a/src/traits/lowering-to-logic.md b/src/traits/lowering-to-logic.md index 1248d4346..cc8b3bf80 100644 --- a/src/traits/lowering-to-logic.md +++ b/src/traits/lowering-to-logic.md @@ -1,7 +1,5 @@ # 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 c62b05936..ccb2b0426 100644 --- a/src/traits/resolution.md +++ b/src/traits/resolution.md @@ -1,7 +1,5 @@ # 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 767ac3fdb..4055f475e 100644 --- a/src/ty.md +++ b/src/ty.md @@ -1,7 +1,5 @@ # 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. diff --git a/src/type-inference.md b/src/type-inference.md index 888eb2439..2243205f1 100644 --- a/src/type-inference.md +++ b/src/type-inference.md @@ -1,7 +1,5 @@ # Type inference - - Type inference is the process of automatic detection of the type of an expression. diff --git a/src/typing_parameter_envs.md b/src/typing_parameter_envs.md index e21bc5155..db15467a4 100644 --- a/src/typing_parameter_envs.md +++ b/src/typing_parameter_envs.md @@ -1,7 +1,5 @@ # Typing/Parameter Environments - - ## 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/variance.md b/src/variance.md index ad4fa4adf..7aa014071 100644 --- a/src/variance.md +++ b/src/variance.md @@ -1,7 +1,5 @@ # 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 48b3f8bb1..b4c337934 100644 --- a/src/walkthrough.md +++ b/src/walkthrough.md @@ -1,7 +1,5 @@ # 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. From 80137fa23d58f7958815d8c26f9f94448b98b33e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 29 Jul 2025 09:35:50 +0200 Subject: [PATCH 422/447] WIP: auth using GitHub app --- .github/workflows/rustc-pull.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index ad570ee45..ea4d7532a 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -9,12 +9,13 @@ on: jobs: pull: if: github.repository == 'rust-lang/rustc-dev-guide' - uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main + uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@ci-gh-app 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 }} From cdcad1f6e58cebd16a42d1388b03c428257bcef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 29 Jul 2025 09:53:04 +0200 Subject: [PATCH 423/447] Remove `bot-pull-requests` triagebot config --- triagebot.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index b3f4c2d28..3ac5d57a5 100644 --- a/triagebot.toml +++ b/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 From 2479b79ec4d4dd13665f4b2fdc02746111bd8d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 29 Jul 2025 10:02:50 +0200 Subject: [PATCH 424/447] Use main branch of josh-sync for CI workflow --- .github/workflows/rustc-pull.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index ea4d7532a..04d6469ae 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -9,7 +9,7 @@ on: jobs: pull: if: github.repository == 'rust-lang/rustc-dev-guide' - uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@ci-gh-app + uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main with: github-app-id: ${{ vars.APP_CLIENT_ID }} zulip-stream-id: 196385 From 7954fa06df26bedd2e21ee0aa902807a6a148f14 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Wed, 16 Jul 2025 16:16:24 -0700 Subject: [PATCH 425/447] Verify llvm-needs-components are not empty and match the --target value --- src/tests/directives.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 5c3ae359b..89e4d3e9b 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -293,8 +293,6 @@ See [Pretty-printer](compiletest.md#pretty-printer-tests). - `no-auto-check-cfg` — disable auto check-cfg (only for `--check-cfg` tests) - [`revisions`](compiletest.md#revisions) — compile multiple times -- [`unused-revision-names`](compiletest.md#ignoring-unused-revision-names) - - suppress tidy checks for mentioning unknown revision names -[`forbid-output`](compiletest.md#incremental-tests) — incremental cfail rejects output pattern - [`should-ice`](compiletest.md#incremental-tests) — incremental cfail should @@ -315,6 +313,17 @@ test suites that use those tools: - `llvm-cov-flags` adds extra flags when running LLVM's `llvm-cov` tool. - Used by [coverage tests](compiletest.md#coverage-tests) in `coverage-run` mode. +### Tidy specific directives + +The following directives control how the [tidy script](../conventions.md#formatting) +verifies tests. + +- `ignore-tidy-target-specific-tests` disables checking that the appropriate + LLVM component is required (via a `needs-llvm-components` directive) when a + test is compiled for a specific target (via the `--target` flag in a + `compile-flag` directive). +- [`unused-revision-names`](compiletest.md#ignoring-unused-revision-names) - + suppress tidy checks for mentioning unknown revision names. ## Substitutions From c7693b6928bbc266b9750235505a22364a92a832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 30 Jul 2025 08:11:01 +0200 Subject: [PATCH 426/447] Remove outdated ci.py reference --- src/tests/docker.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/tests/docker.md b/src/tests/docker.md index 032da1ca1..ae0939842 100644 --- a/src/tests/docker.md +++ b/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 +cargo run --manifest-path src/ci/citool/Cargo.toml run-local # 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 /bin/bash` where `` 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 -# 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 From 8c9fc690d5208434bd3580990a8087742c14bac2 Mon Sep 17 00:00:00 2001 From: tiif Date: Wed, 30 Jul 2025 09:30:10 +0000 Subject: [PATCH 427/447] Add documentation for unstable_feature_bound --- src/stability.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/stability.md b/src/stability.md index 230925252..7a5efdb8a 100644 --- a/src/stability.md +++ b/src/stability.md @@ -183,4 +183,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 From 99e2be5d19978b1f9c82596e3b87b76ea6b6a5ab Mon Sep 17 00:00:00 2001 From: tiif Date: Wed, 30 Jul 2025 11:54:32 +0200 Subject: [PATCH 428/447] Remove space Co-authored-by: Tshepang Mbambo --- src/stability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stability.md b/src/stability.md index 7a5efdb8a..e8589b7f4 100644 --- a/src/stability.md +++ b/src/stability.md @@ -184,6 +184,6 @@ 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]`. +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 From 58168811566beb66a3cb0052d8c57dffe58e2cde Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 31 Jul 2025 04:16:57 +0000 Subject: [PATCH 429/447] Prepare for merging from rust-lang/rust This updates the rust-version file to 32e7a4b92b109c24e9822c862a7c74436b50e564. --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index b631041b6..1ced6098a 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -2b5e239c6b86cde974b0ef0f8e23754fb08ff3c5 +32e7a4b92b109c24e9822c862a7c74436b50e564 From 87f6864b8ccd7d695f65b3c5bdf28f065ecbe4d0 Mon Sep 17 00:00:00 2001 From: lolbinarycat Date: Thu, 31 Jul 2025 13:33:51 -0500 Subject: [PATCH 430/447] improve linking in the "Auxilirary builds" section of directive index --- src/tests/directives.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tests/directives.md b/src/tests/directives.md index 5c3ae359b..8ea76cd8d 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -52,6 +52,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 +63,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 From 4b118c0aa7193a8ed3ca31a842887806c456afd8 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 1 Aug 2025 15:17:36 +0200 Subject: [PATCH 431/447] rarw --- src/SUMMARY.md | 1 + src/solve/candidate-preference.md | 426 ++++++++++++++++++++++++++++++ 2 files changed, 427 insertions(+) create mode 100644 src/solve/candidate-preference.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 7f2f32c62..f984f1196 100644 --- a/src/SUMMARY.md +++ b/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/solve/candidate-preference.md b/src/solve/candidate-preference.md new file mode 100644 index 000000000..af066415a --- /dev/null +++ b/src/solve/candidate-preference.md @@ -0,0 +1,426 @@ +# 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: Sized {} +impl<'a> Trait for &'a str {} +impl<'a> Trait for &'a str {} +fn is_sized(_: T) {} +fn foo<'a, 'b, T>(x: &'b str) +where + &'a str: Trait, +{ + // Elaborating the `&'a str: Trait` 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() {} +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 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 { + type TraitAssoc; +} + +impl Trait for T +where + T: Super, +{ + type TraitAssoc = U; +} + +fn overflow() { + // We can use the elaborated `Super` where-bound + // to prove the where-bound of the `T: Trait` implementation. This currently results in + // overflow. + let x: ::TraitAssoc; +} +``` + +This preference causes a lot of issues. See https://github.com/rust-lang/rust/issues/24066. Most of the +issues are caused by prefering where-bounds over impls even if the where-bound guides type inference: +```rust +trait Trait { + fn call_me(&self, x: T) {} +} +impl Trait for T {} +impl Trait for T {} +fn bug, 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>, + >::Assoc: Bound<'a>, +{ + // Using the where-bound for `>::Assoc: Bound<'a>` + // unnecessarily equates `>::Assoc` with the + // `>::Assoc` from the env. + impls_bound::<'a, >::Assoc>(); + // For a `>::Assoc: Bound<'b>` the self type of the + // where-bound matches, but the arguments of the trait bound don't. + impls_bound::<'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) +where + Vec: Into + Into, +{ + let _: f32 = Vec.into(); + // Without the global `Vec: Into` bound we'd + // eagerly use the non-global `Vec: Into` bound + // here, causing this to fail. +} + +struct Vec; +impl From 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; + fn d_tag(&self) -> Self::Word; + fn tag32(&self) -> Option { + self.d_tag().into().try_into().ok() + // prove `Self::Word: Into` and then select a method + // on `?0`, needs eager inference. + } +} +``` +```rust +fn impl_trait() -> impl Into { + 0u16 +} + +fn main() { + // There are two possible types for `x`: + // - `u32` by using the "alias bound" of `impl Into` + // - `impl Into`, i.e. `u16`, by using `impl From 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 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; +} +trait Trait: Super {} + +// Elaborating the environment results in a `T::Assoc: Super` where-bound. +// This where-bound must not prevent normalization via the `Super` +// item bound. +fn heck>(x: ::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>>(x: >::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` +// where-bound over the `I::Intoiterator: Iterator` +// alias-bound. + +trait Iterator { + type Item; +} + +trait IntoIterator { + type Item; + type IntoIter: Iterator; +} + +fn normalize>() {} + +fn foo() +where + I: IntoIterator, + I::IntoIter: Iterator, +{ + // We need to prefer the `I::IntoIterator: Iterator` + // where-bound over the `I::Intoiterator: Iterator` + // alias-bound. + normalize::(); +} +``` + +### 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` because of + // the impl below, which requires that `Self::Bar<()>: Eq` + // which is true, because we assume `for Self::Bar = i32`. + type Bar: Baz = i32; +} +trait Baz {} +impl Baz for i32 where T::Bar<()>: Eq {} +trait Eq {} +impl Eq 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 Id for T { + type This = T; +} + +fn foo(x: T) -> ::This +where + u32: Id, +{ + 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() {} +fn normalize>() {} + +fn foo<'a>() +where + &'static u32: Trait, +{ + 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 +[#133044]: https://github.com/rust-lang/rust/issues/133044 \ No newline at end of file From 2e920e87896e4994202c42038013109d00f61186 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 1 Aug 2025 15:49:36 +0200 Subject: [PATCH 432/447] rarw --- src/solve/candidate-preference.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/solve/candidate-preference.md b/src/solve/candidate-preference.md index af066415a..896052947 100644 --- a/src/solve/candidate-preference.md +++ b/src/solve/candidate-preference.md @@ -94,7 +94,7 @@ fn overflow() { } ``` -This preference causes a lot of issues. See https://github.com/rust-lang/rust/issues/24066. Most of the +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 { @@ -423,4 +423,5 @@ where [`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 From 80f5a3e1c8e271c2364260daef6be327b816d7c3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 31 Jul 2025 14:56:49 +0000 Subject: [PATCH 433/447] Remove the omit_gdb_pretty_printer_section attribute Disabling loading of pretty printers in the debugger itself is more reliable. Before this commit the .gdb_debug_scripts section couldn't be included in dylibs or rlibs as otherwise there is no way to disable the section anymore without recompiling the entire standard library. --- src/tests/directives.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/directives.md b/src/tests/directives.md index 89e4d3e9b..089757772 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -298,6 +298,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 From 24c403d6ece622e5c649ac02f84449cfaf1a4717 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Sat, 2 Aug 2025 19:01:07 +0500 Subject: [PATCH 434/447] update doc --- src/appendix/humorust.md | 2 +- src/tests/directives.md | 2 +- src/tests/ui.md | 8 +++----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/appendix/humorust.md b/src/appendix/humorust.md index 6df3b212a..8681512ed 100644 --- a/src/appendix/humorust.md +++ b/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/tests/directives.md b/src/tests/directives.md index 6fff021b0..bda95e4df 100644 --- a/src/tests/directives.md +++ b/src/tests/directives.md @@ -359,7 +359,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/tests/ui.md b/src/tests/ui.md index 782f78d76..eecd72695 100644 --- a/src/tests/ui.md +++ b/src/tests/ui.md @@ -25,9 +25,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 +46,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` From d6ade5d7f7569c9e5e8a357499e7ebf5ef1e58c3 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sun, 3 Aug 2025 07:18:26 +0200 Subject: [PATCH 435/447] there is still no official policy --- src/crates-io.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crates-io.md b/src/crates-io.md index 4431585a2..677b1fc03 100644 --- a/src/crates-io.md +++ b/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. - + 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. From 344231eba4e2df658306e49bb6ab459387ff962e Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 4 Aug 2025 04:24:59 +0000 Subject: [PATCH 436/447] Prepare for merging from rust-lang/rust This updates the rust-version file to 383b9c447b61641e1f1a3850253944a897a60827. --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 1ced6098a..e9f1626f1 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -32e7a4b92b109c24e9822c862a7c74436b50e564 +383b9c447b61641e1f1a3850253944a897a60827 From f88f95619df4d936329489c86e8a557179006f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 1 Aug 2025 14:58:06 +0200 Subject: [PATCH 437/447] Implement debugging output of the bootstrap Step graph into a DOT file --- src/building/bootstrapping/debugging-bootstrap.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/building/bootstrapping/debugging-bootstrap.md b/src/building/bootstrapping/debugging-bootstrap.md index c9c0d64a6..9c5ebbd36 100644 --- a/src/building/bootstrapping/debugging-bootstrap.md +++ b/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: From 7b1cf974b4619197adda870c7284e984ef2c2aed Mon Sep 17 00:00:00 2001 From: Robert Serrano Kobylyansky Date: Mon, 4 Aug 2025 13:08:29 +0100 Subject: [PATCH 438/447] Update installation.md The `--enable-offload` and `--enable--enzyme` arguments don't seem to work. Changing them to `--enable-llvm-offload` and `--enable-llvm-enzyme` resulted in the `boostrap.toml` file generating succesfully. --- src/offload/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/offload/installation.md b/src/offload/installation.md index 1e792de3c..b376e962f 100644 --- a/src/offload/installation.md +++ b/src/offload/installation.md @@ -8,7 +8,7 @@ First you need to clone and configure the Rust repository: ```bash git clone git@github.com:rust-lang/rust cd rust -./configure --enable-llvm-link-shared --release-channel=nightly --enable-llvm-assertions --enable-offload --enable-enzyme --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs +./configure --enable-llvm-link-shared --release-channel=nightly --enable-llvm-assertions --enable-llvm-offload --enable-llvm-enzyme --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs ``` Afterwards you can build rustc using: From f1e8e2bf226a0947772dcf4af7eef8396b92504a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 6 Aug 2025 13:57:12 +0200 Subject: [PATCH 439/447] add note on how to build wasi --- src/tests/running.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/tests/running.md b/src/tests/running.md index f6e313062..317b65f98 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -342,7 +342,6 @@ coordinate running tests (see [src/bootstrap/src/core/build_steps/test.rs]). > **TODO** > > - Is there any support for using an iOS emulator? -> - It's also unclear to me how the wasm or asm.js tests are run. [armhf-gnu]: https://github.com/rust-lang/rust/tree/master/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile [QEMU]: https://www.qemu.org/ @@ -350,6 +349,28 @@ coordinate running tests (see [src/bootstrap/src/core/build_steps/test.rs]). [remote-test-server]: https://github.com/rust-lang/rust/tree/master/src/tools/remote-test-server [src/bootstrap/src/core/build_steps/test.rs]: https://github.com/rust-lang/rust/blob/master/src/bootstrap/src/core/build_steps/test.rs +## Testing tests on wasi (wasm32-wasip1) + +Some tests are specific to wasm targets. +To run theste tests, you have to pass `--target wasm32-wasip1` to `x test`. +Additionally, you need the wasi sdk. +Follow the install instructions from the [wasi sdk repository] to get a sysroot on your computer. +On the [wasm32-wasip1 target support page] a minimum version is specified that your sdk must be able to build. +Some cmake commands that take a while and give a lot of very concerning c++ warnings... +Then, in `bootstrap.toml`, point to the sysroot like so: + +``` +[target.wasm32-wasip1] +wasi-root = "/build/sysroot/install/share/wasi-sysroot" +``` + +In my case I git-cloned it next to my rust folder, so it was `../wasi-sdk/build/....` +Now, tests should just run, you don't have to set up anything else. + +[wasi sdk repository]: https://github.com/WebAssembly/wasi-sdk +[wasm32-wasip1 target support page]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support/wasm32-wasip1.md#building-the-target. + + ## Running rustc_codegen_gcc tests First thing to know is that it only supports linux x86_64 at the moment. We will From a470ee39c30ec67bc0bc1dd9b3e1973165b0d378 Mon Sep 17 00:00:00 2001 From: lolbinarycat Date: Wed, 6 Aug 2025 13:31:52 -0500 Subject: [PATCH 440/447] =?UTF-8?q?Link=20from=20"Overview=20of=20the=20co?= =?UTF-8?q?mpiler=20=C2=A7=20Queries"=20to=20the=20Queries=20chapter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's already a link in the other direction, so this seems fairly logical. --- src/overview.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/overview.md b/src/overview.md index 12b76828b..02ba67613 100644 --- a/src/overview.md +++ b/src/overview.md @@ -321,6 +321,10 @@ the name `'tcx`, which means that something is tied to the lifetime of the [`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html +For more information about queries in the compiler, see [the queries chapter][queries]. + +[queries]: https://rustc-dev-guide.rust-lang.org/query.html + ### `ty::Ty` Types are really important in Rust, and they form the core of a lot of compiler From 8fd69840a073db5928ce5c07da3dca4ebfac36bd Mon Sep 17 00:00:00 2001 From: lolbinarycat Date: Wed, 6 Aug 2025 15:01:41 -0500 Subject: [PATCH 441/447] Make link relative an link to md not html --- src/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overview.md b/src/overview.md index 02ba67613..378d8c445 100644 --- a/src/overview.md +++ b/src/overview.md @@ -323,7 +323,7 @@ the name `'tcx`, which means that something is tied to the lifetime of the For more information about queries in the compiler, see [the queries chapter][queries]. -[queries]: https://rustc-dev-guide.rust-lang.org/query.html +[queries]: ./query.md ### `ty::Ty` From 431bb2aa566300e6ce4ffa88b3b3c28a5efee3c9 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 7 Aug 2025 04:18:12 +0000 Subject: [PATCH 442/447] Prepare for merging from rust-lang/rust This updates the rust-version file to 6bcdcc73bd11568fd85f5a38b58e1eda054ad1cd. --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index e9f1626f1..6ec700b9b 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -383b9c447b61641e1f1a3850253944a897a60827 +6bcdcc73bd11568fd85f5a38b58e1eda054ad1cd From 68121856c69b43fd7480fb3e450c884772d7ef63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 7 Aug 2025 10:41:43 +0200 Subject: [PATCH 443/447] Only run the pull workflow once per week --- .github/workflows/rustc-pull.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rustc-pull.yml b/.github/workflows/rustc-pull.yml index 04d6469ae..5ff311896 100644 --- a/.github/workflows/rustc-pull.yml +++ b/.github/workflows/rustc-pull.yml @@ -3,8 +3,8 @@ name: rustc-pull on: workflow_dispatch: schedule: - # Run at 04:00 UTC every Monday and Thursday - - cron: '0 4 * * 1,4' + # Run at 04:00 UTC every Monday + - cron: '0 4 * * 1' jobs: pull: From cf406ba8129b56cf53773921f47981caaeb29f88 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Fri, 8 Aug 2025 15:58:53 -0700 Subject: [PATCH 444/447] Remove mentions of Discord. The official Discord server is no longer active (cannot be posted to). --- src/about-this-guide.md | 1 - src/diagnostics/error-codes.md | 2 +- src/getting-started.md | 17 +++++++---------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/about-this-guide.md b/src/about-this-guide.md index 057e4a4cc..f39577249 100644 --- a/src/about-this-guide.md +++ b/src/about-this-guide.md @@ -74,7 +74,6 @@ You might also find the following sites useful: of the team procedures, active working groups, and the team calendar. - [std-dev-guide] -- a similar guide for developing the standard library. - [The t-compiler zulip][z] -- `#contribute` and `#wg-rustup` on [Discord](https://discord.gg/rust-lang). - The [Rust Internals forum][rif], a place to ask questions and discuss Rust's internals - The [Rust reference][rr], even though it doesn't specifically talk about diff --git a/src/diagnostics/error-codes.md b/src/diagnostics/error-codes.md index 1b6b87e4c..1693432b9 100644 --- a/src/diagnostics/error-codes.md +++ b/src/diagnostics/error-codes.md @@ -20,7 +20,7 @@ explanations should help users understand why their code cannot be accepted by the compiler. Rust prides itself on helpful error messages and long-form explanations are no exception. However, before error explanations are overhauled[^new-explanations] it is a bit open as to how exactly they should be -written, as always: ask your reviewer or ask around on the Rust Discord or Zulip. +written, as always: ask your reviewer or ask around on the Rust Zulip. [^new-explanations]: See the draft RFC [here][new-explanations-rfc]. diff --git a/src/getting-started.md b/src/getting-started.md index 04d2e3773..a4272a401 100644 --- a/src/getting-started.md +++ b/src/getting-started.md @@ -11,7 +11,6 @@ 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). [internals]: https://internals.rust-lang.org -[rust-discord]: http://discord.gg/rust-lang [rust-zulip]: https://rust-lang.zulipchat.com [coc]: https://www.rust-lang.org/policies/code-of-conduct [walkthrough]: ./walkthrough.md @@ -20,8 +19,7 @@ chapter on how to build and run the compiler](./building/how-to-build-and-run.md ## Asking Questions If you have questions, please make a post on the [Rust Zulip server][rust-zulip] or -[internals.rust-lang.org][internals]. If you are contributing to Rustup, be aware they are not on -Zulip - you can ask questions in `#wg-rustup` [on Discord][rust-discord]. +[internals.rust-lang.org][internals]. See the [list of teams and working groups][governance] and [the Community page][community] on the official website for more resources. @@ -30,10 +28,12 @@ official website for more resources. As a reminder, all contributors are expected to follow our [Code of Conduct][coc]. -The compiler team (or `t-compiler`) usually hangs out in Zulip [in this -"stream"][z]; it will be easiest to get questions answered there. +The compiler team (or `t-compiler`) usually hangs out in Zulip in +[the #t-compiler channel][z-t-compiler]; +questions about how the compiler works can go in [#t-compiler/help][z-help]. -[z]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler +[z-t-compiler]: https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler +[z-help]: https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp **Please ask questions!** A lot of people report feeling that they are "wasting expert time", but nobody on `t-compiler` feels this way. Contributors are @@ -162,15 +162,12 @@ incredibly helpful: - [Triaging issues][triage]: categorizing, replicating, and minimizing issues is very helpful to the Rust maintainers. - [Working groups][wg]: there are a bunch of working groups on a wide variety of rust-related things. -- Answer questions in the _Get Help!_ channels on the [Rust Discord - server][rust-discord], on [users.rust-lang.org][users], or on - [StackOverflow][so]. +- Answer questions on [users.rust-lang.org][users], or on [Stack Overflow][so]. - Participate in the [RFC process](https://github.com/rust-lang/rfcs). - Find a [requested community library][community-library], build it, and publish it to [Crates.io](http://crates.io). Easier said than done, but very, very valuable! -[rust-discord]: https://discord.gg/rust-lang [users]: https://users.rust-lang.org/ [so]: http://stackoverflow.com/questions/tagged/rust [community-library]: https://github.com/rust-lang/rfcs/labels/A-community-library From da730fd38f1fc5e67f522a0b729c9c5484e2e828 Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 11 Aug 2025 10:41:00 +0800 Subject: [PATCH 445/447] add a tip for english writing --- src/getting-started.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/getting-started.md b/src/getting-started.md index a4272a401..87e26d379 100644 --- a/src/getting-started.md +++ b/src/getting-started.md @@ -36,13 +36,15 @@ questions about how the compiler works can go in [#t-compiler/help][z-help]. [z-help]: https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp **Please ask questions!** A lot of people report feeling that they are "wasting -expert time", but nobody on `t-compiler` feels this way. Contributors are +expert's time", but nobody on `t-compiler` feels this way. Contributors are important to us. Also, if you feel comfortable, prefer public topics, as this means others can see the questions and answers, and perhaps even integrate them back into this guide :) +**Tip**: If you're not a native English speaker and feel unsure about writing, try using a translator to help. But avoid using LLM tools that generate long, complex words. In daily teamwork, **simple and clear words** are best for easy understanding. Even small typos or grammar mistakes can make you seem more human, and people connect better with humans. + ### Experts Not all `t-compiler` members are experts on all parts of `rustc`; it's a From 4e8a9c516125edd7a5c0b6055a364eb9d418e4f9 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 11 Aug 2025 09:15:33 +0200 Subject: [PATCH 446/447] place link on the more suitable text Also, remove redundant word --- src/git.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/git.md b/src/git.md index 447c6fd45..687830a72 100644 --- a/src/git.md +++ b/src/git.md @@ -338,7 +338,7 @@ your fork with `git push --force-with-lease`. ### Keeping things up to date -The above section on [Rebasing](#rebasing) is a specific +The [above section](#rebasing) is a specific guide on rebasing work and dealing with merge conflicts. Here is some general advice about how to keep your local repo up-to-date with upstream changes: From 93d2469d4eb5128af05eba9e70a1282193cf2902 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 11 Aug 2025 09:20:01 +0200 Subject: [PATCH 447/447] fix grammar --- src/git.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/git.md b/src/git.md index 687830a72..8f0511a45 100644 --- a/src/git.md +++ b/src/git.md @@ -344,7 +344,7 @@ Here is some general advice about how to keep your local repo up-to-date with upstream changes: Using `git pull upstream master` while on your local master branch regularly -will keep it up-to-date. You will also want to rebase your feature branches +will keep it up-to-date. You will also want to keep your feature branches up-to-date as well. After pulling, you can checkout the feature branches and rebase them:

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𝔴D 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