From 00cb12a5210c631213889f5196de572db05bf3f7 Mon Sep 17 00:00:00 2001 From: chiichen Date: Thu, 30 Jan 2025 17:38:46 +0800 Subject: [PATCH 01/36] chore: discard padding white space --- src/doc/rustc-dev-guide/src/building/suggested.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index bf5ffbc00afda..f498875ce1b7a 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/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 fd911ea65a50c838f4334ef353c80ec46358c9e6 Mon Sep 17 00:00:00 2001 From: chiichen Date: Thu, 30 Jan 2025 17:56:31 +0800 Subject: [PATCH 02/36] feat: modify developing with nix section --- .../rustc-dev-guide/src/building/suggested.md | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index f498875ce1b7a..2c6c3fe1df84b 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/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 7306e2b10ff46c7d013e4698ff6b4541fd4bb8a0 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 03/36] Distinguish between "nothing to pull" and "pull error" in josh-sync --- src/doc/rustc-dev-guide/josh-sync/src/main.rs | 15 ++++++++++-- src/doc/rustc-dev-guide/josh-sync/src/sync.rs | 24 +++++++++++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc-dev-guide/josh-sync/src/main.rs b/src/doc/rustc-dev-guide/josh-sync/src/main.rs index 84613ad86890e..175f016f73907 100644 --- a/src/doc/rustc-dev-guide/josh-sync/src/main.rs +++ b/src/doc/rustc-dev-guide/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/src/doc/rustc-dev-guide/josh-sync/src/sync.rs b/src/doc/rustc-dev-guide/josh-sync/src/sync.rs index eff80b1091d3b..cd64be6367032 100644 --- a/src/doc/rustc-dev-guide/josh-sync/src/sync.rs +++ b/src/doc/rustc-dev-guide/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 a7d35e12e2cf9813641cf5547f386cf5d7de4140 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 04/36] Rewrite section on executing Docker tests --- src/doc/rustc-dev-guide/src/tests/docker.md | 65 ++++++++++----------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/docker.md b/src/doc/rustc-dev-guide/src/tests/docker.md index a0aa8bd3e77b6..8327e5ce67c9d 100644 --- a/src/doc/rustc-dev-guide/src/tests/docker.md +++ b/src/doc/rustc-dev-guide/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 40713cb4515404e26c13b16270942acfef4ccf28 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 05/36] 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/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml index 615927d55e597..5d5b145c9434c 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml +++ b/src/doc/rustc-dev-guide/.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 179a2f8a5389dc910602c352d4b98f2dd96d8ca7 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 06/36] Pass `GITHUB_TOKEN` to Zulip CI step --- src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml index 5d5b145c9434c..2a9f56fd6504e 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml +++ b/src/doc/rustc-dev-guide/.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 97edb7a7c2f93451b2b6efa18b630117cce17847 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 07/36] Checkout repository sources in rustc-pull CI action This is needed for the `gh` command to work. --- src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml index 2a9f56fd6504e..5bfcf47d70345 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml +++ b/src/doc/rustc-dev-guide/.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 48c7202b021c2bf759439a18b85a41e7ab4b4a24 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 08/36] Reword submodule handling --- src/doc/rustc-dev-guide/src/tests/docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/docker.md b/src/doc/rustc-dev-guide/src/tests/docker.md index 8327e5ce67c9d..2ca08d42130a5 100644 --- a/src/doc/rustc-dev-guide/src/tests/docker.md +++ b/src/doc/rustc-dev-guide/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 f09de673565b88dd0c9f416e171f5c099073270e 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 09/36] Preparing for merge from rustc --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 183d26b293842..fa65931bdc527 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -66d6064f9eb888018775e08f84747ee6f39ba28e +8239a37f9c0951a037cfc51763ea52a20e71e6bd From 3827ff028971a6ec6ef18fd80f44c1cc05c898bb Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 2 Feb 2025 17:30:30 +0900 Subject: [PATCH 10/36] Apply suggestions from code review --- src/doc/rustc-dev-guide/src/traits/implied-bounds.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/traits/implied-bounds.md b/src/doc/rustc-dev-guide/src/traits/implied-bounds.md index 05693dcd5a18b..cdcb90d3e2edf 100644 --- a/src/doc/rustc-dev-guide/src/traits/implied-bounds.md +++ b/src/doc/rustc-dev-guide/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 d47b46df6aef42fc714a993db376e0a64236f52d 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 11/36] Preparing for merge from rustc --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index fa65931bdc527..b629597207648 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -8239a37f9c0951a037cfc51763ea52a20e71e6bd +613bdd49978298648ed05ace086bd1ecad54b44a From 56a5b59db217833ccb0ca9d52416512f3b0f65f0 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 12/36] Remove "Port run-make tests from Make to Rust" tracking issue from Recurring work --- src/doc/rustc-dev-guide/src/getting-started.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index 4cb1d0b31ebd2..8bf14bef2a033 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/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 99d2b3a996b8852122a07a9a06c416ec7a0f0b90 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 3 Feb 2025 22:07:10 +0200 Subject: [PATCH 13/36] overlong line --- src/doc/rustc-dev-guide/src/diagnostics.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md index 8f389640d271f..972309b5cd343 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics.md +++ b/src/doc/rustc-dev-guide/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 3e5b413dc47c75dd36cac61d6d028feddc413f6f 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 14/36] Make the rustc-pull workflow run less often --- src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml index 5bfcf47d70345..dc5395a19dd03 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml +++ b/src/doc/rustc-dev-guide/.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 299b78e2e3fa43ac283af429e062e58d946c0c7d Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 6 Feb 2025 09:12:42 +0100 Subject: [PATCH 15/36] Replace link with a https based one --- src/doc/rustc-dev-guide/src/appendix/bibliography.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/appendix/bibliography.md b/src/doc/rustc-dev-guide/src/appendix/bibliography.md index 8f6810cbcaeac..93426b645a61e 100644 --- a/src/doc/rustc-dev-guide/src/appendix/bibliography.md +++ b/src/doc/rustc-dev-guide/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 941e82a4b82918723372d7e575382dc0fe40c51a 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 16/36] improve CI cache docs --- src/doc/rustc-dev-guide/src/tests/ci.md | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index 9dde407895e24..a4b22392f1976 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/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 11f64f1eb45d5e7005dc880441758d0b9162fb8f Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 6 Feb 2025 08:29:10 -0700 Subject: [PATCH 17/36] Update links to type schemas What used to be in externs.js is now in rustdoc.d.ts. --- src/doc/rustc-dev-guide/src/rustdoc-internals/search.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md index ddf8ec405f81d..3506431118baf 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md +++ b/src/doc/rustc-dev-guide/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 515bd9f70f089c527e49fea0aced74debf98f771 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 7 Feb 2025 09:03:22 +0100 Subject: [PATCH 18/36] Remove reference to enum.Reveal --- src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md | 3 +-- src/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md b/src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md index 391e562910fa7..f6cff2d6c63cc 100644 --- a/src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md +++ b/src/doc/rustc-dev-guide/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/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md b/src/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md index ca09518d99f4b..5c2f4d594052e 100644 --- a/src/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md +++ b/src/doc/rustc-dev-guide/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 ea54b5e2444cc1da08e2c4dfa720115cd1edb4a8 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 7 Feb 2025 10:34:23 -0700 Subject: [PATCH 19/36] Replace i686-unknown-redox target with i586-unknown-redox --- compiler/rustc_target/src/spec/mod.rs | 2 +- .../{i686_unknown_redox.rs => i586_unknown_redox.rs} | 4 ++-- src/doc/rustc/src/platform-support.md | 2 +- src/doc/rustc/src/platform-support/redox.md | 4 ++-- src/tools/build-manifest/src/main.rs | 2 +- tests/assembly/targets/targets-elf.rs | 6 +++--- 6 files changed, 10 insertions(+), 10 deletions(-) rename compiler/rustc_target/src/spec/targets/{i686_unknown_redox.rs => i586_unknown_redox.rs} (90%) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index e95c4dbd2cffd..7455813c48a5b 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1797,7 +1797,7 @@ supported_targets! { ("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc), ("aarch64-unknown-redox", aarch64_unknown_redox), - ("i686-unknown-redox", i686_unknown_redox), + ("i586-unknown-redox", i586_unknown_redox), ("x86_64-unknown-redox", x86_64_unknown_redox), ("i386-apple-ios", i386_apple_ios), diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs similarity index 90% rename from compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs rename to compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs index bfe52a330d30d..67dfc42103b6f 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs @@ -2,7 +2,7 @@ use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base}; pub(crate) fn target() -> Target { let mut base = base::redox::opts(); - base.cpu = "pentiumpro".into(); + base.cpu = "pentium".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { base.stack_probes = StackProbeType::Call; Target { - llvm_target: "i686-unknown-redox".into(), + llvm_target: "i586-unknown-redox".into(), metadata: crate::spec::TargetMetadata { description: None, tier: None, diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 3b6abdd84832c..d9c0e6a132701 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -310,12 +310,12 @@ target | std | host | notes [`i386-apple-ios`](platform-support/apple-ios.md) | ✓ | | 32-bit x86 iOS (Penryn) [^x86_32-floats-return-ABI] [`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS (Pentium 4) [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86 (original Pentium) [^x86_32-floats-x87] +[`i586-unknown-redox`](platform-support/redox.md) | ✓ | | 32-bit x86 Redox OS (original Pentium) [^x86_32-floats-x87] [`i686-apple-darwin`](platform-support/apple-darwin.md) | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+, Penryn) [^x86_32-floats-return-ABI] `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd (PentiumPro) [^x86_32-floats-x87] [`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD (Pentium 4) [^x86_32-floats-return-ABI] -[`i686-unknown-redox`](platform-support/redox.md) | ✓ | | i686 Redox OS (PentiumPro) [^x86_32-floats-x87] `i686-uwp-windows-gnu` | ✓ | | [^x86_32-floats-return-ABI] [`i686-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ | | [^x86_32-floats-return-ABI] [`i686-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] diff --git a/src/doc/rustc/src/platform-support/redox.md b/src/doc/rustc/src/platform-support/redox.md index 1b3321956ef7b..2bba92d504c46 100644 --- a/src/doc/rustc/src/platform-support/redox.md +++ b/src/doc/rustc/src/platform-support/redox.md @@ -9,7 +9,7 @@ Target triplets available so far: - `x86_64-unknown-redox` (tier 2) - `aarch64-unknown-redox` (tier 3) -- `i686-unknown-redox` (tier 3) +- `i586-unknown-redox` (tier 3) ## Target maintainers @@ -36,7 +36,7 @@ target = [ "", "x86_64-unknown-redox", "aarch64-unknown-redox", - "i686-unknown-redox", + "i586-unknown-redox", ] ``` diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index feec2a7444f87..22ce88f9f28a7 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -99,6 +99,7 @@ static TARGETS: &[&str] = &[ "i586-pc-windows-msvc", "i586-unknown-linux-gnu", "i586-unknown-linux-musl", + "i586-unknown-redox", "i686-apple-darwin", "i686-linux-android", "i686-pc-windows-gnu", @@ -107,7 +108,6 @@ static TARGETS: &[&str] = &[ "i686-unknown-freebsd", "i686-unknown-linux-gnu", "i686-unknown-linux-musl", - "i686-unknown-redox", "i686-unknown-uefi", "loongarch64-unknown-linux-gnu", "loongarch64-unknown-linux-musl", diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 0ff886653a477..b5c0ee5a10741 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -228,6 +228,9 @@ //@ revisions: i586_unknown_netbsd //@ [i586_unknown_netbsd] compile-flags: --target i586-unknown-netbsd //@ [i586_unknown_netbsd] needs-llvm-components: x86 +//@ revisions: i586_unknown_redox +//@ [i586_unknown_redox] compile-flags: --target i586-unknown-redox +//@ [i586_unknown_redox] needs-llvm-components: x86 //@ revisions: i686_linux_android //@ [i686_linux_android] compile-flags: --target i686-linux-android //@ [i686_linux_android] needs-llvm-components: x86 @@ -252,9 +255,6 @@ //@ revisions: i686_unknown_openbsd //@ [i686_unknown_openbsd] compile-flags: --target i686-unknown-openbsd //@ [i686_unknown_openbsd] needs-llvm-components: x86 -//@ revisions: i686_unknown_redox -//@ [i686_unknown_redox] compile-flags: --target i686-unknown-redox -//@ [i686_unknown_redox] needs-llvm-components: x86 //@ revisions: i686_wrs_vxworks //@ [i686_wrs_vxworks] compile-flags: --target i686-wrs-vxworks //@ [i686_wrs_vxworks] needs-llvm-components: x86 From c2ff52afbd2bbc53e5f83fbce034c805c2c1b3f6 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 20/36] Preparing for merge from rustc --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index b629597207648..78e9ecdf174be 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -613bdd49978298648ed05ace086bd1ecad54b44a +124cc92199ffa924f6b4c7cc819a85b65e0c3984 From b8e135a79fa604e595b7d0419ff353700d87587e Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 10 Feb 2025 09:09:56 -0700 Subject: [PATCH 21/36] Change CPU target back to pentiumpro --- compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs index 67dfc42103b6f..29ef8b883a118 100644 --- a/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs @@ -2,7 +2,7 @@ use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base}; pub(crate) fn target() -> Target { let mut base = base::redox::opts(); - base.cpu = "pentium".into(); + base.cpu = "pentiumpro".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); From 54c15ebd5a53ad4796fcca7199ef620f7fc49662 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 10 Feb 2025 09:10:48 -0700 Subject: [PATCH 22/36] Update platform-support.md --- src/doc/rustc/src/platform-support.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index d9c0e6a132701..d3d063c0c8b6b 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -310,7 +310,7 @@ target | std | host | notes [`i386-apple-ios`](platform-support/apple-ios.md) | ✓ | | 32-bit x86 iOS (Penryn) [^x86_32-floats-return-ABI] [`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS (Pentium 4) [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86 (original Pentium) [^x86_32-floats-x87] -[`i586-unknown-redox`](platform-support/redox.md) | ✓ | | 32-bit x86 Redox OS (original Pentium) [^x86_32-floats-x87] +[`i586-unknown-redox`](platform-support/redox.md) | ✓ | | 32-bit x86 Redox OS (PentiumPro) [^x86_32-floats-x87] [`i686-apple-darwin`](platform-support/apple-darwin.md) | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+, Penryn) [^x86_32-floats-return-ABI] `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd (PentiumPro) [^x86_32-floats-x87] From 0395fc2242c2b04f3a0a330e2e1f6eeaf5939777 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 7 Feb 2025 17:50:08 +0100 Subject: [PATCH 23/36] Move line numbers into the `` directly --- src/librustdoc/html/highlight.rs | 112 ++++++++++++++++-- src/librustdoc/html/sources.rs | 24 ++-- src/librustdoc/html/static/css/rustdoc.css | 58 ++++++--- .../html/static/js/scrape-examples.js | 10 +- src/librustdoc/html/static/js/src-script.js | 8 +- .../html/templates/scraped_source.html | 12 +- src/librustdoc/html/templates/source.html | 10 +- 7 files changed, 168 insertions(+), 66 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 8c91cae493103..fbe3a8d5ba4fa 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -54,7 +54,7 @@ pub(crate) fn render_example_with_highlighting( extra_classes: &[String], ) { write_header(out, "rust-example-rendered", None, tooltip, extra_classes); - write_code(out, src, None, None); + write_code(out, src, None, None, None); write_footer(out, playground_button); } @@ -150,6 +150,7 @@ struct TokenHandler<'a, 'tcx, F: Write> { /// used to generate links. pending_elems: Vec<(&'a str, Option)>, href_context: Option>, + write_line_number: fn(&mut F, u32, &'static str), } impl TokenHandler<'_, '_, F> { @@ -182,7 +183,14 @@ impl TokenHandler<'_, '_, F> { && can_merge(current_class, Some(*parent_class), "") { for (text, class) in self.pending_elems.iter() { - string(self.out, EscapeBodyText(text), *class, &self.href_context, false); + string( + self.out, + EscapeBodyText(text), + *class, + &self.href_context, + false, + self.write_line_number, + ); } } else { // We only want to "open" the tag ourselves if we have more than one pending and if the @@ -204,6 +212,7 @@ impl TokenHandler<'_, '_, F> { *class, &self.href_context, close_tag.is_none(), + self.write_line_number, ); } if let Some(close_tag) = close_tag { @@ -213,6 +222,11 @@ impl TokenHandler<'_, '_, F> { self.pending_elems.clear(); true } + + #[inline] + fn write_line_number(&mut self, line: u32, extra: &'static str) { + (self.write_line_number)(&mut self.out, line, extra); + } } impl Drop for TokenHandler<'_, '_, F> { @@ -226,6 +240,43 @@ impl Drop for TokenHandler<'_, '_, F> { } } +fn write_scraped_line_number(out: &mut impl Write, line: u32, extra: &'static str) { + // https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr + // Do not show "1 2 3 4 5 ..." in web search results. + write!(out, "{extra}{line}",).unwrap(); +} + +fn write_line_number(out: &mut impl Write, line: u32, extra: &'static str) { + // https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr + // Do not show "1 2 3 4 5 ..." in web search results. + write!(out, "{extra}{line}",).unwrap(); +} + +fn empty_line_number(out: &mut impl Write, _: u32, extra: &'static str) { + out.write_str(extra).unwrap(); +} + +#[derive(Clone, Copy)] +pub(super) struct LineInfo { + pub(super) start_line: u32, + max_lines: u32, + pub(super) is_scraped_example: bool, +} + +impl LineInfo { + pub(super) fn new(max_lines: u32) -> Self { + Self { start_line: 1, max_lines: max_lines + 1, is_scraped_example: false } + } + + pub(super) fn new_scraped(max_lines: u32, start_line: u32) -> Self { + Self { + start_line: start_line + 1, + max_lines: max_lines + start_line + 1, + is_scraped_example: true, + } + } +} + /// Convert the given `src` source code into HTML by adding classes for highlighting. /// /// This code is used to render code blocks (in the documentation) as well as the source code pages. @@ -242,6 +293,7 @@ pub(super) fn write_code( src: &str, href_context: Option>, decoration_info: Option<&DecorationInfo>, + line_info: Option, ) { // This replace allows to fix how the code source with DOS backline characters is displayed. let src = src.replace("\r\n", "\n"); @@ -252,6 +304,23 @@ pub(super) fn write_code( current_class: None, pending_elems: Vec::new(), href_context, + write_line_number: match line_info { + Some(line_info) => { + if line_info.is_scraped_example { + write_scraped_line_number + } else { + write_line_number + } + } + None => empty_line_number, + }, + }; + + let (mut line, max_lines) = if let Some(line_info) = line_info { + token_handler.write_line_number(line_info.start_line, ""); + (line_info.start_line, line_info.max_lines) + } else { + (0, u32::MAX) }; Classifier::new( @@ -282,7 +351,14 @@ pub(super) fn write_code( if need_current_class_update { token_handler.current_class = class.map(Class::dummy); } - token_handler.pending_elems.push((text, class)); + if text == "\n" { + line += 1; + if line < max_lines { + token_handler.pending_elems.push((text, Some(Class::Backline(line)))); + } + } else { + token_handler.pending_elems.push((text, class)); + } } Highlight::EnterSpan { class } => { let mut should_add = true; @@ -348,6 +424,7 @@ enum Class { PreludeVal(Span), QuestionMark, Decoration(&'static str), + Backline(u32), } impl Class { @@ -396,6 +473,7 @@ impl Class { Class::PreludeVal(_) => "prelude-val", Class::QuestionMark => "question-mark", Class::Decoration(kind) => kind, + Class::Backline(_) => "", } } @@ -419,7 +497,8 @@ impl Class { | Self::Bool | Self::Lifetime | Self::QuestionMark - | Self::Decoration(_) => None, + | Self::Decoration(_) + | Self::Backline(_) => None, } } } @@ -694,8 +773,13 @@ impl<'src> Classifier<'src> { ) { let lookahead = self.peek(); let no_highlight = |sink: &mut dyn FnMut(_)| sink(Highlight::Token { text, class: None }); + let whitespace = |sink: &mut dyn FnMut(_)| { + for part in text.split('\n').intersperse("\n").filter(|s| !s.is_empty()) { + sink(Highlight::Token { text: part, class: None }); + } + }; let class = match token { - TokenKind::Whitespace => return no_highlight(sink), + TokenKind::Whitespace => return whitespace(sink), TokenKind::LineComment { doc_style } | TokenKind::BlockComment { doc_style, .. } => { if doc_style.is_some() { Class::DocComment @@ -716,7 +800,7 @@ impl<'src> Classifier<'src> { // or a reference or pointer type. Unless, of course, it looks like // a logical and or a multiplication operator: `&&` or `* `. TokenKind::Star => match self.tokens.peek() { - Some((TokenKind::Whitespace, _)) => return no_highlight(sink), + Some((TokenKind::Whitespace, _)) => return whitespace(sink), Some((TokenKind::Ident, "mut")) => { self.next(); sink(Highlight::Token { text: "*mut", class: Some(Class::RefKeyWord) }); @@ -740,7 +824,7 @@ impl<'src> Classifier<'src> { sink(Highlight::Token { text: "&=", class: None }); return; } - Some((TokenKind::Whitespace, _)) => return no_highlight(sink), + Some((TokenKind::Whitespace, _)) => return whitespace(sink), Some((TokenKind::Ident, "mut")) => { self.next(); sink(Highlight::Token { text: "&mut", class: Some(Class::RefKeyWord) }); @@ -887,7 +971,9 @@ impl<'src> Classifier<'src> { }; // Anything that didn't return above is the simple case where we the // class just spans a single token, so we can use the `string` method. - sink(Highlight::Token { text, class: Some(class) }); + for part in text.split('\n').intersperse("\n").filter(|s| !s.is_empty()) { + sink(Highlight::Token { text: part, class: Some(class) }); + } } fn peek(&mut self) -> Option { @@ -939,14 +1025,18 @@ fn exit_span(out: &mut impl Write, closing_tag: &str) { /// Note that if `context` is not `None` and that the given `klass` contains a `Span`, the function /// will then try to find this `span` in the `span_correspondence_map`. If found, it'll then /// generate a link for this element (which corresponds to where its definition is located). -fn string( - out: &mut impl Write, +fn string( + out: &mut W, text: T, klass: Option, href_context: &Option>, open_tag: bool, + write_line_number_callback: fn(&mut W, u32, &'static str), ) { - if let Some(closing_tag) = string_without_closing_tag(out, text, klass, href_context, open_tag) + if let Some(Class::Backline(line)) = klass { + write_line_number_callback(out, line, "\n"); + } else if let Some(closing_tag) = + string_without_closing_tag(out, text, klass, href_context, open_tag) { out.write_str(closing_tag).unwrap(); } diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 1ac0c10c61241..7839ba9ac8321 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -1,6 +1,5 @@ use std::cell::RefCell; use std::ffi::OsStr; -use std::ops::RangeInclusive; use std::path::{Component, Path, PathBuf}; use std::{fmt, fs}; @@ -303,16 +302,16 @@ pub(crate) struct ScrapedInfo<'a> { #[template(path = "scraped_source.html")] struct ScrapedSource<'a, Code: std::fmt::Display> { info: ScrapedInfo<'a>, - lines: RangeInclusive, code_html: Code, + max_nb_digits: u32, } #[derive(Template)] #[template(path = "source.html")] struct Source { - lines: RangeInclusive, code_html: Code, file_path: Option<(String, String)>, + max_nb_digits: u32, } pub(crate) enum SourceContext<'a> { @@ -331,6 +330,15 @@ pub(crate) fn print_src( decoration_info: &highlight::DecorationInfo, source_context: SourceContext<'_>, ) { + let mut lines = s.lines().count(); + let line_info = if let SourceContext::Embedded(ref info) = source_context { + highlight::LineInfo::new_scraped(lines as u32, info.offset as u32) + } else { + highlight::LineInfo::new(lines as u32) + }; + if line_info.is_scraped_example { + lines += line_info.start_line as usize; + } let code = fmt::from_fn(move |fmt| { let current_href = context .href_from_span(clean::Span::new(file_span), false) @@ -340,13 +348,13 @@ pub(crate) fn print_src( s, Some(highlight::HrefContext { context, file_span, root_path, current_href }), Some(decoration_info), + Some(line_info), ); Ok(()) }); - let lines = s.lines().count(); + let max_nb_digits = if lines > 0 { lines.ilog(10) + 1 } else { 1 }; match source_context { SourceContext::Standalone { file_path } => Source { - lines: (1..=lines), code_html: code, file_path: if let Some(file_name) = file_path.file_name() && let Some(file_path) = file_path.parent() @@ -355,12 +363,14 @@ pub(crate) fn print_src( } else { None }, + max_nb_digits, } .render_into(&mut writer) .unwrap(), SourceContext::Embedded(info) => { - let lines = (1 + info.offset)..=(lines + info.offset); - ScrapedSource { info, lines, code_html: code }.render_into(&mut writer).unwrap(); + ScrapedSource { info, code_html: code, max_nb_digits } + .render_into(&mut writer) + .unwrap(); } }; } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index d0612e997fd7b..613407cbe1f15 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -40,6 +40,7 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ --docblock-indent: 24px; --font-family: "Source Serif 4", NanumBarunGothic, serif; --font-family-code: "Source Code Pro", monospace; + --line-number-padding: 4px; } :root.sans-serif { @@ -450,9 +451,7 @@ pre.item-decl { .src .content pre { padding: 20px; -} -.rustdoc.src .example-wrap .src-line-numbers { - padding: 20px 0 20px 4px; + padding-left: 16px; } img { @@ -908,22 +907,46 @@ both the code example and the line numbers, so we need to remove the radius in t color: var(--src-line-numbers-span-color); } -.rustdoc .scraped-example .example-wrap .src-line-numbers { - padding: 0; +.example-wrap.digits-1 [data-nosnippet] { + width: calc(1ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-2 [data-nosnippet] { + width: calc(2ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-3 [data-nosnippet] { + width: calc(3ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-4 [data-nosnippet] { + width: calc(4ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-5 [data-nosnippet] { + width: calc(5ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-6 [data-nosnippet] { + width: calc(6ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-7 [data-nosnippet] { + width: calc(7ch + var(--line-number-padding) * 2); } -.rustdoc .src-line-numbers pre { - padding: 14px 0; +.example-wrap.digits-8 [data-nosnippet] { + width: calc(8ch + var(--line-number-padding) * 2); } -.src-line-numbers a, .src-line-numbers span { +.example-wrap.digits-9 [data-nosnippet] { + width: calc(9ch + var(--line-number-padding) * 2); +} + +.example-wrap [data-nosnippet] { color: var(--src-line-numbers-span-color); - padding: 0 8px; + text-align: right; + display: inline-block; + margin-right: 20px; + user-select: none; + padding: 0 4px; } -.src-line-numbers :target { - background-color: transparent; +.example-wrap [data-nosnippet]:target { border-right: none; - padding: 0 8px; } -.src-line-numbers .line-highlighted { +.example-wrap .line-highlighted[data-nosnippet] { background-color: var(--src-line-number-highlighted-background-color); } @@ -1110,7 +1133,7 @@ because of the `[-]` element which would overlap with it. */ } .main-heading a:hover, -.example-wrap .rust a:hover, +.example-wrap .rust a:hover:not([data-nosnippet]), .all-items a:hover, .docblock a:not(.scrape-help):not(.tooltip):hover:not(.doc-anchor), .item-table dd a:not(.scrape-help):not(.tooltip):hover, @@ -1568,7 +1591,7 @@ pre.rust .doccomment { color: var(--code-highlight-doc-comment-color); } -.rustdoc.src .example-wrap pre.rust a { +.rustdoc.src .example-wrap pre.rust a:not([data-nosnippet]) { background: var(--codeblock-link-background); } @@ -1759,8 +1782,7 @@ instead, we check that it's not a "finger" cursor. } } -:target { - padding-right: 3px; +:target:not([data-nosnippet]) { background-color: var(--target-background-color); border-right: 3px solid var(--target-border-color); } @@ -3153,7 +3175,7 @@ Original by Dempfi (https://github.com/dempfi/ayu) color: #ff7733; } -:root[data-theme="ayu"] .src-line-numbers .line-highlighted { +:root[data-theme="ayu"] a[data-nosnippet].line-highlighted { color: #708090; padding-right: 7px; border-right: 1px solid #ffb44c; diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js index d08f15a5bfa86..99cbe6daf3177 100644 --- a/src/librustdoc/html/static/js/scrape-examples.js +++ b/src/librustdoc/html/static/js/scrape-examples.js @@ -16,7 +16,7 @@ // Scroll code block to the given code location function scrollToLoc(elt, loc, isHidden) { - const lines = elt.querySelector(".src-line-numbers > pre"); + const lines = elt.querySelectorAll("[data-nosnippet]"); let scrollOffset; // If the block is greater than the size of the viewer, @@ -25,17 +25,17 @@ const maxLines = isHidden ? HIDDEN_MAX_LINES : DEFAULT_MAX_LINES; if (loc[1] - loc[0] > maxLines) { const line = Math.max(0, loc[0] - 1); - scrollOffset = lines.children[line].offsetTop; + scrollOffset = lines[line].offsetTop; } else { const halfHeight = elt.offsetHeight / 2; - const offsetTop = lines.children[loc[0]].offsetTop; - const lastLine = lines.children[loc[1]]; + const offsetTop = lines[loc[0]].offsetTop; + const lastLine = lines[loc[1]]; const offsetBot = lastLine.offsetTop + lastLine.offsetHeight; const offsetMid = (offsetTop + offsetBot) / 2; scrollOffset = offsetMid - halfHeight; } - lines.parentElement.scrollTo(0, scrollOffset); + lines[0].parentElement.scrollTo(0, scrollOffset); elt.querySelector(".rust").scrollTo(0, scrollOffset); } diff --git a/src/librustdoc/html/static/js/src-script.js b/src/librustdoc/html/static/js/src-script.js index 8f712f4c20c7b..fc27241334bfe 100644 --- a/src/librustdoc/html/static/js/src-script.js +++ b/src/librustdoc/html/static/js/src-script.js @@ -138,10 +138,8 @@ function highlightSrcLines() { if (x) { x.scrollIntoView(); } - onEachLazy(document.getElementsByClassName("src-line-numbers"), e => { - onEachLazy(e.getElementsByTagName("a"), i_e => { - removeClass(i_e, "line-highlighted"); - }); + onEachLazy(document.querySelectorAll("a[data-nosnippet]"), e => { + removeClass(e, "line-highlighted"); }); for (let i = from; i <= to; ++i) { elem = document.getElementById(i); @@ -200,7 +198,7 @@ const handleSrcHighlight = (function() { window.addEventListener("hashchange", highlightSrcLines); -onEachLazy(document.getElementsByClassName("src-line-numbers"), el => { +onEachLazy(document.querySelectorAll("a[data-nosnippet]"), el => { el.addEventListener("click", handleSrcHighlight); }); diff --git a/src/librustdoc/html/templates/scraped_source.html b/src/librustdoc/html/templates/scraped_source.html index bd54bbf58d508..3e69f1c8cad71 100644 --- a/src/librustdoc/html/templates/scraped_source.html +++ b/src/librustdoc/html/templates/scraped_source.html @@ -2,17 +2,7 @@
{{info.name +}} ({{info.title}}) {# #}
{# #} -
- {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr - Do not show "1 2 3 4 5 ..." in web search results. #} -
{# #} -
-                {% for line in lines.clone() %}
-                    {# ~#}
-                    {{line|safe}}
-                {% endfor %}
-            
{# #} -
{# #} +
{# #}
 {# #}
             
                 {{code_html|safe}}
diff --git a/src/librustdoc/html/templates/source.html b/src/librustdoc/html/templates/source.html
index ea530087e6f09..454d4c27f1ad6 100644
--- a/src/librustdoc/html/templates/source.html
+++ b/src/librustdoc/html/templates/source.html
@@ -9,15 +9,7 @@ 

{# #}

{% else %} {% endmatch %} -
- {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr - Do not show "1 2 3 4 5 ..." in web search results. #} -
-        {% for line in lines.clone() %}
-            {# ~#}
-            {{line|safe}}
-        {% endfor %}
-    
{# #} +
{# #}
 {# #}
         
             {{code_html|safe}}

From 673fd23dff47bf72953d1408b1cfbd45f6ef859b Mon Sep 17 00:00:00 2001
From: Guillaume Gomez 
Date: Fri, 7 Feb 2025 17:50:14 +0100
Subject: [PATCH 24/36] Update rustdoc tests

---
 src/librustdoc/html/highlight/tests.rs        | 10 +--
 tests/rustdoc-gui/basic-code.goml             |  6 --
 .../docblock-code-block-line-number.goml      | 66 +++++--------------
 tests/rustdoc-gui/jump-to-def-background.goml |  2 +-
 .../scrape-examples-button-focus.goml         | 40 +----------
 tests/rustdoc-gui/scrape-examples-layout.goml | 47 +++++--------
 tests/rustdoc-gui/source-anchor-scroll.goml   |  6 +-
 .../source-code-page-code-scroll.goml         |  4 +-
 tests/rustdoc-gui/source-code-page.goml       | 38 +++++------
 .../rustdoc/check-source-code-urls-to-def.rs  |  9 +--
 10 files changed, 72 insertions(+), 156 deletions(-)
 delete mode 100644 tests/rustdoc-gui/basic-code.goml

diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs
index fccbb98f80ff3..8f39130bb836e 100644
--- a/src/librustdoc/html/highlight/tests.rs
+++ b/src/librustdoc/html/highlight/tests.rs
@@ -23,7 +23,7 @@ fn test_html_highlighting() {
         let src = include_str!("fixtures/sample.rs");
         let html = {
             let mut out = Buffer::new();
-            write_code(&mut out, src, None, None);
+            write_code(&mut out, src, None, None, None);
             format!("{STYLE}
{}
\n", out.into_inner()) }; expect_file!["fixtures/sample.html"].assert_eq(&html); @@ -37,7 +37,7 @@ fn test_dos_backline() { println!(\"foo\");\r\n\ }\r\n"; let mut html = Buffer::new(); - write_code(&mut html, src, None, None); + write_code(&mut html, src, None, None, None); expect_file!["fixtures/dos_line.html"].assert_eq(&html.into_inner()); }); } @@ -51,7 +51,7 @@ let x = super::b::foo; let y = Self::whatever;"; let mut html = Buffer::new(); - write_code(&mut html, src, None, None); + write_code(&mut html, src, None, None, None); expect_file!["fixtures/highlight.html"].assert_eq(&html.into_inner()); }); } @@ -61,7 +61,7 @@ fn test_union_highlighting() { create_default_session_globals_then(|| { let src = include_str!("fixtures/union.rs"); let mut html = Buffer::new(); - write_code(&mut html, src, None, None); + write_code(&mut html, src, None, None, None); expect_file!["fixtures/union.html"].assert_eq(&html.into_inner()); }); } @@ -78,7 +78,7 @@ let a = 4;"; decorations.insert("example2", vec![(22, 32)]); let mut html = Buffer::new(); - write_code(&mut html, src, None, Some(&DecorationInfo(decorations))); + write_code(&mut html, src, None, Some(&DecorationInfo(decorations)), None); expect_file!["fixtures/decorations.html"].assert_eq(&html.into_inner()); }); } diff --git a/tests/rustdoc-gui/basic-code.goml b/tests/rustdoc-gui/basic-code.goml deleted file mode 100644 index 22ac531618423..0000000000000 --- a/tests/rustdoc-gui/basic-code.goml +++ /dev/null @@ -1,6 +0,0 @@ -// Small test to ensure the "src-line-numbers" element is only present once on -// the page. -go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -click: "a.src" -wait-for: ".src-line-numbers" -assert-count: (".src-line-numbers", 1) diff --git a/tests/rustdoc-gui/docblock-code-block-line-number.goml b/tests/rustdoc-gui/docblock-code-block-line-number.goml index 3c16626336ea6..032746a6bdf44 100644 --- a/tests/rustdoc-gui/docblock-code-block-line-number.goml +++ b/tests/rustdoc-gui/docblock-code-block-line-number.goml @@ -111,28 +111,6 @@ wait-for: "pre.example-line-numbers" // Same check with scraped examples line numbers. go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html" -assert-css: ( - ".scraped-example .src-line-numbers > pre", - { - // There should not be a radius on the right of the line numbers. - "border-top-left-radius": "6px", - "border-bottom-left-radius": "6px", - "border-top-right-radius": "0px", - "border-bottom-right-radius": "0px", - }, - ALL, -) -assert-css: ( - ".scraped-example .src-line-numbers", - { - // There should not be a radius on the right of the line numbers. - "border-top-left-radius": "6px", - "border-bottom-left-radius": "6px", - "border-top-right-radius": "0px", - "border-bottom-right-radius": "0px", - }, - ALL, -) assert-css: ( ".scraped-example .rust", { @@ -149,23 +127,15 @@ define-function: ( "check-padding", [path, padding_bottom], block { - assert-css: (|path| + " .src-line-numbers", { + assert-css: (|path| + " span[data-nosnippet]", { "padding-top": "0px", "padding-bottom": "0px", - "padding-left": "0px", - "padding-right": "0px", - }, ALL) - assert-css: (|path| + " .src-line-numbers > pre", { - "padding-top": "14px", - "padding-bottom": |padding_bottom|, - "padding-left": "0px", - "padding-right": "0px", - }, ALL) - assert-css: (|path| + " .src-line-numbers > pre > span", { - "padding-top": "0px", - "padding-bottom": "0px", - "padding-left": "8px", - "padding-right": "8px", + "padding-left": "4px", + "padding-right": "4px", + "margin-right": "20px", + "margin-left": "0px", + "margin-top": "0px", + "margin-bottom": "0px", }, ALL) }, ) @@ -196,13 +166,13 @@ define-function: ("check-line-numbers-existence", [], block { wait-for-local-storage-false: {"rustdoc-line-numbers": "true" } assert-false: ".example-line-numbers" // Line numbers should still be there. - assert: ".src-line-numbers" + assert-css: ("[data-nosnippet]", { "display": "inline-block"}) // Now disabling the setting. click: "input#line-numbers" wait-for-local-storage: {"rustdoc-line-numbers": "true" } assert-false: ".example-line-numbers" // Line numbers should still be there. - assert: ".src-line-numbers" + assert-css: ("[data-nosnippet]", { "display": "inline-block"}) // Closing settings menu. click: "#settings-menu" wait-for-css: ("#settings", {"display": "none"}) @@ -214,18 +184,16 @@ call-function: ("check-line-numbers-existence", {}) // Now checking the line numbers in the source code page. click: ".src" -assert-css: (".src-line-numbers", { - "padding-top": "20px", - "padding-bottom": "20px", - "padding-left": "4px", - "padding-right": "0px", -}) -assert-css: (".src-line-numbers > a", { +assert-css: ("a[data-nosnippet]", { "padding-top": "0px", "padding-bottom": "0px", - "padding-left": "8px", - "padding-right": "8px", -}) + "padding-left": "4px", + "padding-right": "4px", + "margin-top": "0px", + "margin-bottom": "0px", + "margin-left": "0px", + "margin-right": "20px", +}, ALL) // Checking that turning off the line numbers setting won't remove line numbers. call-function: ("check-line-numbers-existence", {}) diff --git a/tests/rustdoc-gui/jump-to-def-background.goml b/tests/rustdoc-gui/jump-to-def-background.goml index 71320360740c4..de5ea6c9b0b08 100644 --- a/tests/rustdoc-gui/jump-to-def-background.goml +++ b/tests/rustdoc-gui/jump-to-def-background.goml @@ -8,7 +8,7 @@ define-function: ( block { call-function: ("switch-theme", {"theme": |theme|}) assert-css: ( - "body.src .example-wrap pre.rust a", + "body.src .example-wrap pre.rust a:not([data-nosnippet])", {"background-color": |background_color|}, ALL, ) diff --git a/tests/rustdoc-gui/scrape-examples-button-focus.goml b/tests/rustdoc-gui/scrape-examples-button-focus.goml index 83ed6a219b25a..d53993ac08bae 100644 --- a/tests/rustdoc-gui/scrape-examples-button-focus.goml +++ b/tests/rustdoc-gui/scrape-examples-button-focus.goml @@ -4,52 +4,18 @@ go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html" // The next/prev buttons vertically scroll the code viewport between examples move-cursor-to: ".scraped-example-list > .scraped-example" -store-property: (".scraped-example-list > .scraped-example .src-line-numbers", { - "scrollTop": initialScrollTop, -}) +wait-for: ".scraped-example-list > .scraped-example .next" +store-value: (initialScrollTop, 250) assert-property: (".scraped-example-list > .scraped-example .rust", { "scrollTop": |initialScrollTop|, -}) +}, NEAR) focus: ".scraped-example-list > .scraped-example .next" press-key: "Enter" -assert-property-false: (".scraped-example-list > .scraped-example .src-line-numbers", { - "scrollTop": |initialScrollTop| -}, NEAR) assert-property-false: (".scraped-example-list > .scraped-example .rust", { "scrollTop": |initialScrollTop| }, NEAR) focus: ".scraped-example-list > .scraped-example .prev" press-key: "Enter" -assert-property: (".scraped-example-list > .scraped-example .src-line-numbers", { - "scrollTop": |initialScrollTop| -}, NEAR) assert-property: (".scraped-example-list > .scraped-example .rust", { "scrollTop": |initialScrollTop| }, NEAR) - -// The expand button increases the scrollHeight of the minimized code viewport -store-property: (".scraped-example-list > .scraped-example pre", {"offsetHeight": smallOffsetHeight}) -assert-property: (".scraped-example-list > .scraped-example .src-line-numbers", { - "scrollHeight": |smallOffsetHeight| -}, NEAR) -assert-property: (".scraped-example-list > .scraped-example .rust", { - "scrollHeight": |smallOffsetHeight| -}, NEAR) -focus: ".scraped-example-list > .scraped-example .expand" -press-key: "Enter" -assert-property-false: (".scraped-example-list > .scraped-example .src-line-numbers", { - "offsetHeight": |smallOffsetHeight| -}, NEAR) -assert-property-false: (".scraped-example-list > .scraped-example .rust", { - "offsetHeight": |smallOffsetHeight| -}, NEAR) -store-property: (".scraped-example-list > .scraped-example .src-line-numbers", { - "offsetHeight": fullOffsetHeight, -}) -assert-property: (".scraped-example-list > .scraped-example .rust", { - "offsetHeight": |fullOffsetHeight|, - "scrollHeight": |fullOffsetHeight|, -}) -assert-property: (".scraped-example-list > .scraped-example .src-line-numbers", { - "scrollHeight": |fullOffsetHeight| -}, NEAR) diff --git a/tests/rustdoc-gui/scrape-examples-layout.goml b/tests/rustdoc-gui/scrape-examples-layout.goml index 5187ac486b088..85a3b2a628734 100644 --- a/tests/rustdoc-gui/scrape-examples-layout.goml +++ b/tests/rustdoc-gui/scrape-examples-layout.goml @@ -3,35 +3,38 @@ go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html" set-window-size: (1000, 1000) +// We move the mouse over the scraped example for the prev button to be generated. +move-cursor-to: ".scraped-example" + // Check that it's not zero. assert-property-false: ( - ".more-scraped-examples .scraped-example .src-line-numbers", + ".more-scraped-examples .scraped-example span[data-nosnippet]", {"clientWidth": "0"} ) // Check that examples with very long lines have the same width as ones that don't. store-property: ( - ".more-scraped-examples .scraped-example:nth-child(2) .src-line-numbers", + ".more-scraped-examples .scraped-example:nth-child(2) span[data-nosnippet]", {"clientWidth": clientWidth}, ) assert-property: ( - ".more-scraped-examples .scraped-example:nth-child(3) .src-line-numbers", + ".more-scraped-examples .scraped-example:nth-child(3) span[data-nosnippet]", {"clientWidth": |clientWidth|} ) assert-property: ( - ".more-scraped-examples .scraped-example:nth-child(4) .src-line-numbers", + ".more-scraped-examples .scraped-example:nth-child(4) span[data-nosnippet]", {"clientWidth": |clientWidth|} ) assert-property: ( - ".more-scraped-examples .scraped-example:nth-child(5) .src-line-numbers", + ".more-scraped-examples .scraped-example:nth-child(5) span[data-nosnippet]", {"clientWidth": |clientWidth|} ) assert-property: ( - ".more-scraped-examples .scraped-example:nth-child(6) .src-line-numbers", + ".more-scraped-examples .scraped-example:nth-child(6) span[data-nosnippet]", {"clientWidth": |clientWidth|} ) @@ -55,25 +58,6 @@ assert-size: (".more-scraped-examples .scraped-example .example-wrap", { "width": |width|, }) -// Check that the expand button works and also that line number aligns with code. -move-cursor-to: ".scraped-example .rust" -click: ".scraped-example .button-holder .expand" -wait-for: ".scraped-example.expanded" -// They should have the same y position. -compare-elements-position: ( - ".scraped-example.expanded .src-line-numbers pre span", - ".scraped-example.expanded .rust code", - ["y"], -) -// And they should have the same height. -compare-elements-size: ( - ".scraped-example.expanded .src-line-numbers", - ".scraped-example.expanded .rust", - ["height"], -) -// Collapse code again. -click: ".scraped-example .button-holder .expand" - // Check that for both mobile and desktop sizes, the buttons in scraped examples are displayed // correctly. @@ -98,7 +82,7 @@ define-function: ( [], block { // Title should be above the code. - store-position: (".scraped-example .example-wrap .src-line-numbers", {"x": x, "y": y}) + store-position: (".scraped-example .example-wrap", {"x": x, "y": y}) store-size: (".scraped-example .scraped-example-title", { "height": title_height }) assert-position: (".scraped-example .scraped-example-title", { @@ -107,10 +91,13 @@ define-function: ( }) // Line numbers should be right beside the code. - compare-elements-position: ( - ".scraped-example .example-wrap .src-line-numbers", - ".scraped-example .example-wrap .rust", - ["y"], + compare-elements-position-near: ( + ".scraped-example .example-wrap span[data-nosnippet]", + // On the first line, the code starts with `fn main` so we have a keyword. + ".scraped-example .example-wrap .rust span.kw", + // They're not exactly the same size but since they're on the same line, + // it's kinda the same. + {"y": 2}, ) } ) diff --git a/tests/rustdoc-gui/source-anchor-scroll.goml b/tests/rustdoc-gui/source-anchor-scroll.goml index 4ad65bbbd61ac..c005af1e7a1c6 100644 --- a/tests/rustdoc-gui/source-anchor-scroll.goml +++ b/tests/rustdoc-gui/source-anchor-scroll.goml @@ -8,13 +8,13 @@ set-window-size: (600, 800) assert-property: ("html", {"scrollTop": "0"}) click: '//a[text() = "barbar" and @href="#5-7"]' -assert-property: ("html", {"scrollTop": "208"}) +assert-property: ("html", {"scrollTop": "206"}) click: '//a[text() = "bar" and @href="#28-36"]' assert-property: ("html", {"scrollTop": "239"}) click: '//a[normalize-space() = "sub_fn" and @href="#2-4"]' -assert-property: ("html", {"scrollTop": "136"}) +assert-property: ("html", {"scrollTop": "134"}) // We now check that clicking on lines doesn't change the scroll // Extra information: the "sub_fn" function header is on line 1. click: '//*[@id="6"]' -assert-property: ("html", {"scrollTop": "136"}) +assert-property: ("html", {"scrollTop": "134"}) diff --git a/tests/rustdoc-gui/source-code-page-code-scroll.goml b/tests/rustdoc-gui/source-code-page-code-scroll.goml index 60012db6c8c8b..c15a9ae7983c6 100644 --- a/tests/rustdoc-gui/source-code-page-code-scroll.goml +++ b/tests/rustdoc-gui/source-code-page-code-scroll.goml @@ -2,7 +2,7 @@ go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" set-window-size: (800, 1000) // "scrollWidth" should be superior than "clientWidth". -assert-property: ("body", {"scrollWidth": 1776, "clientWidth": 800}) +assert-property: ("body", {"scrollWidth": 1780, "clientWidth": 800}) // Both properties should be equal (ie, no scroll on the code block). -assert-property: (".example-wrap .rust", {"scrollWidth": 1662, "clientWidth": 1662}) +assert-property: (".example-wrap .rust", {"scrollWidth": 1715, "clientWidth": 1715}) diff --git a/tests/rustdoc-gui/source-code-page.goml b/tests/rustdoc-gui/source-code-page.goml index afb194625210c..aa5a16aac7048 100644 --- a/tests/rustdoc-gui/source-code-page.goml +++ b/tests/rustdoc-gui/source-code-page.goml @@ -3,7 +3,7 @@ include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" show-text: true // Check that we can click on the line number. -click: ".src-line-numbers > a:nth-child(4)" // This is the anchor for line 4. +click: "//a[@data-nosnippet and text()='4']" // This is the anchor for line 4. // Ensure that the page URL was updated. assert-document-property: ({"URL": "lib.rs.html#4"}, ENDS_WITH) assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"}) @@ -14,11 +14,11 @@ assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"}) assert-css: ("//*[@id='4']", {"border-right-width": "0px"}) // We now check that the good anchors are highlighted go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#4-6" -assert-attribute-false: (".src-line-numbers > a:nth-child(3)", {"class": "line-highlighted"}) -assert-attribute: (".src-line-numbers > a:nth-child(4)", {"class": "line-highlighted"}) -assert-attribute: (".src-line-numbers > a:nth-child(5)", {"class": "line-highlighted"}) -assert-attribute: (".src-line-numbers > a:nth-child(6)", {"class": "line-highlighted"}) -assert-attribute-false: (".src-line-numbers > a:nth-child(7)", {"class": "line-highlighted"}) +assert-attribute-false: ("//a[@data-nosnippet and text()='3']", {"class": "line-highlighted"}) +assert-attribute: ("//a[@data-nosnippet and text()='4']", {"class": "line-highlighted"}) +assert-attribute: ("//a[@data-nosnippet and text()='5']", {"class": "line-highlighted"}) +assert-attribute: ("//a[@data-nosnippet and text()='6']", {"class": "line-highlighted"}) +assert-attribute-false: ("//a[@data-nosnippet and text()='7']", {"class": "line-highlighted"}) define-function: ( "check-colors", @@ -26,12 +26,12 @@ define-function: ( block { call-function: ("switch-theme", {"theme": |theme|}) assert-css: ( - ".src-line-numbers > a:not(.line-highlighted)", + "a[data-nosnippet]:not(.line-highlighted)", {"color": |color|, "background-color": |background_color|}, ALL, ) assert-css: ( - ".src-line-numbers > a.line-highlighted", + "a[data-nosnippet].line-highlighted", {"color": |highlight_color|, "background-color": |highlight_background_color|}, ALL, ) @@ -61,37 +61,37 @@ call-function: ("check-colors", { }) // This is to ensure that the content is correctly align with the line numbers. -compare-elements-position: ("//*[@id='1']", ".rust > code > span", ["y"]) +compare-elements-position-near: ("//*[@id='1']", ".rust > code > span", {"y": 2}) // Check the `href` property so that users can treat anchors as links. -assert-property: (".src-line-numbers > a:nth-child(1)", { +assert-property: ("//a[@data-nosnippet and text()='1']", { "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#1" }, ENDS_WITH) -assert-property: (".src-line-numbers > a:nth-child(2)", { +assert-property: ("//a[@data-nosnippet and text()='2']", { "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#2" }, ENDS_WITH) -assert-property: (".src-line-numbers > a:nth-child(3)", { +assert-property: ("//a[@data-nosnippet and text()='3']", { "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#3" }, ENDS_WITH) -assert-property: (".src-line-numbers > a:nth-child(4)", { +assert-property: ("//a[@data-nosnippet and text()='4']", { "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#4" }, ENDS_WITH) -assert-property: (".src-line-numbers > a:nth-child(5)", { +assert-property: ("//a[@data-nosnippet and text()='5']", { "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#5" }, ENDS_WITH) -assert-property: (".src-line-numbers > a:nth-child(6)", { +assert-property: ("//a[@data-nosnippet and text()='6']", { "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#6" }, ENDS_WITH) // Assert that the line numbers text is aligned to the right. -assert-css: (".src-line-numbers", {"text-align": "right"}) +assert-css: ("a[data-nosnippet]", {"text-align": "right"}, ALL) // Now let's check that clicking on something else than the line number doesn't // do anything (and certainly not add a `#NaN` to the URL!). go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" // We use this assert-position to know where we will click. -assert-position: ("//*[@id='1']", {"x": 88, "y": 171}) -// We click on the left of the "1" anchor but still in the "src-line-number" `
`.
-click: (163, 77)
+assert-position: ("//*[@id='1']", {"x": 81, "y": 169})
+// We click on the left of the "1" anchor but still in the `a[data-nosnippet]`.
+click: (77, 163)
 assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH)
 
 // Checking the source code sidebar.
diff --git a/tests/rustdoc/check-source-code-urls-to-def.rs b/tests/rustdoc/check-source-code-urls-to-def.rs
index 8703287abc553..d701b88bf9fd0 100644
--- a/tests/rustdoc/check-source-code-urls-to-def.rs
+++ b/tests/rustdoc/check-source-code-urls-to-def.rs
@@ -31,7 +31,8 @@ fn babar() {}
 //@ has - '//pre[@class="rust"]//a/@href' '/struct.String.html'
 //@ has - '//pre[@class="rust"]//a/@href' '/primitive.u32.html'
 //@ has - '//pre[@class="rust"]//a/@href' '/primitive.str.html'
-//@ count - '//pre[@class="rust"]//a[@href="#23"]' 5
+// The 5 links to line 23 and the line 23 itself.
+//@ count - '//pre[@class="rust"]//a[@href="#23"]' 6
 //@ has - '//pre[@class="rust"]//a[@href="../../source_code/struct.SourceCode.html"]' \
 //        'source_code::SourceCode'
 pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::SourceCode) {
@@ -50,8 +51,8 @@ pub fn foo2(t: &T, v: &V, b: bool) {}
 pub trait AnotherTrait {}
 pub trait WhyNot {}
 
-//@ has - '//pre[@class="rust"]//a[@href="#50"]' 'AnotherTrait'
-//@ has - '//pre[@class="rust"]//a[@href="#51"]' 'WhyNot'
+//@ has - '//pre[@class="rust"]//a[@href="#51"]' 'AnotherTrait'
+//@ has - '//pre[@class="rust"]//a[@href="#52"]' 'WhyNot'
 pub fn foo3(t: &T, v: &V)
 where
     T: AnotherTrait,
@@ -60,7 +61,7 @@ where
 
 pub trait AnotherTrait2 {}
 
-//@ has - '//pre[@class="rust"]//a[@href="#61"]' 'AnotherTrait2'
+//@ has - '//pre[@class="rust"]//a[@href="#62"]' 'AnotherTrait2'
 pub fn foo4() {
     let x: Vec<&dyn AnotherTrait2> = Vec::new();
 }

From 9e0c8b67e9fdb0dd2045f986536aa612d0746714 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez 
Date: Mon, 10 Feb 2025 18:49:09 +0100
Subject: [PATCH 25/36] Add regression test for source line numbers

---
 tests/rustdoc/source-line-numbers.rs | 35 ++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 tests/rustdoc/source-line-numbers.rs

diff --git a/tests/rustdoc/source-line-numbers.rs b/tests/rustdoc/source-line-numbers.rs
new file mode 100644
index 0000000000000..0b654b1a00476
--- /dev/null
+++ b/tests/rustdoc/source-line-numbers.rs
@@ -0,0 +1,35 @@
+// This test ensures that we have the expected number of line generated.
+
+#![crate_name = "foo"]
+
+//@ has 'src/foo/source-line-numbers.rs.html'
+//@ count - '//a[@data-nosnippet]' 35
+//@ has - '//a[@id="35"]' '35'
+
+#[
+macro_export
+]
+macro_rules! bar {
+    ($x:ident) => {{
+        $x += 2;
+        $x *= 2;
+    }}
+}
+
+/*
+multi line
+comment
+*/
+fn x(_: u8, _: u8) {}
+
+fn foo() {
+    let mut y = 0;
+    bar!(y);
+    println!("
+    {y}
+    ");
+    x(
+      1,
+      2,
+    );
+}

From 9222b05d9fb29c465058cbac744fd9c054f8ec1a Mon Sep 17 00:00:00 2001
From: Guillaume Gomez 
Date: Tue, 11 Feb 2025 11:56:47 +0100
Subject: [PATCH 26/36] Correctly handle `user-select: none`

---
 src/librustdoc/html/static/css/rustdoc.css | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 613407cbe1f15..f39c0e4a31400 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -900,7 +900,9 @@ both the code example and the line numbers, so we need to remove the radius in t
 	min-width: fit-content; /* prevent collapsing into nothing in truncated scraped examples */
 	flex-grow: 0;
 	text-align: right;
+	-moz-user-select: none;
 	-webkit-user-select: none;
+	-ms-user-select: none;
 	user-select: none;
 	padding: 14px 8px;
 	padding-right: 2px;
@@ -940,6 +942,9 @@ both the code example and the line numbers, so we need to remove the radius in t
 	text-align: right;
 	display: inline-block;
 	margin-right: 20px;
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
 	user-select: none;
 	padding: 0 4px;
 }

From 909d43b38cfafe85a806b8a51b0718539885e756 Mon Sep 17 00:00:00 2001
From: onur-ozkan 
Date: Sun, 9 Feb 2025 11:44:14 +0300
Subject: [PATCH 27/36] add `Builder::is_host_target`

Signed-off-by: onur-ozkan 
---
 src/bootstrap/src/core/build_steps/compile.rs |  4 ++--
 src/bootstrap/src/core/build_steps/dist.rs    |  6 +++---
 src/bootstrap/src/core/build_steps/llvm.rs    |  6 +++---
 src/bootstrap/src/core/build_steps/test.rs    |  2 +-
 src/bootstrap/src/core/sanity.rs              |  2 +-
 src/bootstrap/src/lib.rs                      | 11 ++++++++---
 6 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index f6f9067b9c6fc..980383c381577 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -191,7 +191,7 @@ impl Step for Std {
         // The LLD wrappers and `rust-lld` are self-contained linking components that can be
         // necessary to link the stdlib on some targets. We'll also need to copy these binaries to
         // the `stage0-sysroot` to ensure the linker is found when bootstrapping on such a target.
-        if compiler.stage == 0 && compiler.host == builder.config.build {
+        if compiler.stage == 0 && builder.is_host_target(&compiler.host) {
             // We want to copy the host `bin` folder within the `rustlib` folder in the sysroot.
             let src_sysroot_bin = builder
                 .rustc_snapshot_sysroot()
@@ -2312,7 +2312,7 @@ pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path)
     // FIXME: to make things simpler for now, limit this to the host and target where we know
     // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
     // cross-compiling. Expand this to other appropriate targets in the future.
-    if target != "x86_64-unknown-linux-gnu" || target != builder.config.build || !path.exists() {
+    if target != "x86_64-unknown-linux-gnu" || !builder.is_host_target(&target) || !path.exists() {
         return;
     }
 
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 18f920b85eee0..22c3be60499dd 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -582,7 +582,7 @@ impl Step for DebuggerScripts {
 fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
     // The only true set of target libraries came from the build triple, so
     // let's reduce redundant work by only producing archives from that host.
-    if compiler.host != builder.config.build {
+    if !builder.is_host_target(&compiler.host) {
         builder.info("\tskipping, not a build host");
         true
     } else {
@@ -637,7 +637,7 @@ fn copy_target_libs(
     for (path, dependency_type) in builder.read_stamp_file(stamp) {
         if dependency_type == DependencyType::TargetSelfContained {
             builder.copy_link(&path, &self_contained_dst.join(path.file_name().unwrap()));
-        } else if dependency_type == DependencyType::Target || builder.config.build == target {
+        } else if dependency_type == DependencyType::Target || builder.is_host_target(&target) {
             builder.copy_link(&path, &dst.join(path.file_name().unwrap()));
         }
     }
@@ -786,7 +786,7 @@ impl Step for Analysis {
     fn run(self, builder: &Builder<'_>) -> Option {
         let compiler = self.compiler;
         let target = self.target;
-        if compiler.host != builder.config.build {
+        if !builder.is_host_target(&compiler.host) {
             return None;
         }
 
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 9dd3505706213..00485c5a23127 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -516,7 +516,7 @@ impl Step for Llvm {
         }
 
         // https://llvm.org/docs/HowToCrossCompileLLVM.html
-        if target != builder.config.build {
+        if !builder.is_host_target(&target) {
             let LlvmResult { llvm_config, .. } =
                 builder.ensure(Llvm { target: builder.config.build });
             if !builder.config.dry_run() {
@@ -661,7 +661,7 @@ fn configure_cmake(
     }
     cfg.target(&target.triple).host(&builder.config.build.triple);
 
-    if target != builder.config.build {
+    if !builder.is_host_target(&target) {
         cfg.define("CMAKE_CROSSCOMPILING", "True");
 
         if target.contains("netbsd") {
@@ -1111,7 +1111,7 @@ impl Step for Lld {
             .define("LLVM_CMAKE_DIR", llvm_cmake_dir)
             .define("LLVM_INCLUDE_TESTS", "OFF");
 
-        if target != builder.config.build {
+        if !builder.is_host_target(&target) {
             // Use the host llvm-tblgen binary.
             cfg.define(
                 "LLVM_TABLEGEN_EXE",
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index c452f4cd6ae0a..259a6c4b1cb3d 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -2742,7 +2742,7 @@ impl Step for Crate {
             cargo
         } else {
             // Also prepare a sysroot for the target.
-            if builder.config.build != target {
+            if !builder.is_host_target(&target) {
                 builder.ensure(compile::Std::new(compiler, target).force_recompile(true));
                 builder.ensure(RemoteCopyLibs { compiler, target });
             }
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 6c8cda18548ef..8055a724e3396 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -329,7 +329,7 @@ than building it.
         if target.contains("musl") && !target.contains("unikraft") {
             // If this is a native target (host is also musl) and no musl-root is given,
             // fall back to the system toolchain in /usr before giving up
-            if build.musl_root(*target).is_none() && build.config.build == *target {
+            if build.musl_root(*target).is_none() && build.is_host_target(target) {
                 let target = build.config.target_config.entry(*target).or_default();
                 target.musl_root = Some("/usr".into());
             }
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index e564a4b975148..440c9e782da63 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -739,7 +739,7 @@ impl Build {
     /// Note that if LLVM is configured externally then the directory returned
     /// will likely be empty.
     fn llvm_out(&self, target: TargetSelection) -> PathBuf {
-        if self.config.llvm_from_ci && self.config.build == target {
+        if self.config.llvm_from_ci && self.is_host_target(&target) {
             self.config.ci_llvm_root()
         } else {
             self.out.join(target).join("llvm")
@@ -789,7 +789,7 @@ impl Build {
     fn is_system_llvm(&self, target: TargetSelection) -> bool {
         match self.config.target_config.get(&target) {
             Some(Target { llvm_config: Some(_), .. }) => {
-                let ci_llvm = self.config.llvm_from_ci && target == self.config.build;
+                let ci_llvm = self.config.llvm_from_ci && self.is_host_target(&target);
                 !ci_llvm
             }
             // We're building from the in-tree src/llvm-project sources.
@@ -1274,7 +1274,7 @@ Executed at: {executed_at}"#,
             // need to use CXX compiler as linker to resolve the exception functions
             // that are only existed in CXX libraries
             Some(self.cxx.borrow()[&target].path().into())
-        } else if target != self.config.build
+        } else if !self.is_host_target(&target)
             && helpers::use_host_linker(target)
             && !target.is_msvc()
         {
@@ -1925,6 +1925,11 @@ to download LLVM rather than building it.
         stream.reset().unwrap();
         result
     }
+
+    /// Checks if the given target is the same as the host target.
+    fn is_host_target(&self, target: &TargetSelection) -> bool {
+        &self.config.build == target
+    }
 }
 
 #[cfg(unix)]

From 61ba728b18f892d704d8a062027d81880f4958b8 Mon Sep 17 00:00:00 2001
From: onur-ozkan 
Date: Sun, 9 Feb 2025 11:51:15 +0300
Subject: [PATCH 28/36] add coverage for `Builder::is_host_target`

Signed-off-by: onur-ozkan 
---
 src/bootstrap/src/core/builder/tests.rs | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 994975ed5a8b4..5718c84f31486 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -1065,3 +1065,18 @@ fn test_prebuilt_llvm_config_path_resolution() {
         .join(exe("llvm-config", builder.config.build));
     assert_eq!(expected, actual);
 }
+
+fn test_is_host_target() {
+    let target1 = TargetSelection::from_user(TEST_TRIPLE_1);
+    let target2 = TargetSelection::from_user(TEST_TRIPLE_2);
+
+    for (target1, target2) in [(target1, target2), (target2, target1)] {
+        let mut config = configure("build", &[], &[]);
+        config.build = target1;
+        let build = Build::new(config);
+        let builder = Builder::new(&build);
+
+        assert!(builder.is_host_target(&target1));
+        assert!(!builder.is_host_target(&target2));
+    }
+}

From b594b9f4f54d05f7ac21d2c49c3093f89fd3ed1f Mon Sep 17 00:00:00 2001
From: Guillaume Gomez 
Date: Tue, 11 Feb 2025 18:17:46 +0100
Subject: [PATCH 29/36] Remove quotes around href in code line numbers

---
 src/librustdoc/html/highlight.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index fbe3a8d5ba4fa..15bf968e0fc77 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -249,7 +249,7 @@ fn write_scraped_line_number(out: &mut impl Write, line: u32, extra: &'static st
 fn write_line_number(out: &mut impl Write, line: u32, extra: &'static str) {
     // https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr
     // Do not show "1 2 3 4 5 ..." in web search results.
-    write!(out, "{extra}{line}",).unwrap();
+    write!(out, "{extra}{line}",).unwrap();
 }
 
 fn empty_line_number(out: &mut impl Write, _: u32, extra: &'static str) {

From acc7ddfd53a425b61d2beee8ea34726d7c99b553 Mon Sep 17 00:00:00 2001
From: onur-ozkan 
Date: Mon, 10 Feb 2025 11:25:35 +0300
Subject: [PATCH 30/36] rename `is_host_target` to `is_builder_target`

Signed-off-by: onur-ozkan 
---
 src/bootstrap/src/core/build_steps/compile.rs |  5 +++--
 src/bootstrap/src/core/build_steps/dist.rs    |  6 +++---
 src/bootstrap/src/core/build_steps/llvm.rs    |  6 +++---
 src/bootstrap/src/core/build_steps/test.rs    |  2 +-
 src/bootstrap/src/core/builder/tests.rs       |  7 ++++---
 src/bootstrap/src/core/sanity.rs              |  2 +-
 src/bootstrap/src/lib.rs                      | 10 +++++-----
 7 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 980383c381577..e0cc9c2cae90d 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -191,7 +191,7 @@ impl Step for Std {
         // The LLD wrappers and `rust-lld` are self-contained linking components that can be
         // necessary to link the stdlib on some targets. We'll also need to copy these binaries to
         // the `stage0-sysroot` to ensure the linker is found when bootstrapping on such a target.
-        if compiler.stage == 0 && builder.is_host_target(&compiler.host) {
+        if compiler.stage == 0 && builder.is_builder_target(&compiler.host) {
             // We want to copy the host `bin` folder within the `rustlib` folder in the sysroot.
             let src_sysroot_bin = builder
                 .rustc_snapshot_sysroot()
@@ -2312,7 +2312,8 @@ pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path)
     // FIXME: to make things simpler for now, limit this to the host and target where we know
     // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
     // cross-compiling. Expand this to other appropriate targets in the future.
-    if target != "x86_64-unknown-linux-gnu" || !builder.is_host_target(&target) || !path.exists() {
+    if target != "x86_64-unknown-linux-gnu" || !builder.is_builder_target(&target) || !path.exists()
+    {
         return;
     }
 
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 22c3be60499dd..ae3761a97e50f 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -582,7 +582,7 @@ impl Step for DebuggerScripts {
 fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
     // The only true set of target libraries came from the build triple, so
     // let's reduce redundant work by only producing archives from that host.
-    if !builder.is_host_target(&compiler.host) {
+    if !builder.is_builder_target(&compiler.host) {
         builder.info("\tskipping, not a build host");
         true
     } else {
@@ -637,7 +637,7 @@ fn copy_target_libs(
     for (path, dependency_type) in builder.read_stamp_file(stamp) {
         if dependency_type == DependencyType::TargetSelfContained {
             builder.copy_link(&path, &self_contained_dst.join(path.file_name().unwrap()));
-        } else if dependency_type == DependencyType::Target || builder.is_host_target(&target) {
+        } else if dependency_type == DependencyType::Target || builder.is_builder_target(&target) {
             builder.copy_link(&path, &dst.join(path.file_name().unwrap()));
         }
     }
@@ -786,7 +786,7 @@ impl Step for Analysis {
     fn run(self, builder: &Builder<'_>) -> Option {
         let compiler = self.compiler;
         let target = self.target;
-        if !builder.is_host_target(&compiler.host) {
+        if !builder.is_builder_target(&compiler.host) {
             return None;
         }
 
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 00485c5a23127..ee60dbef7b98e 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -516,7 +516,7 @@ impl Step for Llvm {
         }
 
         // https://llvm.org/docs/HowToCrossCompileLLVM.html
-        if !builder.is_host_target(&target) {
+        if !builder.is_builder_target(&target) {
             let LlvmResult { llvm_config, .. } =
                 builder.ensure(Llvm { target: builder.config.build });
             if !builder.config.dry_run() {
@@ -661,7 +661,7 @@ fn configure_cmake(
     }
     cfg.target(&target.triple).host(&builder.config.build.triple);
 
-    if !builder.is_host_target(&target) {
+    if !builder.is_builder_target(&target) {
         cfg.define("CMAKE_CROSSCOMPILING", "True");
 
         if target.contains("netbsd") {
@@ -1111,7 +1111,7 @@ impl Step for Lld {
             .define("LLVM_CMAKE_DIR", llvm_cmake_dir)
             .define("LLVM_INCLUDE_TESTS", "OFF");
 
-        if !builder.is_host_target(&target) {
+        if !builder.is_builder_target(&target) {
             // Use the host llvm-tblgen binary.
             cfg.define(
                 "LLVM_TABLEGEN_EXE",
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 259a6c4b1cb3d..509875a469f1f 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -2742,7 +2742,7 @@ impl Step for Crate {
             cargo
         } else {
             // Also prepare a sysroot for the target.
-            if !builder.is_host_target(&target) {
+            if !builder.is_builder_target(&target) {
                 builder.ensure(compile::Std::new(compiler, target).force_recompile(true));
                 builder.ensure(RemoteCopyLibs { compiler, target });
             }
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 5718c84f31486..a0be474ca3e39 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -1066,7 +1066,8 @@ fn test_prebuilt_llvm_config_path_resolution() {
     assert_eq!(expected, actual);
 }
 
-fn test_is_host_target() {
+#[test]
+fn test_is_builder_target() {
     let target1 = TargetSelection::from_user(TEST_TRIPLE_1);
     let target2 = TargetSelection::from_user(TEST_TRIPLE_2);
 
@@ -1076,7 +1077,7 @@ fn test_is_host_target() {
         let build = Build::new(config);
         let builder = Builder::new(&build);
 
-        assert!(builder.is_host_target(&target1));
-        assert!(!builder.is_host_target(&target2));
+        assert!(builder.is_builder_target(&target1));
+        assert!(!builder.is_builder_target(&target2));
     }
 }
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 8055a724e3396..9e4a0816e0d48 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -329,7 +329,7 @@ than building it.
         if target.contains("musl") && !target.contains("unikraft") {
             // If this is a native target (host is also musl) and no musl-root is given,
             // fall back to the system toolchain in /usr before giving up
-            if build.musl_root(*target).is_none() && build.is_host_target(target) {
+            if build.musl_root(*target).is_none() && build.is_builder_target(target) {
                 let target = build.config.target_config.entry(*target).or_default();
                 target.musl_root = Some("/usr".into());
             }
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 440c9e782da63..665ab117002e0 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -739,7 +739,7 @@ impl Build {
     /// Note that if LLVM is configured externally then the directory returned
     /// will likely be empty.
     fn llvm_out(&self, target: TargetSelection) -> PathBuf {
-        if self.config.llvm_from_ci && self.is_host_target(&target) {
+        if self.config.llvm_from_ci && self.is_builder_target(&target) {
             self.config.ci_llvm_root()
         } else {
             self.out.join(target).join("llvm")
@@ -789,7 +789,7 @@ impl Build {
     fn is_system_llvm(&self, target: TargetSelection) -> bool {
         match self.config.target_config.get(&target) {
             Some(Target { llvm_config: Some(_), .. }) => {
-                let ci_llvm = self.config.llvm_from_ci && self.is_host_target(&target);
+                let ci_llvm = self.config.llvm_from_ci && self.is_builder_target(&target);
                 !ci_llvm
             }
             // We're building from the in-tree src/llvm-project sources.
@@ -1274,7 +1274,7 @@ Executed at: {executed_at}"#,
             // need to use CXX compiler as linker to resolve the exception functions
             // that are only existed in CXX libraries
             Some(self.cxx.borrow()[&target].path().into())
-        } else if !self.is_host_target(&target)
+        } else if !self.is_builder_target(&target)
             && helpers::use_host_linker(target)
             && !target.is_msvc()
         {
@@ -1926,8 +1926,8 @@ to download LLVM rather than building it.
         result
     }
 
-    /// Checks if the given target is the same as the host target.
-    fn is_host_target(&self, target: &TargetSelection) -> bool {
+    /// Checks if the given target is the same as the builder target.
+    fn is_builder_target(&self, target: &TargetSelection) -> bool {
         &self.config.build == target
     }
 }

From 1b98d0ed13e4a8ff8d94e6aee0f11fab07d6139a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
Date: Tue, 31 Dec 2024 18:51:36 +0000
Subject: [PATCH 31/36] Explain that in paths generics can't be set on both the
 enum and the variant

```
error[E0109]: type arguments are not allowed on enum `Enum` and tuple variant `TSVariant`
  --> $DIR/enum-variant-generic-args.rs:54:12
   |
LL |     Enum::<()>::TSVariant::<()>(());
   |     ----   ^^   ---------   ^^ type argument not allowed
   |     |           |
   |     |           not allowed on tuple variant `TSVariant`
   |     not allowed on enum `Enum`
   |
   = note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
help: remove the generics arguments from one of the path segments
   |
LL -     Enum::<()>::TSVariant::<()>(());
LL +     Enum::<()>::TSVariant(());
   |
```

Fix #93993.
---
 compiler/rustc_hir_analysis/src/collect.rs    |  7 ++-
 .../src/hir_ty_lowering/errors.rs             | 58 +++++++++++++------
 .../src/hir_ty_lowering/mod.rs                |  4 +-
 .../rustc_hir_typeck/src/fn_ctxt/_impl.rs     |  7 ++-
 .../enum-variant-generic-args.rs              |  6 +-
 .../enum-variant-generic-args.stderr          | 54 ++++++++++++-----
 6 files changed, 94 insertions(+), 42 deletions(-)

diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index ce7319f656190..126237799562f 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -614,9 +614,10 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
             if !infer_replacements.is_empty() {
                 diag.multipart_suggestion(
                     format!(
-                    "try replacing `_` with the type{} in the corresponding trait method signature",
-                    rustc_errors::pluralize!(infer_replacements.len()),
-                ),
+                        "try replacing `_` with the type{} in the corresponding trait method \
+                         signature",
+                        rustc_errors::pluralize!(infer_replacements.len()),
+                    ),
                     infer_replacements,
                     Applicability::MachineApplicable,
                 );
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 79aa2f4b8ccd2..66746dfc3875d 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -6,7 +6,7 @@ use rustc_errors::{
     Applicability, Diag, ErrorGuaranteed, MultiSpan, listify, pluralize, struct_span_code_err,
 };
 use rustc_hir as hir;
-use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_middle::bug;
 use rustc_middle::ty::fast_reject::{TreatParams, simplify_type};
@@ -1027,7 +1027,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         &self,
         segments: impl Iterator> + Clone,
         args_visitors: impl Iterator> + Clone,
-        err_extend: GenericsArgsErrExtend<'_>,
+        err_extend: GenericsArgsErrExtend<'a>,
     ) -> ErrorGuaranteed {
         #[derive(PartialEq, Eq, Hash)]
         enum ProhibitGenericsArg {
@@ -1047,23 +1047,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             };
         });
 
+        let segments: Vec<_> = match err_extend {
+            GenericsArgsErrExtend::DefVariant(segments) => segments.iter().collect(),
+            _ => segments.collect(),
+        };
         let types_and_spans: Vec<_> = segments
-            .clone()
+            .iter()
             .flat_map(|segment| {
                 if segment.args().args.is_empty() {
                     None
                 } else {
                     Some((
                         match segment.res {
-                            hir::def::Res::PrimTy(ty) => {
+                            Res::PrimTy(ty) => {
                                 format!("{} `{}`", segment.res.descr(), ty.name())
                             }
-                            hir::def::Res::Def(_, def_id)
+                            Res::Def(_, def_id)
                                 if let Some(name) = self.tcx().opt_item_name(def_id) =>
                             {
                                 format!("{} `{name}`", segment.res.descr())
                             }
-                            hir::def::Res::Err => "this type".to_string(),
+                            Res::Err => "this type".to_string(),
                             _ => segment.res.descr().to_string(),
                         },
                         segment.ident.span,
@@ -1074,11 +1078,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let this_type = listify(&types_and_spans, |(t, _)| t.to_string())
             .expect("expected one segment to deny");
 
-        let arg_spans: Vec = segments
-            .clone()
-            .flat_map(|segment| segment.args().args)
-            .map(|arg| arg.span())
-            .collect();
+        let arg_spans: Vec =
+            segments.iter().flat_map(|segment| segment.args().args).map(|arg| arg.span()).collect();
 
         let mut kinds = Vec::with_capacity(4);
         prohibit_args.iter().for_each(|arg| match arg {
@@ -1103,7 +1104,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         for (what, span) in types_and_spans {
             err.span_label(span, format!("not allowed on {what}"));
         }
-        generics_args_err_extend(self.tcx(), segments, &mut err, err_extend);
+        generics_args_err_extend(self.tcx(), segments.into_iter(), &mut err, err_extend);
         err.emit()
     }
 
@@ -1400,7 +1401,7 @@ pub enum GenericsArgsErrExtend<'tcx> {
     },
     SelfTyParam(Span),
     Param(DefId),
-    DefVariant,
+    DefVariant(&'tcx [hir::PathSegment<'tcx>]),
     None,
 }
 
@@ -1408,7 +1409,7 @@ fn generics_args_err_extend<'a>(
     tcx: TyCtxt<'_>,
     segments: impl Iterator> + Clone,
     err: &mut Diag<'_>,
-    err_extend: GenericsArgsErrExtend<'_>,
+    err_extend: GenericsArgsErrExtend<'a>,
 ) {
     match err_extend {
         GenericsArgsErrExtend::EnumVariant { qself, assoc_segment, adt_def } => {
@@ -1496,6 +1497,32 @@ fn generics_args_err_extend<'a>(
             ];
             err.multipart_suggestion_verbose(msg, suggestion, Applicability::MaybeIncorrect);
         }
+        GenericsArgsErrExtend::DefVariant(segments) => {
+            let args: Vec = segments
+                .iter()
+                .filter_map(|segment| match segment.res {
+                    Res::Def(
+                        DefKind::Ctor(CtorOf::Variant, _) | DefKind::Variant | DefKind::Enum,
+                        _,
+                    ) => segment.args().span_ext().map(|s| s.with_lo(segment.ident.span.hi())),
+                    _ => None,
+                })
+                .collect();
+            if args.len() > 1
+                && let Some(span) = args.into_iter().last()
+            {
+                let msg = "generic arguments are not allowed on both an enum and its variant's \
+                           path segments simultaneously; they are only valid in one place or the \
+                           other";
+                err.note(msg);
+                err.span_suggestion_verbose(
+                    span,
+                    "remove the generics arguments from one of the path segments",
+                    String::new(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+        }
         GenericsArgsErrExtend::PrimTy(prim_ty) => {
             let name = prim_ty.name_str();
             for segment in segments {
@@ -1512,9 +1539,6 @@ fn generics_args_err_extend<'a>(
         GenericsArgsErrExtend::OpaqueTy => {
             err.note("`impl Trait` types can't have type parameters");
         }
-        GenericsArgsErrExtend::DefVariant => {
-            err.note("enum variants can't have type parameters");
-        }
         GenericsArgsErrExtend::Param(def_id) => {
             let span = tcx.def_ident_span(def_id).unwrap();
             let kind = tcx.def_descr(def_id);
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index ffddf6f73aaf0..aef5c7aa38f1d 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -1694,7 +1694,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     pub fn prohibit_generic_args<'a>(
         &self,
         segments: impl Iterator> + Clone,
-        err_extend: GenericsArgsErrExtend<'_>,
+        err_extend: GenericsArgsErrExtend<'a>,
     ) -> Result<(), ErrorGuaranteed> {
         let args_visitors = segments.clone().flat_map(|segment| segment.args().args);
         let mut result = Ok(());
@@ -1911,7 +1911,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     path.segments.iter().enumerate().filter_map(|(index, seg)| {
                         if !indices.contains(&index) { Some(seg) } else { None }
                     }),
-                    GenericsArgsErrExtend::DefVariant,
+                    GenericsArgsErrExtend::DefVariant(&path.segments),
                 );
 
                 let GenericPathSegment(def_id, index) = generic_segments.last().unwrap();
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 6bb8cf5f33159..e74ffeff343a2 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1043,12 +1043,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let mut user_self_ty = None;
         let mut is_alias_variant_ctor = false;
+        let mut err_extend = GenericsArgsErrExtend::None;
         match res {
             Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) if let Some(self_ty) = self_ty => {
                 let adt_def = self_ty.normalized.ty_adt_def().unwrap();
                 user_self_ty =
                     Some(UserSelfTy { impl_def_id: adt_def.did(), self_ty: self_ty.raw });
                 is_alias_variant_ctor = true;
+                err_extend = GenericsArgsErrExtend::DefVariant(segments);
+            }
+            Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
+                err_extend = GenericsArgsErrExtend::DefVariant(segments);
             }
             Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
                 let assoc_item = tcx.associated_item(def_id);
@@ -1095,7 +1100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             segments.iter().enumerate().filter_map(|(index, seg)| {
                 if !indices.contains(&index) || is_alias_variant_ctor { Some(seg) } else { None }
             }),
-            GenericsArgsErrExtend::None,
+            err_extend,
         );
 
         if let Res::Local(hid) = res {
diff --git a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
index 759a7fd7e05a9..e4897005a5c1a 100644
--- a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
+++ b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
@@ -52,7 +52,7 @@ fn main() {
     // Tuple struct variant
 
     Enum::<()>::TSVariant::<()>(());
-    //~^ ERROR type arguments are not allowed on tuple variant `TSVariant` [E0109]
+    //~^ ERROR type arguments are not allowed on enum `Enum` and tuple variant `TSVariant` [E0109]
 
     Alias::TSVariant::<()>(());
     //~^ ERROR type arguments are not allowed on this type [E0109]
@@ -70,7 +70,7 @@ fn main() {
     // Struct variant
 
     Enum::<()>::SVariant::<()> { v: () };
-    //~^ ERROR type arguments are not allowed on variant `SVariant` [E0109]
+    //~^ ERROR type arguments are not allowed on enum `Enum` and variant `SVariant` [E0109]
 
     Alias::SVariant::<()> { v: () };
     //~^ ERROR type arguments are not allowed on this type [E0109]
@@ -88,7 +88,7 @@ fn main() {
     // Unit variant
 
     Enum::<()>::UVariant::<()>;
-    //~^ ERROR type arguments are not allowed on unit variant `UVariant` [E0109]
+    //~^ ERROR type arguments are not allowed on enum `Enum` and unit variant `UVariant` [E0109]
 
     Alias::UVariant::<()>;
     //~^ ERROR type arguments are not allowed on this type [E0109]
diff --git a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
index 8caf17ae2da5a..3f98a1eb5c09a 100644
--- a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
+++ b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
@@ -278,13 +278,21 @@ LL |         Self::<()>::UVariant::<()>;
    |                     |
    |                     not allowed on this type
 
-error[E0109]: type arguments are not allowed on tuple variant `TSVariant`
-  --> $DIR/enum-variant-generic-args.rs:54:29
+error[E0109]: type arguments are not allowed on enum `Enum` and tuple variant `TSVariant`
+  --> $DIR/enum-variant-generic-args.rs:54:12
    |
 LL |     Enum::<()>::TSVariant::<()>(());
-   |                 ---------   ^^ type argument not allowed
-   |                 |
-   |                 not allowed on tuple variant `TSVariant`
+   |     ----   ^^   ---------   ^^ type argument not allowed
+   |     |           |
+   |     |           not allowed on tuple variant `TSVariant`
+   |     not allowed on enum `Enum`
+   |
+   = note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
+help: remove the generics arguments from one of the path segments
+   |
+LL -     Enum::<()>::TSVariant::<()>(());
+LL +     Enum::<()>::TSVariant(());
+   |
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/enum-variant-generic-args.rs:57:24
@@ -346,15 +354,21 @@ LL |     AliasFixed::<()>::TSVariant::<()>(());
    |                       |
    |                       not allowed on this type
 
-error[E0109]: type arguments are not allowed on variant `SVariant`
-  --> $DIR/enum-variant-generic-args.rs:72:28
+error[E0109]: type arguments are not allowed on enum `Enum` and variant `SVariant`
+  --> $DIR/enum-variant-generic-args.rs:72:12
    |
 LL |     Enum::<()>::SVariant::<()> { v: () };
-   |                 --------   ^^ type argument not allowed
-   |                 |
-   |                 not allowed on variant `SVariant`
+   |     ----   ^^   --------   ^^ type argument not allowed
+   |     |           |
+   |     |           not allowed on variant `SVariant`
+   |     not allowed on enum `Enum`
+   |
+   = note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
+help: remove the generics arguments from one of the path segments
+   |
+LL -     Enum::<()>::SVariant::<()> { v: () };
+LL +     Enum::<()>::SVariant { v: () };
    |
-   = note: enum variants can't have type parameters
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/enum-variant-generic-args.rs:75:23
@@ -444,13 +458,21 @@ LL -     AliasFixed::<()>::SVariant::<()> { v: () };
 LL +     AliasFixed::<()>::SVariant { v: () };
    |
 
-error[E0109]: type arguments are not allowed on unit variant `UVariant`
-  --> $DIR/enum-variant-generic-args.rs:90:28
+error[E0109]: type arguments are not allowed on enum `Enum` and unit variant `UVariant`
+  --> $DIR/enum-variant-generic-args.rs:90:12
    |
 LL |     Enum::<()>::UVariant::<()>;
-   |                 --------   ^^ type argument not allowed
-   |                 |
-   |                 not allowed on unit variant `UVariant`
+   |     ----   ^^   --------   ^^ type argument not allowed
+   |     |           |
+   |     |           not allowed on unit variant `UVariant`
+   |     not allowed on enum `Enum`
+   |
+   = note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
+help: remove the generics arguments from one of the path segments
+   |
+LL -     Enum::<()>::UVariant::<()>;
+LL +     Enum::<()>::UVariant;
+   |
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/enum-variant-generic-args.rs:93:23

From 23daa8c724cccc4ef75de60d271a50ef193abf0f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
Date: Tue, 11 Feb 2025 23:47:56 +0000
Subject: [PATCH 32/36] Remove some the spans pointing at the enum in the path
 and its generic args

```
error[E0109]: type arguments are not allowed on tuple variant `TSVariant`
  --> $DIR/enum-variant-generic-args.rs:54:29
   |
LL |     Enum::<()>::TSVariant::<()>(());
   |                 ---------   ^^ type argument not allowed
   |                 |
   |                 not allowed on tuple variant `TSVariant`
   |
   = note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
help: remove the generics arguments from one of the path segments
   |
LL -     Enum::<()>::TSVariant::<()>(());
LL +     Enum::<()>::TSVariant(());
   |
```
---
 .../src/hir_ty_lowering/errors.rs             | 13 +++-----
 .../enum-variant-generic-args.rs              |  6 ++--
 .../enum-variant-generic-args.stderr          | 33 +++++++++----------
 3 files changed, 23 insertions(+), 29 deletions(-)

diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 66746dfc3875d..7eb982a31798c 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -1047,10 +1047,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             };
         });
 
-        let segments: Vec<_> = match err_extend {
-            GenericsArgsErrExtend::DefVariant(segments) => segments.iter().collect(),
-            _ => segments.collect(),
-        };
+        let segments: Vec<_> = segments.collect();
         let types_and_spans: Vec<_> = segments
             .iter()
             .flat_map(|segment| {
@@ -1511,10 +1508,10 @@ fn generics_args_err_extend<'a>(
             if args.len() > 1
                 && let Some(span) = args.into_iter().last()
             {
-                let msg = "generic arguments are not allowed on both an enum and its variant's \
-                           path segments simultaneously; they are only valid in one place or the \
-                           other";
-                err.note(msg);
+                err.note(
+                    "generic arguments are not allowed on both an enum and its variant's path \
+                     segments simultaneously; they are only valid in one place or the other",
+                );
                 err.span_suggestion_verbose(
                     span,
                     "remove the generics arguments from one of the path segments",
diff --git a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
index e4897005a5c1a..759a7fd7e05a9 100644
--- a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
+++ b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
@@ -52,7 +52,7 @@ fn main() {
     // Tuple struct variant
 
     Enum::<()>::TSVariant::<()>(());
-    //~^ ERROR type arguments are not allowed on enum `Enum` and tuple variant `TSVariant` [E0109]
+    //~^ ERROR type arguments are not allowed on tuple variant `TSVariant` [E0109]
 
     Alias::TSVariant::<()>(());
     //~^ ERROR type arguments are not allowed on this type [E0109]
@@ -70,7 +70,7 @@ fn main() {
     // Struct variant
 
     Enum::<()>::SVariant::<()> { v: () };
-    //~^ ERROR type arguments are not allowed on enum `Enum` and variant `SVariant` [E0109]
+    //~^ ERROR type arguments are not allowed on variant `SVariant` [E0109]
 
     Alias::SVariant::<()> { v: () };
     //~^ ERROR type arguments are not allowed on this type [E0109]
@@ -88,7 +88,7 @@ fn main() {
     // Unit variant
 
     Enum::<()>::UVariant::<()>;
-    //~^ ERROR type arguments are not allowed on enum `Enum` and unit variant `UVariant` [E0109]
+    //~^ ERROR type arguments are not allowed on unit variant `UVariant` [E0109]
 
     Alias::UVariant::<()>;
     //~^ ERROR type arguments are not allowed on this type [E0109]
diff --git a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
index 3f98a1eb5c09a..5039ae8f288ee 100644
--- a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
+++ b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
@@ -278,14 +278,13 @@ LL |         Self::<()>::UVariant::<()>;
    |                     |
    |                     not allowed on this type
 
-error[E0109]: type arguments are not allowed on enum `Enum` and tuple variant `TSVariant`
-  --> $DIR/enum-variant-generic-args.rs:54:12
+error[E0109]: type arguments are not allowed on tuple variant `TSVariant`
+  --> $DIR/enum-variant-generic-args.rs:54:29
    |
 LL |     Enum::<()>::TSVariant::<()>(());
-   |     ----   ^^   ---------   ^^ type argument not allowed
-   |     |           |
-   |     |           not allowed on tuple variant `TSVariant`
-   |     not allowed on enum `Enum`
+   |                 ---------   ^^ type argument not allowed
+   |                 |
+   |                 not allowed on tuple variant `TSVariant`
    |
    = note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
 help: remove the generics arguments from one of the path segments
@@ -354,14 +353,13 @@ LL |     AliasFixed::<()>::TSVariant::<()>(());
    |                       |
    |                       not allowed on this type
 
-error[E0109]: type arguments are not allowed on enum `Enum` and variant `SVariant`
-  --> $DIR/enum-variant-generic-args.rs:72:12
+error[E0109]: type arguments are not allowed on variant `SVariant`
+  --> $DIR/enum-variant-generic-args.rs:72:28
    |
 LL |     Enum::<()>::SVariant::<()> { v: () };
-   |     ----   ^^   --------   ^^ type argument not allowed
-   |     |           |
-   |     |           not allowed on variant `SVariant`
-   |     not allowed on enum `Enum`
+   |                 --------   ^^ type argument not allowed
+   |                 |
+   |                 not allowed on variant `SVariant`
    |
    = note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
 help: remove the generics arguments from one of the path segments
@@ -458,14 +456,13 @@ LL -     AliasFixed::<()>::SVariant::<()> { v: () };
 LL +     AliasFixed::<()>::SVariant { v: () };
    |
 
-error[E0109]: type arguments are not allowed on enum `Enum` and unit variant `UVariant`
-  --> $DIR/enum-variant-generic-args.rs:90:12
+error[E0109]: type arguments are not allowed on unit variant `UVariant`
+  --> $DIR/enum-variant-generic-args.rs:90:28
    |
 LL |     Enum::<()>::UVariant::<()>;
-   |     ----   ^^   --------   ^^ type argument not allowed
-   |     |           |
-   |     |           not allowed on unit variant `UVariant`
-   |     not allowed on enum `Enum`
+   |                 --------   ^^ type argument not allowed
+   |                 |
+   |                 not allowed on unit variant `UVariant`
    |
    = note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
 help: remove the generics arguments from one of the path segments

From 32fd1a7b7205d1f8ccf168c22dada83ea38e3adb Mon Sep 17 00:00:00 2001
From: Jubilee Young 
Date: Tue, 11 Feb 2025 19:40:29 -0800
Subject: [PATCH 33/36] compiler: replace ExternAbi::name calls with formatters

Most of these just format the ABI string, so... just format ExternAbi?
This makes it more consistent and less jank when we can do it.
---
 compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs |  4 +---
 compiler/rustc_errors/src/diagnostic_impls.rs          |  1 +
 compiler/rustc_hir_analysis/messages.ftl               |  8 ++++----
 compiler/rustc_hir_analysis/src/errors.rs              |  5 +++--
 .../rustc_hir_analysis/src/hir_ty_lowering/cmse.rs     | 10 ++++------
 compiler/rustc_lint/src/early/diagnostics.rs           |  3 +--
 compiler/rustc_lint/src/lints.rs                       |  5 +++--
 .../src/function_item_references.rs                    |  7 +------
 .../ui/link-native-libs/suggest-libname-only-1.stderr  |  2 +-
 .../ui/link-native-libs/suggest-libname-only-2.stderr  |  2 +-
 tests/ui/lint/cli-lint-override.forbid_warn.stderr     |  2 +-
 tests/ui/lint/cli-lint-override.force_warn_deny.stderr |  2 +-
 tests/ui/lint/cli-lint-override.warn_deny.stderr       |  2 +-
 tests/ui/parser/bad-lit-suffixes.stderr                |  4 ++--
 tests/ui/parser/lit-err-in-macro.stderr                |  2 +-
 tests/ui/proc-macro/inner-attrs.stderr                 |  2 +-
 16 files changed, 27 insertions(+), 34 deletions(-)

diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 051753715913a..53953b089c613 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -367,9 +367,7 @@ fn push_debuginfo_type_name<'tcx>(
                 output.push_str(sig.safety.prefix_str());
 
                 if sig.abi != rustc_abi::ExternAbi::Rust {
-                    output.push_str("extern \"");
-                    output.push_str(sig.abi.name());
-                    output.push_str("\" ");
+                    let _ = write!(output, "extern {} ", sig.abi);
                 }
 
                 output.push_str("fn(");
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index 14baf7554bcf6..7f383946c1463 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -93,6 +93,7 @@ into_diag_arg_using_display!(
     SplitDebuginfo,
     ExitStatus,
     ErrCode,
+    rustc_abi::ExternAbi,
 );
 
 impl IntoDiagArg for rustc_type_ir::TraitRef {
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 258267c5ca929..d7b43a8126d8f 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -72,17 +72,17 @@ hir_analysis_cmse_entry_generic =
     functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
 
 hir_analysis_cmse_inputs_stack_spill =
-    arguments for `"{$abi_name}"` function too large to pass via registers
+    arguments for `{$abi}` function too large to pass via registers
     .label = {$plural ->
         [false] this argument doesn't
         *[true] these arguments don't
     } fit in the available registers
-    .note = functions with the `"{$abi_name}"` ABI must pass all their arguments via the 4 32-bit available argument registers
+    .note = functions with the `{$abi}` ABI must pass all their arguments via the 4 32-bit available argument registers
 
 hir_analysis_cmse_output_stack_spill =
-    return value of `"{$abi_name}"` function too large to pass via registers
+    return value of `{$abi}` function too large to pass via registers
     .label = this type doesn't fit in the available registers
-    .note1 = functions with the `"{$abi_name}"` ABI must pass their result via the available return registers
+    .note1 = functions with the `{$abi}` ABI must pass their result via the available return registers
     .note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
 
 hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 12750543f4bf7..0d0fe9d981f95 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1,5 +1,6 @@
 //! Errors emitted by `rustc_hir_analysis`.
 
+use rustc_abi::ExternAbi;
 use rustc_errors::codes::*;
 use rustc_errors::{
     Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan,
@@ -1689,7 +1690,7 @@ pub(crate) struct CmseInputsStackSpill {
     #[label]
     pub span: Span,
     pub plural: bool,
-    pub abi_name: &'static str,
+    pub abi: ExternAbi,
 }
 
 #[derive(Diagnostic)]
@@ -1700,7 +1701,7 @@ pub(crate) struct CmseOutputStackSpill {
     #[primary_span]
     #[label]
     pub span: Span,
-    pub abi_name: &'static str,
+    pub abi: ExternAbi,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
index 4c8f2735b9795..5fed2e352879c 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
@@ -17,8 +17,6 @@ pub(crate) fn validate_cmse_abi<'tcx>(
     abi: ExternAbi,
     fn_sig: ty::PolyFnSig<'tcx>,
 ) {
-    let abi_name = abi.name();
-
     match abi {
         ExternAbi::CCmseNonSecureCall => {
             let hir_node = tcx.hir_node(hir_id);
@@ -56,7 +54,7 @@ pub(crate) fn validate_cmse_abi<'tcx>(
                         .to(bare_fn_ty.decl.inputs[index].span)
                         .to(bare_fn_ty.decl.inputs.last().unwrap().span);
                     let plural = bare_fn_ty.param_names.len() - index != 1;
-                    dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi_name });
+                    dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi });
                 }
                 Err(layout_err) => {
                     if should_emit_generic_error(abi, layout_err) {
@@ -69,7 +67,7 @@ pub(crate) fn validate_cmse_abi<'tcx>(
                 Ok(true) => {}
                 Ok(false) => {
                     let span = bare_fn_ty.decl.output.span();
-                    dcx.emit_err(errors::CmseOutputStackSpill { span, abi_name });
+                    dcx.emit_err(errors::CmseOutputStackSpill { span, abi });
                 }
                 Err(layout_err) => {
                     if should_emit_generic_error(abi, layout_err) {
@@ -92,7 +90,7 @@ pub(crate) fn validate_cmse_abi<'tcx>(
                     //                                      ^^^^^^
                     let span = decl.inputs[index].span.to(decl.inputs.last().unwrap().span);
                     let plural = decl.inputs.len() - index != 1;
-                    dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi_name });
+                    dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi });
                 }
                 Err(layout_err) => {
                     if should_emit_generic_error(abi, layout_err) {
@@ -105,7 +103,7 @@ pub(crate) fn validate_cmse_abi<'tcx>(
                 Ok(true) => {}
                 Ok(false) => {
                     let span = decl.output.span();
-                    dcx.emit_err(errors::CmseOutputStackSpill { span, abi_name });
+                    dcx.emit_err(errors::CmseOutputStackSpill { span, abi });
                 }
                 Err(layout_err) => {
                     if should_emit_generic_error(abi, layout_err) {
diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs
index 92dbc76a7b5ec..aeb5a03a4f7e3 100644
--- a/compiler/rustc_lint/src/early/diagnostics.rs
+++ b/compiler/rustc_lint/src/early/diagnostics.rs
@@ -160,8 +160,7 @@ pub(super) fn decorate_lint(
             .decorate_lint(diag);
         }
         BuiltinLintDiag::MissingAbi(label_span, default_abi) => {
-            lints::MissingAbi { span: label_span, default_abi: default_abi.name() }
-                .decorate_lint(diag);
+            lints::MissingAbi { span: label_span, default_abi }.decorate_lint(diag);
         }
         BuiltinLintDiag::LegacyDeriveHelpers(label_span) => {
             lints::LegacyDeriveHelpers { span: label_span }.decorate_lint(diag);
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 09b0e1ed8bdba..368d36bfdd0b2 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2,6 +2,7 @@
 #![allow(rustc::untranslatable_diagnostic)]
 use std::num::NonZero;
 
+use rustc_abi::ExternAbi;
 use rustc_errors::codes::*;
 use rustc_errors::{
     Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString, ElidedLifetimeInPathSubdiag,
@@ -2833,9 +2834,9 @@ pub(crate) struct PatternsInFnsWithoutBodySub {
 #[derive(LintDiagnostic)]
 #[diag(lint_extern_without_abi)]
 pub(crate) struct MissingAbi {
-    #[suggestion(code = "extern \"{default_abi}\"", applicability = "machine-applicable")]
+    #[suggestion(code = "extern {default_abi}", applicability = "machine-applicable")]
     pub span: Span,
-    pub default_abi: &'static str,
+    pub default_abi: ExternAbi,
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs
index 7e88925b2e1b6..73e47bb79f0bf 100644
--- a/compiler/rustc_mir_transform/src/function_item_references.rs
+++ b/compiler/rustc_mir_transform/src/function_item_references.rs
@@ -161,12 +161,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
         let unsafety = fn_sig.safety().prefix_str();
         let abi = match fn_sig.abi() {
             ExternAbi::Rust => String::from(""),
-            other_abi => {
-                let mut s = String::from("extern \"");
-                s.push_str(other_abi.name());
-                s.push_str("\" ");
-                s
-            }
+            other_abi => format!("extern {other_abi} "),
         };
         let ident = self.tcx.item_ident(fn_id);
         let ty_params = fn_args.types().map(|ty| format!("{ty}"));
diff --git a/tests/ui/link-native-libs/suggest-libname-only-1.stderr b/tests/ui/link-native-libs/suggest-libname-only-1.stderr
index aae8f7de966a0..47f7d92c9f9e2 100644
--- a/tests/ui/link-native-libs/suggest-libname-only-1.stderr
+++ b/tests/ui/link-native-libs/suggest-libname-only-1.stderr
@@ -2,7 +2,7 @@ warning: extern declarations without an explicit ABI are deprecated
   --> $DIR/suggest-libname-only-1.rs:7:1
    |
 LL | extern { }
-   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
    |
    = note: `#[warn(missing_abi)]` on by default
 
diff --git a/tests/ui/link-native-libs/suggest-libname-only-2.stderr b/tests/ui/link-native-libs/suggest-libname-only-2.stderr
index a2adaee3f97f5..a2d8f4c8191bf 100644
--- a/tests/ui/link-native-libs/suggest-libname-only-2.stderr
+++ b/tests/ui/link-native-libs/suggest-libname-only-2.stderr
@@ -2,7 +2,7 @@ warning: extern declarations without an explicit ABI are deprecated
   --> $DIR/suggest-libname-only-2.rs:7:1
    |
 LL | extern { }
-   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
    |
    = note: `#[warn(missing_abi)]` on by default
 
diff --git a/tests/ui/lint/cli-lint-override.forbid_warn.stderr b/tests/ui/lint/cli-lint-override.forbid_warn.stderr
index 169be997b48c6..fb8779ad4f15d 100644
--- a/tests/ui/lint/cli-lint-override.forbid_warn.stderr
+++ b/tests/ui/lint/cli-lint-override.forbid_warn.stderr
@@ -2,7 +2,7 @@ error: extern declarations without an explicit ABI are deprecated
   --> $DIR/cli-lint-override.rs:12:1
    |
 LL | extern fn foo() {}
-   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
    |
    = note: requested on the command line with `-F missing-abi`
 
diff --git a/tests/ui/lint/cli-lint-override.force_warn_deny.stderr b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr
index 574f2ca66a420..10fc13e3f52f8 100644
--- a/tests/ui/lint/cli-lint-override.force_warn_deny.stderr
+++ b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr
@@ -2,7 +2,7 @@ warning: extern declarations without an explicit ABI are deprecated
   --> $DIR/cli-lint-override.rs:12:1
    |
 LL | extern fn foo() {}
-   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
    |
    = note: requested on the command line with `--force-warn missing-abi`
 
diff --git a/tests/ui/lint/cli-lint-override.warn_deny.stderr b/tests/ui/lint/cli-lint-override.warn_deny.stderr
index bfec37ada95e5..979ca22324f1e 100644
--- a/tests/ui/lint/cli-lint-override.warn_deny.stderr
+++ b/tests/ui/lint/cli-lint-override.warn_deny.stderr
@@ -2,7 +2,7 @@ error: extern declarations without an explicit ABI are deprecated
   --> $DIR/cli-lint-override.rs:12:1
    |
 LL | extern fn foo() {}
-   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
    |
    = note: requested on the command line with `-D missing-abi`
 
diff --git a/tests/ui/parser/bad-lit-suffixes.stderr b/tests/ui/parser/bad-lit-suffixes.stderr
index 704f7363e81c2..d6b50b0e0d1fe 100644
--- a/tests/ui/parser/bad-lit-suffixes.stderr
+++ b/tests/ui/parser/bad-lit-suffixes.stderr
@@ -55,7 +55,7 @@ warning: extern declarations without an explicit ABI are deprecated
   --> $DIR/bad-lit-suffixes.rs:3:1
    |
 LL | extern
-   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
    |
    = note: `#[warn(missing_abi)]` on by default
 
@@ -63,7 +63,7 @@ warning: extern declarations without an explicit ABI are deprecated
   --> $DIR/bad-lit-suffixes.rs:7:1
    |
 LL | extern
-   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
 
 error: suffixes on string literals are invalid
   --> $DIR/bad-lit-suffixes.rs:12:5
diff --git a/tests/ui/parser/lit-err-in-macro.stderr b/tests/ui/parser/lit-err-in-macro.stderr
index fc2603d0b104c..9422f22f9c8fe 100644
--- a/tests/ui/parser/lit-err-in-macro.stderr
+++ b/tests/ui/parser/lit-err-in-macro.stderr
@@ -8,7 +8,7 @@ warning: extern declarations without an explicit ABI are deprecated
   --> $DIR/lit-err-in-macro.rs:3:9
    |
 LL |         extern $abi fn f() {}
-   |         ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   |         ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
 ...
 LL | f!("Foo"__);
    | ----------- in this macro invocation
diff --git a/tests/ui/proc-macro/inner-attrs.stderr b/tests/ui/proc-macro/inner-attrs.stderr
index 3ab180be821a9..8b5fec1b4c37e 100644
--- a/tests/ui/proc-macro/inner-attrs.stderr
+++ b/tests/ui/proc-macro/inner-attrs.stderr
@@ -26,7 +26,7 @@ warning: extern declarations without an explicit ABI are deprecated
   --> $DIR/inner-attrs.rs:82:1
    |
 LL | extern {
-   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
    |
    = note: `#[warn(missing_abi)]` on by default
 

From 2e2afff50cd96939627965efb1198683abcfaa2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= 
Date: Wed, 12 Feb 2025 09:51:14 +0100
Subject: [PATCH 34/36] Put kobzol back to review rotation

---
 triagebot.toml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/triagebot.toml b/triagebot.toml
index 169a6121615ac..db86b6debbfe7 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1043,7 +1043,6 @@ users_on_vacation = [
     "jyn514",
     "nnethercote",
     "workingjubilee",
-    "kobzol",
 ]
 
 [[assign.warn_non_default_branch.exceptions]]

From 0ca8353651e6e100224001697f9bb93f0380b037 Mon Sep 17 00:00:00 2001
From: eyelash 
Date: Wed, 12 Feb 2025 09:54:33 +0100
Subject: [PATCH 35/36] `f16` is half-precision

---
 library/std/src/f16.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs
index cc523c93b4de7..f6a553b1d0fa2 100644
--- a/library/std/src/f16.rs
+++ b/library/std/src/f16.rs
@@ -1,4 +1,4 @@
-//! Constants for the `f16` double-precision floating point type.
+//! Constants for the `f16` half-precision floating point type.
 //!
 //! *[See also the `f16` primitive type](primitive@f16).*
 //!

From 4f37b458fc729c1f8b992cdda9f62f6b944b4106 Mon Sep 17 00:00:00 2001
From: eyelash 
Date: Wed, 12 Feb 2025 09:55:45 +0100
Subject: [PATCH 36/36] `f128` is quadruple-precision

---
 library/std/src/f128.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs
index 89612fa747551..cff0bf4ccf4c4 100644
--- a/library/std/src/f128.rs
+++ b/library/std/src/f128.rs
@@ -1,4 +1,4 @@
-//! Constants for the `f128` double-precision floating point type.
+//! Constants for the `f128` quadruple-precision floating point type.
 //!
 //! *[See also the `f128` primitive type](primitive@f128).*
 //!