about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorThe Miri Cronjob Bot <miri@cron.bot>2025-07-25 05:08:27 +0000
committerThe Miri Cronjob Bot <miri@cron.bot>2025-07-25 05:08:27 +0000
commit8ff5894541e058efef81be97689d83401b6793af (patch)
tree5c52dde4eaf49da2828efa6f2a7e728ffb4530db /src
parent0258894b762a163df714a86589a9e8158b354499 (diff)
parent51c5f191dec8b78b8a1b6e26eec26c26556125e3 (diff)
downloadrust-8ff5894541e058efef81be97689d83401b6793af.tar.gz
rust-8ff5894541e058efef81be97689d83401b6793af.zip
Merge ref 'b56aaec52bc0' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh.

Upstream ref: b56aaec52bc0fa35591a872fb4aac81f606e265c
Filtered ref: 12f5e3255df658296af9fc953d8c1ab79ba91ea3

This merge was created using https://github.com/rust-lang/josh-sync.
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs24
-rw-r--r--src/bootstrap/src/core/builder/mod.rs8
-rw-r--r--src/bootstrap/src/core/builder/tests.rs38
-rw-r--r--src/bootstrap/src/core/config/config.rs3
-rw-r--r--src/bootstrap/src/core/config/flags.rs2
-rw-r--r--src/bootstrap/src/core/config/toml/rust.rs30
-rw-r--r--src/bootstrap/src/core/download.rs1
-rw-r--r--src/build_helper/src/npm.rs43
-rw-r--r--src/ci/citool/src/jobs.rs116
-rw-r--r--src/ci/citool/src/jobs/tests.rs220
-rw-r--r--src/ci/citool/tests/jobs.rs2
-rw-r--r--src/ci/docker/host-x86_64/pr-check-1/Dockerfile9
-rw-r--r--src/ci/docker/host-x86_64/test-various/Dockerfile6
-rw-r--r--src/ci/docker/host-x86_64/tidy/Dockerfile2
-rw-r--r--src/ci/github-actions/jobs.yml25
-rw-r--r--src/doc/rustc-dev-guide/src/asm.md6
-rw-r--r--src/doc/rustc-dev-guide/src/autodiff/installation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md4
-rw-r--r--src/doc/rustc-dev-guide/src/offload/installation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/profile-guided-optimization.md2
-rw-r--r--src/doc/rustc-dev-guide/src/sanitizers.md4
-rw-r--r--src/doc/rustc-dev-guide/src/tests/compiletest.md10
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ui.md8
-rw-r--r--src/etc/completions/x.fish2
-rw-r--r--src/etc/completions/x.ps12
-rw-r--r--src/etc/completions/x.py.fish2
-rw-r--r--src/etc/completions/x.py.ps12
-rw-r--r--src/etc/completions/x.py.zsh2
-rw-r--r--src/etc/completions/x.zsh2
-rw-r--r--src/librustdoc/doctest.rs2
-rw-r--r--src/librustdoc/html/render/search_index.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_use.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_trait_names.rs2
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr2
-rw-r--r--src/tools/compiletest/src/common.rs4
-rw-r--r--src/tools/compiletest/src/lib.rs19
-rw-r--r--src/tools/miri/src/machine.rs45
-rw-r--r--src/tools/miri/tests/pass/const-addrs.rs20
-rw-r--r--src/tools/opt-dist/src/environment.rs16
-rw-r--r--src/tools/opt-dist/src/main.rs6
-rw-r--r--src/tools/opt-dist/src/tests.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs16
-rw-r--r--src/tools/rustdoc-gui-test/src/main.rs6
-rw-r--r--src/tools/tidy/src/deps.rs1
-rw-r--r--src/tools/tidy/src/ext_tool_checks.rs41
-rw-r--r--src/tools/tidy/src/ext_tool_checks/rustdoc_js.rs113
-rw-r--r--src/tools/tidy/src/issues.txt1224
-rw-r--r--src/tools/tidy/src/lib.rs1
-rw-r--r--src/tools/tidy/src/main.rs5
-rw-r--r--src/tools/tidy/src/pal.rs1
-rw-r--r--src/tools/tidy/src/rustdoc_js.rs101
-rw-r--r--src/tools/tidy/src/target_policy.rs6
-rw-r--r--src/tools/tidy/src/ui_tests.rs55
-rw-r--r--src/tools/tidy/src/unit_tests.rs3
56 files changed, 734 insertions, 1571 deletions
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 39e4fb2ac01..c8a54ad250c 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -1068,6 +1068,8 @@ impl Step for PlainSourceTarball {
             "bootstrap.example.toml",
             "configure",
             "license-metadata.json",
+            "package-lock.json",
+            "package.json",
             "x",
             "x.ps1",
             "x.py",
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 8344b0e03b4..ebbb569e9db 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1113,6 +1113,12 @@ impl Step for Tidy {
             8 * std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32
         });
         cmd.arg(jobs.to_string());
+        // pass the path to the npm command used for installing js deps.
+        if let Some(npm) = &builder.config.npm {
+            cmd.arg(npm);
+        } else {
+            cmd.arg("npm");
+        }
         if builder.is_verbose() {
             cmd.arg("--verbose");
         }
@@ -1342,7 +1348,12 @@ test!(Ui { path: "tests/ui", mode: "ui", suite: "ui", default: true });
 
 test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes", default: true });
 
-test!(Codegen { path: "tests/codegen", mode: "codegen", suite: "codegen", default: true });
+test!(CodegenLlvm {
+    path: "tests/codegen-llvm",
+    mode: "codegen",
+    suite: "codegen-llvm",
+    default: true
+});
 
 test!(CodegenUnits {
     path: "tests/codegen-units",
@@ -1407,7 +1418,12 @@ test!(Pretty {
 
 test!(RunMake { path: "tests/run-make", mode: "run-make", suite: "run-make", default: true });
 
-test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly", default: true });
+test!(AssemblyLlvm {
+    path: "tests/assembly-llvm",
+    mode: "assembly",
+    suite: "assembly-llvm",
+    default: true
+});
 
 /// Runs the coverage test suite at `tests/coverage` in some or all of the
 /// coverage test modes.
@@ -1615,7 +1631,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         let suite_path = self.path;
 
         // Skip codegen tests if they aren't enabled in configuration.
-        if !builder.config.codegen_tests && suite == "codegen" {
+        if !builder.config.codegen_tests && mode == "codegen" {
             return;
         }
 
@@ -1812,7 +1828,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
         flags.push(format!(
             "-Cdebuginfo={}",
-            if suite == "codegen" {
+            if mode == "codegen" {
                 // codegen tests typically check LLVM IR and are sensitive to additional debuginfo.
                 // So do not apply `rust.debuginfo-level-tests` for codegen tests.
                 if builder.config.rust_debuginfo_level_tests
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index d73e2bce25b..923c3a9a935 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -411,8 +411,8 @@ const PATH_REMAP: &[(&str, &[&str])] = &[
         "tests",
         &[
             // tidy-alphabetical-start
-            "tests/assembly",
-            "tests/codegen",
+            "tests/assembly-llvm",
+            "tests/codegen-llvm",
             "tests/codegen-units",
             "tests/coverage",
             "tests/coverage-run-rustdoc",
@@ -1049,9 +1049,9 @@ impl<'a> Builder<'a> {
                 test::Crashes,
                 test::Coverage,
                 test::MirOpt,
-                test::Codegen,
+                test::CodegenLlvm,
                 test::CodegenUnits,
-                test::Assembly,
+                test::AssemblyLlvm,
                 test::Incremental,
                 test::Debuginfo,
                 test::UiFullDeps,
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index c025a8b15d0..6ea5d4e6553 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -642,6 +642,7 @@ mod snapshot {
     };
     use crate::core::builder::{Builder, Kind, StepDescription, StepMetadata};
     use crate::core::config::TargetSelection;
+    use crate::core::config::toml::rust::with_lld_opt_in_targets;
     use crate::utils::cache::Cache;
     use crate::utils::helpers::get_host_target;
     use crate::utils::tests::{ConfigBuilder, TestCtx};
@@ -998,7 +999,7 @@ mod snapshot {
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustdoc 0 <host>
-        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
+        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
         ");
     }
 
@@ -1047,7 +1048,7 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
@@ -1089,7 +1090,7 @@ mod snapshot {
         [build] rustc 1 <host> -> WasmComponentLd 2 <host>
         [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
@@ -1125,8 +1126,8 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
@@ -1162,7 +1163,7 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 1 <host> -> std 1 <target1>
@@ -1199,8 +1200,8 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 1 <host> -> std 1 <target1>
@@ -1241,7 +1242,7 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
         [dist] docs <target1>
@@ -1273,7 +1274,7 @@ mod snapshot {
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustc 1 <host> -> WasmComponentLd 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 1 <host> -> std 1 <target1>
         [build] rustc 2 <host> -> std 2 <target1>
@@ -1619,7 +1620,7 @@ mod snapshot {
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustdoc 0 <host>
-        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
+        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
         ");
     }
 
@@ -1653,6 +1654,21 @@ mod snapshot {
     }
 
     #[test]
+    fn test_lld_opt_in() {
+        with_lld_opt_in_targets(vec![host_target()], || {
+            let ctx = TestCtx::new();
+            insta::assert_snapshot!(
+                ctx.config("build")
+                    .path("compiler")
+                    .render_steps(), @r"
+            [build] llvm <host>
+            [build] rustc 0 <host> -> rustc 1 <host>
+            [build] rustc 0 <host> -> LldWrapper 1 <host>
+            ");
+        });
+    }
+
+    #[test]
     fn doc_library_no_std_target() {
         let ctx = TestCtx::new();
         insta::assert_snapshot!(
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 22a75183404..6e04f115424 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -942,6 +942,7 @@ impl Config {
         config.rust_profile_use = flags_rust_profile_use;
         config.rust_profile_generate = flags_rust_profile_generate;
 
+        config.apply_target_config(toml.target);
         config.apply_rust_config(toml.rust, flags_warnings);
 
         config.reproducible_artifacts = flags_reproducible_artifact;
@@ -967,8 +968,6 @@ impl Config {
 
         config.apply_gcc_config(toml.gcc);
 
-        config.apply_target_config(toml.target);
-
         match ccache {
             Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()),
             Some(StringOrBool::Bool(true)) => {
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index 1547ca44494..31a427f9ffa 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -386,7 +386,7 @@ pub enum Subcommand {
         bless: bool,
         #[arg(long)]
         /// comma-separated list of other files types to check (accepts py, py:lint,
-        /// py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)
+        /// py:fmt, shell, cpp, cpp:fmt, js, js:lint, js:typecheck, spellcheck)
         ///
         /// Any argument can be prefixed with "auto:" to only run if
         /// relevant files are modified (eg. "auto:py").
diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs
index 71fab0e6ae6..c136bd4a6f9 100644
--- a/src/bootstrap/src/core/config/toml/rust.rs
+++ b/src/bootstrap/src/core/config/toml/rust.rs
@@ -410,6 +410,31 @@ pub(crate) fn validate_codegen_backends(backends: Vec<String>, section: &str) ->
     backends
 }
 
+#[cfg(not(test))]
+fn default_lld_opt_in_targets() -> Vec<String> {
+    vec!["x86_64-unknown-linux-gnu".to_string()]
+}
+
+#[cfg(test)]
+thread_local! {
+    static TEST_LLD_OPT_IN_TARGETS: std::cell::RefCell<Option<Vec<String>>> = std::cell::RefCell::new(None);
+}
+
+#[cfg(test)]
+fn default_lld_opt_in_targets() -> Vec<String> {
+    TEST_LLD_OPT_IN_TARGETS.with(|cell| cell.borrow().clone()).unwrap_or_default()
+}
+
+#[cfg(test)]
+pub fn with_lld_opt_in_targets<R>(targets: Vec<String>, f: impl FnOnce() -> R) -> R {
+    TEST_LLD_OPT_IN_TARGETS.with(|cell| {
+        let prev = cell.replace(Some(targets));
+        let result = f();
+        cell.replace(prev);
+        result
+    })
+}
+
 impl Config {
     pub fn apply_rust_config(&mut self, toml_rust: Option<Rust>, warnings: Warnings) {
         let mut debug = None;
@@ -617,12 +642,13 @@ impl Config {
         //   thus, disabled
         // - similarly, lld will not be built nor used by default when explicitly asked not to, e.g.
         //   when the config sets `rust.lld = false`
-        if self.host_target.triple == "x86_64-unknown-linux-gnu" && self.hosts == [self.host_target]
+        if default_lld_opt_in_targets().contains(&self.host_target.triple.to_string())
+            && self.hosts == [self.host_target]
         {
             let no_llvm_config = self
                 .target_config
                 .get(&self.host_target)
-                .is_some_and(|target_config| target_config.llvm_config.is_none());
+                .is_none_or(|target_config| target_config.llvm_config.is_none());
             let enable_lld = self.llvm_from_ci || no_llvm_config;
             // Prefer the config setting in case an explicit opt-out is needed.
             self.lld_enabled = lld_enabled.unwrap_or(enable_lld);
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index d7c6d8dbcc3..373fcd52052 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -875,6 +875,7 @@ pub(crate) fn is_download_ci_available(target_triple: &str, llvm_assertions: boo
         "powerpc-unknown-linux-gnu",
         "powerpc64-unknown-linux-gnu",
         "powerpc64le-unknown-linux-gnu",
+        "powerpc64le-unknown-linux-musl",
         "riscv64gc-unknown-linux-gnu",
         "s390x-unknown-linux-gnu",
         "x86_64-apple-darwin",
diff --git a/src/build_helper/src/npm.rs b/src/build_helper/src/npm.rs
index dedef40978d..86cf6183bd0 100644
--- a/src/build_helper/src/npm.rs
+++ b/src/build_helper/src/npm.rs
@@ -3,23 +3,34 @@ use std::path::{Path, PathBuf};
 use std::process::Command;
 use std::{fs, io};
 
-/// Install an exact package version, and return the path of `node_modules`.
-pub fn install_one(
-    out_dir: &Path,
-    npm_bin: &Path,
-    pkg_name: &str,
-    pkg_version: &str,
-) -> Result<PathBuf, io::Error> {
+use crate::ci::CiEnv;
+
+/// Install all the npm deps, and return the path of `node_modules`.
+pub fn install(src_root_path: &Path, out_dir: &Path, npm: &Path) -> Result<PathBuf, io::Error> {
     let nm_path = out_dir.join("node_modules");
-    let _ = fs::create_dir(&nm_path);
-    let mut child = Command::new(npm_bin)
-        .arg("install")
-        .arg("--audit=false")
-        .arg("--fund=false")
-        .arg(format!("{pkg_name}@{pkg_version}"))
-        .current_dir(out_dir)
-        .spawn()?;
-    let exit_status = child.wait()?;
+    let copy_to_build = |p| {
+        fs::copy(src_root_path.join(p), out_dir.join(p)).map_err(|e| {
+            eprintln!("unable to copy {p:?} to build directory: {e:?}");
+            e
+        })
+    };
+    // copy stuff to the output directory to make node_modules get put there.
+    copy_to_build("package.json")?;
+    copy_to_build("package-lock.json")?;
+
+    let mut cmd = Command::new(npm);
+    if CiEnv::is_ci() {
+        // `npm ci` redownloads every time and thus is too slow for local development.
+        cmd.arg("ci");
+    } else {
+        cmd.arg("install");
+    }
+    // disable a bunch of things we don't want.
+    // this makes tidy output less noisy, and also significantly improves runtime
+    // of repeated tidy invokations.
+    cmd.args(&["--audit=false", "--save=false", "--fund=false"]);
+    cmd.current_dir(out_dir);
+    let exit_status = cmd.spawn()?.wait()?;
     if !exit_status.success() {
         eprintln!("npm install did not exit successfully");
         return Err(io::Error::other(Box::<dyn Error + Send + Sync>::from(format!(
diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs
index 410274227e4..47516cbc1f4 100644
--- a/src/ci/citool/src/jobs.rs
+++ b/src/ci/citool/src/jobs.rs
@@ -1,9 +1,9 @@
 #[cfg(test)]
 mod tests;
 
-use std::collections::BTreeMap;
+use std::collections::{BTreeMap, HashSet};
 
-use anyhow::Context as _;
+use anyhow::{Context as _, anyhow};
 use serde_yaml::Value;
 
 use crate::GitHubContext;
@@ -85,6 +85,10 @@ impl JobDatabase {
             .cloned()
             .collect()
     }
+
+    fn find_auto_job_by_name(&self, job_name: &str) -> Option<&Job> {
+        self.auto_jobs.iter().find(|job| job.name == job_name)
+    }
 }
 
 pub fn load_job_db(db: &str) -> anyhow::Result<JobDatabase> {
@@ -97,14 +101,118 @@ pub fn load_job_db(db: &str) -> anyhow::Result<JobDatabase> {
         db.apply_merge().context("failed to apply merge keys")
     };
 
-    // Apply merge twice to handle nested merges
+    // Apply merge twice to handle nested merges up to depth 2.
     apply_merge(&mut db)?;
     apply_merge(&mut db)?;
 
-    let db: JobDatabase = serde_yaml::from_value(db).context("failed to parse job database")?;
+    let mut db: JobDatabase = serde_yaml::from_value(db).context("failed to parse job database")?;
+
+    register_pr_jobs_as_auto_jobs(&mut db)?;
+
+    validate_job_database(&db)?;
+
     Ok(db)
 }
 
+/// Maintain invariant that PR CI jobs must be a subset of Auto CI jobs modulo carve-outs.
+///
+/// When PR jobs are auto-registered as Auto jobs, they will have `continue_on_error` overridden to
+/// be `false` to avoid wasting Auto CI resources.
+///
+/// When a job is already both a PR job and a auto job, we will post-validate their "equivalence
+/// modulo certain carve-outs" in [`validate_job_database`].
+///
+/// This invariant is important to make sure that it's not easily possible (without modifying
+/// `citool`) to have PRs with red PR-only CI jobs merged into `master`, causing all subsequent PR
+/// CI runs to be red until the cause is fixed.
+fn register_pr_jobs_as_auto_jobs(db: &mut JobDatabase) -> anyhow::Result<()> {
+    for pr_job in &db.pr_jobs {
+        // It's acceptable to "override" a PR job in Auto job, for instance, `x86_64-gnu-tools` will
+        // receive an additional `DEPLOY_TOOLSTATES_JSON: toolstates-linux.json` env when under Auto
+        // environment versus PR environment.
+        if db.find_auto_job_by_name(&pr_job.name).is_some() {
+            continue;
+        }
+
+        let auto_registered_job = Job { continue_on_error: Some(false), ..pr_job.clone() };
+        db.auto_jobs.push(auto_registered_job);
+    }
+
+    Ok(())
+}
+
+fn validate_job_database(db: &JobDatabase) -> anyhow::Result<()> {
+    fn ensure_no_duplicate_job_names(section: &str, jobs: &Vec<Job>) -> anyhow::Result<()> {
+        let mut job_names = HashSet::new();
+        for job in jobs {
+            let job_name = job.name.as_str();
+            if !job_names.insert(job_name) {
+                return Err(anyhow::anyhow!(
+                    "duplicate job name `{job_name}` in section `{section}`"
+                ));
+            }
+        }
+        Ok(())
+    }
+
+    ensure_no_duplicate_job_names("pr", &db.pr_jobs)?;
+    ensure_no_duplicate_job_names("auto", &db.auto_jobs)?;
+    ensure_no_duplicate_job_names("try", &db.try_jobs)?;
+    ensure_no_duplicate_job_names("optional", &db.optional_jobs)?;
+
+    fn equivalent_modulo_carve_out(pr_job: &Job, auto_job: &Job) -> anyhow::Result<()> {
+        let Job {
+            name,
+            os,
+            only_on_channel,
+            free_disk,
+            doc_url,
+            codebuild,
+
+            // Carve-out configs allowed to be different.
+            env: _,
+            continue_on_error: _,
+        } = pr_job;
+
+        if *name == auto_job.name
+            && *os == auto_job.os
+            && *only_on_channel == auto_job.only_on_channel
+            && *free_disk == auto_job.free_disk
+            && *doc_url == auto_job.doc_url
+            && *codebuild == auto_job.codebuild
+        {
+            Ok(())
+        } else {
+            Err(anyhow!(
+                "PR job `{}` differs from corresponding Auto job `{}` in configuration other than `continue_on_error` and `env`",
+                pr_job.name,
+                auto_job.name
+            ))
+        }
+    }
+
+    for pr_job in &db.pr_jobs {
+        // At this point, any PR job must also be an Auto job, auto-registered or overridden.
+        let auto_job = db
+            .find_auto_job_by_name(&pr_job.name)
+            .expect("PR job must either be auto-registered as Auto job or overridden");
+
+        equivalent_modulo_carve_out(pr_job, auto_job)?;
+    }
+
+    // Auto CI jobs must all "fail-fast" to avoid wasting Auto CI resources. For instance, `tidy`.
+    for auto_job in &db.auto_jobs {
+        if auto_job.continue_on_error == Some(true) {
+            return Err(anyhow!(
+                "Auto job `{}` cannot have `continue_on_error: true`",
+                auto_job.name
+            ));
+        }
+    }
+
+    Ok(())
+}
+
 /// Representation of a job outputted to a GitHub Actions workflow.
 #[derive(serde::Serialize, Debug)]
 struct GithubActionsJob {
diff --git a/src/ci/citool/src/jobs/tests.rs b/src/ci/citool/src/jobs/tests.rs
index 63ac508b632..f1f6274e1ed 100644
--- a/src/ci/citool/src/jobs/tests.rs
+++ b/src/ci/citool/src/jobs/tests.rs
@@ -1,3 +1,4 @@
+use std::collections::BTreeMap;
 use std::path::Path;
 
 use super::Job;
@@ -146,3 +147,222 @@ fn validate_jobs() {
         panic!("Job validation failed:\n{error_messages}");
     }
 }
+
+#[test]
+fn pr_job_implies_auto_job() {
+    let db = load_job_db(
+        r#"
+envs:
+  pr:
+  try:
+  auto:
+  optional:
+
+pr:
+    - name: pr-ci-a
+      os: ubuntu
+      env: {}
+try:
+auto:
+optional:
+"#,
+    )
+    .unwrap();
+
+    assert_eq!(db.auto_jobs.iter().map(|j| j.name.as_str()).collect::<Vec<_>>(), vec!["pr-ci-a"])
+}
+
+#[test]
+fn implied_auto_job_keeps_env_and_fails_fast() {
+    let db = load_job_db(
+        r#"
+envs:
+  pr:
+  try:
+  auto:
+  optional:
+
+pr:
+    - name: tidy
+      env:
+        DEPLOY_TOOLSTATES_JSON: toolstates-linux.json
+      continue_on_error: true
+      os: ubuntu
+try:
+auto:
+optional:
+"#,
+    )
+    .unwrap();
+
+    assert_eq!(db.auto_jobs.iter().map(|j| j.name.as_str()).collect::<Vec<_>>(), vec!["tidy"]);
+    assert_eq!(db.auto_jobs[0].continue_on_error, Some(false));
+    assert_eq!(
+        db.auto_jobs[0].env,
+        BTreeMap::from([(
+            "DEPLOY_TOOLSTATES_JSON".to_string(),
+            serde_yaml::Value::String("toolstates-linux.json".to_string())
+        )])
+    );
+}
+
+#[test]
+#[should_panic = "duplicate"]
+fn duplicate_job_name() {
+    let _ = load_job_db(
+        r#"
+envs:
+  pr:
+  try:
+  auto:
+
+
+pr:
+    - name: pr-ci-a
+      os: ubuntu
+      env: {}
+    - name: pr-ci-a
+      os: ubuntu
+      env: {}
+try:
+auto:
+optional:
+"#,
+    )
+    .unwrap();
+}
+
+#[test]
+fn auto_job_can_override_pr_job_spec() {
+    let db = load_job_db(
+        r#"
+envs:
+  pr:
+  try:
+  auto:
+  optional:
+
+pr:
+    - name: tidy
+      os: ubuntu
+      env: {}
+try:
+auto:
+    - name: tidy
+      env:
+        DEPLOY_TOOLSTATES_JSON: toolstates-linux.json
+      continue_on_error: false
+      os: ubuntu
+optional:
+"#,
+    )
+    .unwrap();
+
+    assert_eq!(db.auto_jobs.iter().map(|j| j.name.as_str()).collect::<Vec<_>>(), vec!["tidy"]);
+    assert_eq!(db.auto_jobs[0].continue_on_error, Some(false));
+    assert_eq!(
+        db.auto_jobs[0].env,
+        BTreeMap::from([(
+            "DEPLOY_TOOLSTATES_JSON".to_string(),
+            serde_yaml::Value::String("toolstates-linux.json".to_string())
+        )])
+    );
+}
+
+#[test]
+fn compatible_divergence_pr_auto_job() {
+    let db = load_job_db(
+        r#"
+envs:
+  pr:
+  try:
+  auto:
+  optional:
+
+pr:
+    - name: tidy
+      continue_on_error: true
+      env:
+        ENV_ALLOWED_TO_DIFFER: "hello world"
+      os: ubuntu
+try:
+auto:
+    - name: tidy
+      continue_on_error: false
+      env:
+        ENV_ALLOWED_TO_DIFFER: "goodbye world"
+      os: ubuntu
+optional:
+"#,
+    )
+    .unwrap();
+
+    // `continue_on_error` and `env` are carve-outs *allowed* to diverge between PR and Auto job of
+    // the same name. Should load successfully.
+
+    assert_eq!(db.auto_jobs.iter().map(|j| j.name.as_str()).collect::<Vec<_>>(), vec!["tidy"]);
+    assert_eq!(db.auto_jobs[0].continue_on_error, Some(false));
+    assert_eq!(
+        db.auto_jobs[0].env,
+        BTreeMap::from([(
+            "ENV_ALLOWED_TO_DIFFER".to_string(),
+            serde_yaml::Value::String("goodbye world".to_string())
+        )])
+    );
+}
+
+#[test]
+#[should_panic = "differs"]
+fn incompatible_divergence_pr_auto_job() {
+    // `os` is not one of the carve-out options allowed to diverge. This should fail.
+    let _ = load_job_db(
+        r#"
+envs:
+  pr:
+  try:
+  auto:
+  optional:
+
+pr:
+    - name: tidy
+      continue_on_error: true
+      env:
+        ENV_ALLOWED_TO_DIFFER: "hello world"
+      os: ubuntu
+try:
+auto:
+    - name: tidy
+      continue_on_error: false
+      env:
+        ENV_ALLOWED_TO_DIFFER: "goodbye world"
+      os: windows
+optional:
+"#,
+    )
+    .unwrap();
+}
+
+#[test]
+#[should_panic = "cannot have `continue_on_error: true`"]
+fn auto_job_continue_on_error() {
+    // Auto CI jobs must fail-fast.
+    let _ = load_job_db(
+        r#"
+envs:
+  pr:
+  try:
+  auto:
+  optional:
+
+pr:
+try:
+auto:
+    - name: tidy
+      continue_on_error: true
+      os: windows
+      env: {}
+optional:
+"#,
+    )
+    .unwrap();
+}
diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs
index dbaf13d4f42..24e0b85cab2 100644
--- a/src/ci/citool/tests/jobs.rs
+++ b/src/ci/citool/tests/jobs.rs
@@ -6,7 +6,7 @@ const TEST_JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/tes
 fn auto_jobs() {
     let stdout = get_matrix("push", "commit", "refs/heads/auto");
     insta::assert_snapshot!(stdout, @r#"
-    jobs=[{"name":"aarch64-gnu","full_name":"auto - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"x86_64-gnu-llvm-18-1","full_name":"auto - x86_64-gnu-llvm-18-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DOCKER_SCRIPT":"stage_2_test_set1.sh","IMAGE":"x86_64-gnu-llvm-18","READ_ONLY_SRC":"0","RUST_BACKTRACE":1,"TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"aarch64-apple","full_name":"auto - aarch64-apple","os":"macos-14","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","MACOSX_DEPLOYMENT_TARGET":11.0,"MACOSX_STD_DEPLOYMENT_TARGET":11.0,"NO_DEBUG_ASSERTIONS":1,"NO_LLVM_ASSERTIONS":1,"NO_OVERFLOW_CHECKS":1,"RUSTC_RETRY_LINKER_ON_SEGFAULT":1,"RUST_CONFIGURE_ARGS":"--enable-sanitizers --enable-profiler --set rust.jemalloc","SCRIPT":"./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin","SELECT_XCODE":"/Applications/Xcode_15.4.app","TOOLSTATE_PUBLISH":1,"USE_XCODE_CLANG":1}},{"name":"dist-i686-msvc","full_name":"auto - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}}]
+    jobs=[{"name":"aarch64-gnu","full_name":"auto - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"x86_64-gnu-llvm-18-1","full_name":"auto - x86_64-gnu-llvm-18-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DOCKER_SCRIPT":"stage_2_test_set1.sh","IMAGE":"x86_64-gnu-llvm-18","READ_ONLY_SRC":"0","RUST_BACKTRACE":1,"TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"aarch64-apple","full_name":"auto - aarch64-apple","os":"macos-14","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","MACOSX_DEPLOYMENT_TARGET":11.0,"MACOSX_STD_DEPLOYMENT_TARGET":11.0,"NO_DEBUG_ASSERTIONS":1,"NO_LLVM_ASSERTIONS":1,"NO_OVERFLOW_CHECKS":1,"RUSTC_RETRY_LINKER_ON_SEGFAULT":1,"RUST_CONFIGURE_ARGS":"--enable-sanitizers --enable-profiler --set rust.jemalloc","SCRIPT":"./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin","SELECT_XCODE":"/Applications/Xcode_15.4.app","TOOLSTATE_PUBLISH":1,"USE_XCODE_CLANG":1}},{"name":"dist-i686-msvc","full_name":"auto - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}},{"name":"pr-check-1","full_name":"auto - pr-check-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"pr-check-2","full_name":"auto - pr-check-2","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"tidy","full_name":"auto - tidy","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true,"doc_url":"https://foo.bar"}]
     run_type=auto
     "#);
 }
diff --git a/src/ci/docker/host-x86_64/pr-check-1/Dockerfile b/src/ci/docker/host-x86_64/pr-check-1/Dockerfile
index 8bbcc18e2be..d3c3cd1b63e 100644
--- a/src/ci/docker/host-x86_64/pr-check-1/Dockerfile
+++ b/src/ci/docker/host-x86_64/pr-check-1/Dockerfile
@@ -27,10 +27,6 @@ COPY scripts/nodejs.sh /scripts/
 RUN sh /scripts/nodejs.sh /node
 ENV PATH="/node/bin:${PATH}"
 
-# Install es-check
-# Pin its version to prevent unrelated CI failures due to future es-check versions.
-RUN npm install es-check@6.1.1 eslint@8.6.0 typescript@5.7.3 -g
-
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
@@ -52,7 +48,4 @@ ENV SCRIPT \
   python3 ../x.py check --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \
   /scripts/validate-toolstate.sh && \
   reuse --include-submodules lint && \
-  python3 ../x.py test collect-license-metadata && \
-  # Runs checks to ensure that there are no issues in our JS code.
-  es-check es2019 ../src/librustdoc/html/static/js/*.js && \
-  tsc --project ../src/librustdoc/html/static/js/tsconfig.json
+  python3 ../x.py test collect-license-metadata
diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile
index 8d2e45ae497..4d09bea69c0 100644
--- a/src/ci/docker/host-x86_64/test-various/Dockerfile
+++ b/src/ci/docker/host-x86_64/test-various/Dockerfile
@@ -65,14 +65,14 @@ ENV WASM_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $WASM_T
   tests/ui \
   tests/mir-opt \
   tests/codegen-units \
-  tests/codegen \
-  tests/assembly \
+  tests/codegen-llvm \
+  tests/assembly-llvm \
   library/core
 
 ENV NVPTX_TARGETS=nvptx64-nvidia-cuda
 ENV NVPTX_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $NVPTX_TARGETS \
   tests/run-make \
-  tests/assembly
+  tests/assembly-llvm
 
 ENV MUSL_TARGETS=x86_64-unknown-linux-musl \
     CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \
diff --git a/src/ci/docker/host-x86_64/tidy/Dockerfile b/src/ci/docker/host-x86_64/tidy/Dockerfile
index dbb950cbe0c..ee1ae5410ee 100644
--- a/src/ci/docker/host-x86_64/tidy/Dockerfile
+++ b/src/ci/docker/host-x86_64/tidy/Dockerfile
@@ -45,4 +45,4 @@ RUN bash -c 'npm install -g eslint@$(cat /tmp/eslint.version)'
 # NOTE: intentionally uses python2 for x.py so we can test it still works.
 # validate-toolstate only runs in our CI, so it's ok for it to only support python3.
 ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 \
-  src/tools/tidy tidyselftest --extra-checks=py,cpp
+  src/tools/tidy tidyselftest --extra-checks=py,cpp,js
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index 0a6ebe44b3d..011688487b4 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -124,9 +124,16 @@ jobs:
     <<: *job-linux-36c-codebuild
 
 
-# Jobs that run on each push to a pull request (PR)
-# These jobs automatically inherit envs.pr, to avoid repeating
-# it in each job definition.
+# Jobs that run on each push to a pull request (PR).
+#
+# These jobs automatically inherit envs.pr, to avoid repeating it in each job
+# definition.
+#
+# PR CI jobs will be automatically registered as Auto CI jobs or overriden. When
+# automatically registered, the PR CI job configuration will be copied as an
+# Auto CI job but with `continue_on_error` overriden to `false` (to fail-fast).
+# When overriden, `citool` will check for equivalence between the PR and CI job
+# of the same name modulo `continue_on_error` and `env`.
 pr:
   - name: pr-check-1
     <<: *job-linux-4c
@@ -177,9 +184,15 @@ optional:
       IMAGE: pr-check-1
     <<: *job-linux-4c
 
-# Main CI jobs that have to be green to merge a commit into master
-# These jobs automatically inherit envs.auto, to avoid repeating
-# it in each job definition.
+# Main CI jobs that have to be green to merge a commit into master.
+#
+# These jobs automatically inherit envs.auto, to avoid repeating it in each job
+# definition.
+#
+# Auto jobs may not specify `continue_on_error: true`, and thus will fail-fast.
+#
+# Unless explicitly overriden, PR CI jobs will be automatically registered as
+# Auto CI jobs.
 auto:
   #############################
   #   Linux/Docker builders   #
diff --git a/src/doc/rustc-dev-guide/src/asm.md b/src/doc/rustc-dev-guide/src/asm.md
index eec9d448b0c..1bb493e73d5 100644
--- a/src/doc/rustc-dev-guide/src/asm.md
+++ b/src/doc/rustc-dev-guide/src/asm.md
@@ -155,9 +155,9 @@ can't know ahead of time whether a function will require a frame/base pointer.
 
 Various tests for inline assembly are available:
 
-- `tests/assembly/asm`
+- `tests/assembly-llvm/asm`
 - `tests/ui/asm`
-- `tests/codegen/asm-*`
+- `tests/codegen-llvm/asm-*`
 
 Every architecture supported by inline assembly must have exhaustive tests in
-`tests/assembly/asm` which test all combinations of register classes and types.
+`tests/assembly-llvm/asm` which test all combinations of register classes and types.
diff --git a/src/doc/rustc-dev-guide/src/autodiff/installation.md b/src/doc/rustc-dev-guide/src/autodiff/installation.md
index a550f6d233e..ddbb3a05424 100644
--- a/src/doc/rustc-dev-guide/src/autodiff/installation.md
+++ b/src/doc/rustc-dev-guide/src/autodiff/installation.md
@@ -25,7 +25,7 @@ rustup toolchain install nightly # enables -Z unstable-options
 You can then run our test cases:
 
 ```bash
-./x test --stage 1 tests/codegen/autodiff
+./x test --stage 1 tests/codegen-llvm/autodiff
 ./x test --stage 1 tests/pretty/autodiff
 ./x test --stage 1 tests/ui/autodiff
 ./x test --stage 1 tests/ui/feature-gates/feature-gate-autodiff.rs
diff --git a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
index 28e0e7a908d..880363b94bf 100644
--- a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
+++ b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
@@ -117,7 +117,7 @@ human-readable coverage report.
 > directive, so they will be skipped if the profiler runtime has not been
 > [enabled in `bootstrap.toml`](#recommended-configtoml-settings).
 
-Finally, the [`tests/codegen/instrument-coverage/testprog.rs`] test compiles a simple Rust program
+Finally, the [`tests/codegen-llvm/instrument-coverage/testprog.rs`] test compiles a simple Rust program
 with `-C instrument-coverage` and compares the compiled program's LLVM IR to
 expected LLVM IR instructions and structured data for a coverage-enabled
 program, including various checks for Coverage Map-related metadata and the LLVM
@@ -136,4 +136,4 @@ and `mir-opt` tests can be refreshed by running:
 [`tests/coverage`]: https://github.com/rust-lang/rust/tree/master/tests/coverage
 [`src/tools/coverage-dump`]: https://github.com/rust-lang/rust/tree/master/src/tools/coverage-dump
 [`tests/coverage-run-rustdoc`]: https://github.com/rust-lang/rust/tree/master/tests/coverage-run-rustdoc
-[`tests/codegen/instrument-coverage/testprog.rs`]: https://github.com/rust-lang/rust/blob/master/tests/mir-opt/coverage/instrument_coverage.rs
+[`tests/codegen-llvm/instrument-coverage/testprog.rs`]: https://github.com/rust-lang/rust/blob/master/tests/mir-opt/coverage/instrument_coverage.rs
diff --git a/src/doc/rustc-dev-guide/src/offload/installation.md b/src/doc/rustc-dev-guide/src/offload/installation.md
index 1962314c70a..1e792de3c8c 100644
--- a/src/doc/rustc-dev-guide/src/offload/installation.md
+++ b/src/doc/rustc-dev-guide/src/offload/installation.md
@@ -40,7 +40,7 @@ This gives you a working LLVM build.
 ## Testing
 run
 ```
-./x test --stage 1 tests/codegen/gpu_offload
+./x test --stage 1 tests/codegen-llvm/gpu_offload
 ```
 
 ## Usage
diff --git a/src/doc/rustc-dev-guide/src/profile-guided-optimization.md b/src/doc/rustc-dev-guide/src/profile-guided-optimization.md
index d279786ac45..2fa81021045 100644
--- a/src/doc/rustc-dev-guide/src/profile-guided-optimization.md
+++ b/src/doc/rustc-dev-guide/src/profile-guided-optimization.md
@@ -132,7 +132,7 @@ There is also a [codegen test][codegen-test] that checks that some expected
 instrumentation artifacts show up in LLVM IR.
 
 [rmake-tests]: https://github.com/rust-lang/rust/tree/master/tests/run-make
-[codegen-test]: https://github.com/rust-lang/rust/blob/master/tests/codegen/pgo-instrumentation.rs
+[codegen-test]: https://github.com/rust-lang/rust/blob/master/tests/codegen-llvm/pgo-instrumentation.rs
 
 ## Additional information
 
diff --git a/src/doc/rustc-dev-guide/src/sanitizers.md b/src/doc/rustc-dev-guide/src/sanitizers.md
index 664b4feac4f..29d9056c15d 100644
--- a/src/doc/rustc-dev-guide/src/sanitizers.md
+++ b/src/doc/rustc-dev-guide/src/sanitizers.md
@@ -76,7 +76,7 @@ implementation:
 ## Testing sanitizers
 
 Sanitizers are validated by code generation tests in
-[`tests/codegen/sanitize*.rs`][test-cg] and end-to-end functional tests in
+[`tests/codegen-llvm/sanitize*.rs`][test-cg] and end-to-end functional tests in
 [`tests/ui/sanitizer/`][test-ui] directory.
 
 Testing sanitizer functionality requires the sanitizer runtimes (built when
@@ -85,7 +85,7 @@ sanitizer. When sanitizer is unsupported on given target, sanitizers tests will
 be ignored. This behaviour is controlled by compiletest `needs-sanitizer-*`
 directives.
 
-[test-cg]: https://github.com/rust-lang/rust/tree/master/tests/codegen
+[test-cg]: https://github.com/rust-lang/rust/tree/master/tests/codegen-llvm
 [test-ui]: https://github.com/rust-lang/rust/tree/master/tests/ui/sanitizer
 
 ## Enabling sanitizer on a new target
diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md
index aa99347b2bb..a108dfdef9b 100644
--- a/src/doc/rustc-dev-guide/src/tests/compiletest.md
+++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md
@@ -68,7 +68,7 @@ The following test suites are available, with links for more information:
 | [`pretty`](#pretty-printer-tests)         | Check pretty printing                                                                                               |
 | [`incremental`](#incremental-tests)       | Check incremental compilation behavior                                                                              |
 | [`debuginfo`](#debuginfo-tests)           | Check debuginfo generation running debuggers                                                                        |
-| [`codegen`](#codegen-tests)               | Check code generation                                                                                               |
+| [`codegen-*`](#codegen-tests)             | Check code generation                                                                                               |
 | [`codegen-units`](#codegen-units-tests)   | Check codegen unit partitioning                                                                                     |
 | [`assembly`](#assembly-tests)             | Check assembly output                                                                                               |
 | [`mir-opt`](#mir-opt-tests)               | Check MIR generation and optimizations                                                                              |
@@ -290,7 +290,7 @@ For example, `./x test tests/debuginfo -- --debugger gdb` will only test GDB com
 
 ### Codegen tests
 
-The tests in [`tests/codegen`] test LLVM code generation. They compile the test
+The tests in [`tests/codegen-llvm`] test LLVM code generation. They compile the test
 with the `--emit=llvm-ir` flag to emit LLVM IR. They then run the LLVM
 [FileCheck] tool. The test is annotated with various `// CHECK` comments to
 check the generated code. See the [FileCheck] documentation for a tutorial and
@@ -301,13 +301,13 @@ See also the [assembly tests](#assembly-tests) for a similar set of tests.
 If you need to work with `#![no_std]` cross-compiling tests, consult the
 [`minicore` test auxiliary](./minicore.md) chapter.
 
-[`tests/codegen`]: https://github.com/rust-lang/rust/tree/master/tests/codegen
+[`tests/codegen-llvm`]: https://github.com/rust-lang/rust/tree/master/tests/codegen-llvm
 [FileCheck]: https://llvm.org/docs/CommandGuide/FileCheck.html
 
 
 ### Assembly tests
 
-The tests in [`tests/assembly`] test LLVM assembly output. They compile the test
+The tests in [`tests/assembly-llvm`] test LLVM assembly output. They compile the test
 with the `--emit=asm` flag to emit a `.s` file with the assembly output. They
 then run the LLVM [FileCheck] tool.
 
@@ -324,7 +324,7 @@ See also the [codegen tests](#codegen-tests) for a similar set of tests.
 If you need to work with `#![no_std]` cross-compiling tests, consult the
 [`minicore` test auxiliary](./minicore.md) chapter.
 
-[`tests/assembly`]: https://github.com/rust-lang/rust/tree/master/tests/assembly
+[`tests/assembly-llvm`]: https://github.com/rust-lang/rust/tree/master/tests/assembly-llvm
 
 
 ### Codegen-units tests
diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md
index 9bfc60e08a6..b1feef9ed0c 100644
--- a/src/doc/rustc-dev-guide/src/tests/ui.md
+++ b/src/doc/rustc-dev-guide/src/tests/ui.md
@@ -309,7 +309,8 @@ fn main((ؼ
 
 Use `//~?` to match an error without line information.
 `//~?` is precise and will not match errors if their line information is available.
-It should be preferred to using `error-pattern`, which is imprecise and non-exhaustive.
+For tests wishing to match against compiler diagnostics, error annotations should
+be preferred over //@ error-pattern, //@ error-pattern is imprecise and non-exhaustive.
 
 ```rust,ignore
 //@ compile-flags: --print yyyy
@@ -347,8 +348,6 @@ fn main() {
 }
 ```
 
-Use of `error-pattern` is not recommended in general.
-
 For strict testing of compile time output, try to use the line annotations `//~` as much as
 possible, including `//~?` annotations for diagnostics without spans.
 
@@ -359,7 +358,8 @@ Some of the compiler messages can stay uncovered by annotations in this mode.
 
 For checking runtime output, `//@ check-run-results` may be preferable.
 
-Only use `error-pattern` if none of the above works.
+Only use `error-pattern` if none of the above works, such as when finding a
+specific string pattern in a runtime panic output.
 
 Line annotations `//~` and `error-pattern` are compatible and can be used in the same test.
 
diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish
index 28a228d5464..a5e5bb8f09e 100644
--- a/src/etc/completions/x.fish
+++ b/src/etc/completions/x.fish
@@ -299,7 +299,7 @@ complete -c x -n "__fish_x_using_subcommand doc" -l skip-std-check-if-no-downloa
 complete -c x -n "__fish_x_using_subcommand doc" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
 complete -c x -n "__fish_x_using_subcommand test" -l compiletest-rustc-args -d 'extra options to pass the compiler when running compiletest tests' -r
-complete -c x -n "__fish_x_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)' -r
+complete -c x -n "__fish_x_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, cpp, cpp:fmt, js, js:lint, js:typecheck, spellcheck)' -r
 complete -c x -n "__fish_x_using_subcommand test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
 complete -c x -n "__fish_x_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
 complete -c x -n "__fish_x_using_subcommand test" -l run -d 'whether to execute run-* tests' -r
diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1
index 0c9b3828273..4fee3bc0a86 100644
--- a/src/etc/completions/x.ps1
+++ b/src/etc/completions/x.ps1
@@ -345,7 +345,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
         'x;test' {
             [CompletionResult]::new('--test-args', '--test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
             [CompletionResult]::new('--compiletest-rustc-args', '--compiletest-rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running compiletest tests')
-            [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)')
+            [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, cpp, cpp:fmt, js, js:lint, js:typecheck, spellcheck)')
             [CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
             [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
             [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index 43ae7424e27..e2e6ae05ee0 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -299,7 +299,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand doc" -l skip-std-check-if-no-d
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l compiletest-rustc-args -d 'extra options to pass the compiler when running compiletest tests' -r
-complete -c x.py -n "__fish_x.py_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)' -r
+complete -c x.py -n "__fish_x.py_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, cpp, cpp:fmt, js, js:lint, js:typecheck, spellcheck)' -r
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l run -d 'whether to execute run-* tests' -r
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index 4311e383d64..ea3aacc21c7 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -345,7 +345,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
         'x.py;test' {
             [CompletionResult]::new('--test-args', '--test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
             [CompletionResult]::new('--compiletest-rustc-args', '--compiletest-rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running compiletest tests')
-            [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)')
+            [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, cpp, cpp:fmt, js, js:lint, js:typecheck, spellcheck)')
             [CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
             [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
             [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh
index aff35b31e21..32e986ad141 100644
--- a/src/etc/completions/x.py.zsh
+++ b/src/etc/completions/x.py.zsh
@@ -345,7 +345,7 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \
 '*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS:_default' \
-'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, shell\:lint, cpp, cpp\:fmt, spellcheck)]:EXTRA_CHECKS:_default' \
+'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, cpp, cpp\:fmt, js, js\:lint, js\:typecheck, spellcheck)]:EXTRA_CHECKS:_default' \
 '--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \
 '--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \
 '--run=[whether to execute run-* tests]:auto | always | never:_default' \
diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh
index 28ad00f3a0d..65995553276 100644
--- a/src/etc/completions/x.zsh
+++ b/src/etc/completions/x.zsh
@@ -345,7 +345,7 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \
 '*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS:_default' \
-'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, shell\:lint, cpp, cpp\:fmt, spellcheck)]:EXTRA_CHECKS:_default' \
+'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, cpp, cpp\:fmt, js, js\:lint, js\:typecheck, spellcheck)]:EXTRA_CHECKS:_default' \
 '--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \
 '--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \
 '--run=[whether to execute run-* tests]:auto | always | never:_default' \
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 38ba6b4503d..a32c2f7fb18 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -444,7 +444,7 @@ fn add_exe_suffix(input: String, target: &TargetTuple) -> String {
     let exe_suffix = match target {
         TargetTuple::TargetTuple(_) => Target::expect_builtin(target).options.exe_suffix,
         TargetTuple::TargetJson { contents, .. } => {
-            Target::from_json(contents.parse().unwrap()).unwrap().0.options.exe_suffix
+            Target::from_json(contents).unwrap().0.options.exe_suffix
         }
     };
     input + &exe_suffix
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index 3c9be29ccc3..e2f86b8a854 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -100,9 +100,22 @@ pub(crate) fn build_index(
     let crate_doc =
         short_markdown_summary(&krate.module.doc_value(), &krate.module.link_names(cache));
 
+    #[derive(Eq, Ord, PartialEq, PartialOrd)]
+    struct SerSymbolAsStr(Symbol);
+
+    impl Serialize for SerSymbolAsStr {
+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+        where
+            S: Serializer,
+        {
+            self.0.as_str().serialize(serializer)
+        }
+    }
+
+    type AliasMap = BTreeMap<SerSymbolAsStr, Vec<usize>>;
     // Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias,
     // we need the alias element to have an array of items.
-    let mut aliases: BTreeMap<String, Vec<usize>> = BTreeMap::new();
+    let mut aliases: AliasMap = BTreeMap::new();
 
     // Sort search index items. This improves the compressibility of the search index.
     cache.search_index.sort_unstable_by(|k1, k2| {
@@ -116,7 +129,7 @@ pub(crate) fn build_index(
     // Set up alias indexes.
     for (i, item) in cache.search_index.iter().enumerate() {
         for alias in &item.aliases[..] {
-            aliases.entry(alias.to_string()).or_default().push(i);
+            aliases.entry(SerSymbolAsStr(*alias)).or_default().push(i);
         }
     }
 
@@ -474,7 +487,7 @@ pub(crate) fn build_index(
         // The String is alias name and the vec is the list of the elements with this alias.
         //
         // To be noted: the `usize` elements are indexes to `items`.
-        aliases: &'a BTreeMap<String, Vec<usize>>,
+        aliases: &'a AliasMap,
         // Used when a type has more than one impl with an associated item with the same name.
         associated_item_disambiguators: &'a Vec<(usize, String)>,
         // A list of shard lengths encoded as vlqhex. See the comment in write_vlqhex_to_string
diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs
index c1a26c5a9c7..d1a54df988f 100644
--- a/src/tools/clippy/clippy_lints/src/macro_use.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_use.rs
@@ -7,8 +7,9 @@ use rustc_hir::{self as hir, AmbigArg};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
 use rustc_span::edition::Edition;
-use rustc_span::{Span, sym};
+use rustc_span::{Span};
 use std::collections::BTreeMap;
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -99,15 +100,14 @@ impl LateLintPass<'_> for MacroUseImports {
             && let hir::ItemKind::Use(path, _kind) = &item.kind
             && let hir_id = item.hir_id()
             && let attrs = cx.tcx.hir_attrs(hir_id)
-            && let Some(mac_attr) = attrs.iter().find(|attr| attr.has_name(sym::macro_use))
+            && let Some(mac_attr_span) = find_attr!(attrs, AttributeKind::MacroUse {span, ..} => *span)
             && let Some(Res::Def(DefKind::Mod, id)) = path.res.type_ns
             && !id.is_local()
         {
             for kid in cx.tcx.module_children(id) {
                 if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res {
-                    let span = mac_attr.span();
                     let def_path = cx.tcx.def_path_str(mac_id);
-                    self.imports.push((def_path, span, hir_id));
+                    self.imports.push((def_path, mac_attr_span, hir_id));
                 }
             }
         } else if item.span.from_expansion() {
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 5f10e1968f1..388c029c9ef 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -338,7 +338,7 @@ impl<'tcx> NonCopyConst<'tcx> {
         tcx: TyCtxt<'tcx>,
         typing_env: TypingEnv<'tcx>,
         ty: Ty<'tcx>,
-        val: ConstValue<'tcx>,
+        val: ConstValue,
     ) -> Result<bool, ()> {
         let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
         match self.is_ty_freeze(tcx, typing_env, ty) {
@@ -477,7 +477,7 @@ impl<'tcx> NonCopyConst<'tcx> {
         typing_env: TypingEnv<'tcx>,
         typeck: &'tcx TypeckResults<'tcx>,
         mut src_expr: &'tcx Expr<'tcx>,
-        mut val: ConstValue<'tcx>,
+        mut val: ConstValue,
     ) -> Result<Option<BorrowSource<'tcx>>, ()> {
         let mut parents = tcx.hir_parent_iter(src_expr.hir_id);
         let mut ty = typeck.expr_ty(src_expr);
diff --git a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
index 610cec7b8c8..b7a1d5b2123 100644
--- a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
@@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames {
             && ident.name != kw::Underscore
             // Only check traits
             && let Some(Res::Def(DefKind::Trait, _)) = path.res.type_ns
-            && cx.tcx.maybe_unused_trait_imports(()).contains(&item.owner_id.def_id)
+            && cx.tcx.resolutions(()).maybe_unused_trait_imports.contains(&item.owner_id.def_id)
             // Only check this import if it is visible to its module only (no pub, pub(crate), ...)
             && let module = cx.tcx.parent_module_from_def_id(item.owner_id.def_id)
             && cx.tcx.visibility(item.owner_id.def_id) == Visibility::Restricted(module.to_def_id())
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
index a4bf0099244..26e360112b6 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
@@ -328,7 +328,7 @@ error: creating a shared reference to mutable static
 LL |         if X.is_some() {
    |            ^^^^^^^^^^^ shared reference to mutable static
    |
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
    = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
    = note: `#[deny(static_mut_refs)]` on by default
 
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 12084fa0b15..aceae3e3a3b 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -57,8 +57,8 @@ impl TestMode {
 string_enum! {
     #[derive(Clone, Copy, PartialEq, Debug)]
     pub enum TestSuite {
-        Assembly => "assembly",
-        Codegen => "codegen",
+        AssemblyLlvm => "assembly-llvm",
+        CodegenLlvm => "codegen-llvm",
         CodegenUnits => "codegen-units",
         Coverage => "coverage",
         CoverageRunRustdoc => "coverage-run-rustdoc",
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index 41bed8ed8a0..c712185733c 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -31,7 +31,7 @@ use std::time::SystemTime;
 use std::{env, fs, vec};
 
 use build_helper::git::{get_git_modified_files, get_git_untracked_files};
-use camino::{Utf8Path, Utf8PathBuf};
+use camino::{Utf8Component, Utf8Path, Utf8PathBuf};
 use getopts::Options;
 use rayon::iter::{ParallelBridge, ParallelIterator};
 use tracing::debug;
@@ -799,6 +799,23 @@ fn collect_tests_from_dir(
         return Ok(TestCollector::new());
     }
 
+    let mut components = dir.components().rev();
+    if let Some(Utf8Component::Normal(last)) = components.next()
+        && let Some(("assembly" | "codegen", backend)) = last.split_once('-')
+        && let Some(Utf8Component::Normal(parent)) = components.next()
+        && parent == "tests"
+        && let Ok(backend) = CodegenBackend::try_from(backend)
+        && backend != cx.config.codegen_backend
+    {
+        // We ignore asm tests which don't match the current codegen backend.
+        warning!(
+            "Ignoring tests in `{dir}` because they don't match the configured codegen \
+             backend (`{}`)",
+            cx.config.codegen_backend.as_str(),
+        );
+        return Ok(TestCollector::new());
+    }
+
     // For run-make tests, a "test file" is actually a directory that contains an `rmake.rs`.
     if cx.config.mode == TestMode::RunMake {
         let mut collector = TestCollector::new();
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index ce33c870b4b..7271d3f619c 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -4,7 +4,6 @@
 use std::any::Any;
 use std::borrow::Cow;
 use std::cell::{Cell, RefCell};
-use std::collections::hash_map::Entry;
 use std::path::Path;
 use std::rc::Rc;
 use std::{fmt, process};
@@ -70,12 +69,6 @@ pub struct FrameExtra<'tcx> {
     /// This is used by `MiriMachine::current_span` and `MiriMachine::caller_span`
     pub is_user_relevant: bool,
 
-    /// We have a cache for the mapping from [`mir::Const`] to resulting [`AllocId`].
-    /// However, we don't want all frames to always get the same result, so we insert
-    /// an additional bit of "salt" into the cache key. This salt is fixed per-frame
-    /// so that within a call, a const will have a stable address.
-    salt: usize,
-
     /// Data race detector per-frame data.
     pub data_race: Option<data_race::FrameState>,
 }
@@ -88,14 +81,12 @@ impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> {
             catch_unwind,
             timing: _,
             is_user_relevant,
-            salt,
             data_race,
         } = self;
         f.debug_struct("FrameData")
             .field("borrow_tracker", borrow_tracker)
             .field("catch_unwind", catch_unwind)
             .field("is_user_relevant", is_user_relevant)
-            .field("salt", salt)
             .field("data_race", data_race)
             .finish()
     }
@@ -108,7 +99,6 @@ impl VisitProvenance for FrameExtra<'_> {
             borrow_tracker,
             timing: _,
             is_user_relevant: _,
-            salt: _,
             data_race: _,
         } = self;
 
@@ -578,11 +568,6 @@ pub struct MiriMachine<'tcx> {
     /// diagnostics.
     pub(crate) allocation_spans: RefCell<FxHashMap<AllocId, (Span, Option<Span>)>>,
 
-    /// Maps MIR consts to their evaluated result. We combine the const with a "salt" (`usize`)
-    /// that is fixed per stack frame; this lets us have sometimes different results for the
-    /// same const while ensuring consistent results within a single call.
-    const_cache: RefCell<FxHashMap<(mir::Const<'tcx>, usize), OpTy<'tcx>>>,
-
     /// For each allocation, an offset inside that allocation that was deemed aligned even for
     /// symbolic alignment checks. This cannot be stored in `AllocExtra` since it needs to be
     /// tracked for vtables and function allocations as well as regular allocations.
@@ -764,7 +749,6 @@ impl<'tcx> MiriMachine<'tcx> {
             stack_size,
             collect_leak_backtraces: config.collect_leak_backtraces,
             allocation_spans: RefCell::new(FxHashMap::default()),
-            const_cache: RefCell::new(FxHashMap::default()),
             symbolic_alignment: RefCell::new(FxHashMap::default()),
             union_data_ranges: FxHashMap::default(),
             pthread_mutex_sanity: Cell::new(false),
@@ -941,7 +925,6 @@ impl VisitProvenance for MiriMachine<'_> {
             stack_size: _,
             collect_leak_backtraces: _,
             allocation_spans: _,
-            const_cache: _,
             symbolic_alignment: _,
             union_data_ranges: _,
             pthread_mutex_sanity: _,
@@ -1578,7 +1561,6 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
             catch_unwind: None,
             timing,
             is_user_relevant: ecx.machine.is_user_relevant(&frame),
-            salt: ecx.machine.rng.borrow_mut().random_range(0..ADDRS_PER_ANON_GLOBAL),
             data_race: ecx
                 .machine
                 .data_race
@@ -1737,33 +1719,6 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         interp_ok(())
     }
 
-    fn eval_mir_constant<F>(
-        ecx: &InterpCx<'tcx, Self>,
-        val: mir::Const<'tcx>,
-        span: Span,
-        layout: Option<TyAndLayout<'tcx>>,
-        eval: F,
-    ) -> InterpResult<'tcx, OpTy<'tcx>>
-    where
-        F: Fn(
-            &InterpCx<'tcx, Self>,
-            mir::Const<'tcx>,
-            Span,
-            Option<TyAndLayout<'tcx>>,
-        ) -> InterpResult<'tcx, OpTy<'tcx>>,
-    {
-        let frame = ecx.active_thread_stack().last().unwrap();
-        let mut cache = ecx.machine.const_cache.borrow_mut();
-        match cache.entry((val, frame.extra.salt)) {
-            Entry::Vacant(ve) => {
-                let op = eval(ecx, val, span, layout)?;
-                ve.insert(op.clone());
-                interp_ok(op)
-            }
-            Entry::Occupied(oe) => interp_ok(oe.get().clone()),
-        }
-    }
-
     fn get_global_alloc_salt(
         ecx: &InterpCx<'tcx, Self>,
         instance: Option<ty::Instance<'tcx>>,
diff --git a/src/tools/miri/tests/pass/const-addrs.rs b/src/tools/miri/tests/pass/const-addrs.rs
index af68b28b2b8..0d1531c73cd 100644
--- a/src/tools/miri/tests/pass/const-addrs.rs
+++ b/src/tools/miri/tests/pass/const-addrs.rs
@@ -1,14 +1,10 @@
-// The const fn interpreter creates a new AllocId every time it evaluates any const.
-// If we do that in Miri, repeatedly evaluating a const causes unbounded memory use
-// we need to keep track of the base address for that AllocId, and the allocation is never
-// deallocated.
-// In Miri we explicitly store previously-assigned AllocIds for each const and ensure
-// that we only hand out a finite number of AllocIds per const.
-// MIR inlining will put every evaluation of the const we're repeatedly evaluating into the same
-// stack frame, breaking this test.
+// The interpreter used to create a new AllocId every time it evaluates any const.
+// This caused unbounded memory use in Miri.
+// This test verifies that we only create a bounded amount of addresses for any given const.
+// In practice, the interpreter always returns the same address, but we *do not guarantee* that.
 //@compile-flags: -Zinline-mir=no
 
-const EVALS: usize = 256;
+const EVALS: usize = 64;
 
 use std::collections::HashSet;
 fn main() {
@@ -16,10 +12,8 @@ fn main() {
     for _ in 0..EVALS {
         addrs.insert(const_addr());
     }
-    // Check that the const allocation has multiple base addresses
-    assert!(addrs.len() > 1);
-    // But also that we get a limited number of unique base addresses
-    assert!(addrs.len() < EVALS);
+    // Check that we always return the same base address for the const allocation.
+    assert_eq!(addrs.len(), 1);
 
     // Check that within a call we always produce the same address
     let mut prev = 0;
diff --git a/src/tools/opt-dist/src/environment.rs b/src/tools/opt-dist/src/environment.rs
index e6e4c711c0c..2cae0785f33 100644
--- a/src/tools/opt-dist/src/environment.rs
+++ b/src/tools/opt-dist/src/environment.rs
@@ -28,6 +28,8 @@ pub struct Environment {
     run_tests: bool,
     fast_try_build: bool,
     build_llvm: bool,
+    #[builder(default)]
+    stage0_root: Option<Utf8PathBuf>,
 }
 
 impl Environment {
@@ -56,17 +58,11 @@ impl Environment {
     }
 
     pub fn cargo_stage_0(&self) -> Utf8PathBuf {
-        self.build_artifacts()
-            .join("stage0")
-            .join("bin")
-            .join(format!("cargo{}", executable_extension()))
+        self.stage0().join("bin").join(format!("cargo{}", executable_extension()))
     }
 
     pub fn rustc_stage_0(&self) -> Utf8PathBuf {
-        self.build_artifacts()
-            .join("stage0")
-            .join("bin")
-            .join(format!("rustc{}", executable_extension()))
+        self.stage0().join("bin").join(format!("rustc{}", executable_extension()))
     }
 
     pub fn rustc_stage_2(&self) -> Utf8PathBuf {
@@ -116,6 +112,10 @@ impl Environment {
     pub fn build_llvm(&self) -> bool {
         self.build_llvm
     }
+
+    pub fn stage0(&self) -> Utf8PathBuf {
+        self.stage0_root.clone().unwrap_or_else(|| self.build_artifacts().join("stage0"))
+    }
 }
 
 /// What is the extension of binary executables on this platform?
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index 42170ff39d7..19706b4a4f0 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -107,6 +107,10 @@ enum EnvironmentCmd {
         /// in bootstrap.toml via `build.build-dir` option
         #[arg(long, default_value = "build")]
         build_dir: Utf8PathBuf,
+
+        /// Path to custom stage0 root
+        #[arg(long)]
+        stage0_root: Option<Utf8PathBuf>,
     },
     /// Perform an optimized build on Linux CI, from inside Docker.
     LinuxCi {
@@ -144,6 +148,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
             run_tests,
             build_llvm,
             build_dir,
+            stage0_root,
         } => {
             let env = EnvironmentBuilder::default()
                 .host_tuple(target_triple)
@@ -160,6 +165,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 .run_tests(run_tests)
                 .fast_try_build(is_fast_try_build)
                 .build_llvm(build_llvm)
+                .stage0_root(stage0_root)
                 .build()?;
 
             (env, shared.build_args)
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
index c3c45d262dd..c9a21fc6fb2 100644
--- a/src/tools/opt-dist/src/tests.rs
+++ b/src/tools/opt-dist/src/tests.rs
@@ -100,8 +100,8 @@ llvm-config = "{llvm_config}"
             env.host_tuple(),
             "--stage",
             "0",
-            "tests/assembly",
-            "tests/codegen",
+            "tests/assembly-llvm",
+            "tests/codegen-llvm",
             "tests/codegen-units",
             "tests/incremental",
             "tests/mir-opt",
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
index 236f316366d..372a9dfc43d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
@@ -3,9 +3,9 @@
 use std::{cmp, ops::Bound};
 
 use hir_def::{
-    AdtId, VariantId,
     layout::{Integer, ReprOptions, TargetDataLayout},
     signatures::{StructFlags, VariantFields},
+    AdtId, VariantId,
 };
 use intern::sym;
 use rustc_index::IndexVec;
@@ -13,9 +13,9 @@ use smallvec::SmallVec;
 use triomphe::Arc;
 
 use crate::{
-    Substitution, TraitEnvironment,
     db::HirDatabase,
-    layout::{Layout, LayoutError, field_ty},
+    layout::{field_ty, Layout, LayoutError},
+    Substitution, TraitEnvironment,
 };
 
 use super::LayoutCx;
@@ -85,16 +85,6 @@ pub fn layout_of_adt_query(
                 let d = db.const_eval_discriminant(e.enum_variants(db).variants[id.0].0).ok()?;
                 Some((id, d))
             }),
-            // FIXME: The current code for niche-filling relies on variant indices
-            // instead of actual discriminants, so enums with
-            // explicit discriminants (RFC #2363) would misbehave and we should disable
-            // niche optimization for them.
-            // The code that do it in rustc:
-            // repr.inhibit_enum_layout_opt() || def
-            //     .variants()
-            //     .iter_enumerated()
-            //     .any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32()))
-            repr.inhibit_enum_layout_opt(),
             !matches!(def, AdtId::EnumId(..))
                 && variants
                     .iter()
diff --git a/src/tools/rustdoc-gui-test/src/main.rs b/src/tools/rustdoc-gui-test/src/main.rs
index 5b86bea8932..42feae8c208 100644
--- a/src/tools/rustdoc-gui-test/src/main.rs
+++ b/src/tools/rustdoc-gui-test/src/main.rs
@@ -65,10 +65,8 @@ fn main() -> Result<(), ()> {
         }
     }
 
-    // FIXME(binarycat): once we get package.json in version control, this should be updated to install via that instead
-    let local_node_modules =
-        npm::install_one(&config.out_dir, &config.npm, "browser-ui-test", "0.21.1")
-            .expect("unable to install browser-ui-test");
+    let local_node_modules = npm::install(&config.rust_src, &config.out_dir, &config.npm)
+        .expect("unable to install browser-ui-test");
 
     let mut command = Command::new(&config.nodejs);
 
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index f43f5eae9a5..d17ae162ab2 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -378,6 +378,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "serde",
     "serde_derive",
     "serde_json",
+    "serde_path_to_error",
     "sha1",
     "sha2",
     "sharded-slab",
diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs
index 381ea44fd46..8121eb057db 100644
--- a/src/tools/tidy/src/ext_tool_checks.rs
+++ b/src/tools/tidy/src/ext_tool_checks.rs
@@ -25,6 +25,8 @@ use std::{fmt, fs, io};
 
 use crate::CiInfo;
 
+mod rustdoc_js;
+
 const MIN_PY_REV: (u32, u32) = (3, 9);
 const MIN_PY_REV_STR: &str = "≥3.9";
 
@@ -46,12 +48,25 @@ pub fn check(
     root_path: &Path,
     outdir: &Path,
     ci_info: &CiInfo,
+    librustdoc_path: &Path,
+    tools_path: &Path,
+    npm: &Path,
     bless: bool,
     extra_checks: Option<&str>,
     pos_args: &[String],
     bad: &mut bool,
 ) {
-    if let Err(e) = check_impl(root_path, outdir, ci_info, bless, extra_checks, pos_args) {
+    if let Err(e) = check_impl(
+        root_path,
+        outdir,
+        ci_info,
+        librustdoc_path,
+        tools_path,
+        npm,
+        bless,
+        extra_checks,
+        pos_args,
+    ) {
         tidy_error!(bad, "{e}");
     }
 }
@@ -60,6 +75,9 @@ fn check_impl(
     root_path: &Path,
     outdir: &Path,
     ci_info: &CiInfo,
+    librustdoc_path: &Path,
+    tools_path: &Path,
+    npm: &Path,
     bless: bool,
     extra_checks: Option<&str>,
     pos_args: &[String],
@@ -108,6 +126,8 @@ fn check_impl(
     let shell_lint = extra_check!(Shell, Lint);
     let cpp_fmt = extra_check!(Cpp, Fmt);
     let spellcheck = extra_check!(Spellcheck, None);
+    let js_lint = extra_check!(Js, Lint);
+    let js_typecheck = extra_check!(Js, Typecheck);
 
     let mut py_path = None;
 
@@ -275,6 +295,19 @@ fn check_impl(
         spellcheck_runner(&args)?;
     }
 
+    if js_lint || js_typecheck {
+        rustdoc_js::npm_install(root_path, outdir, npm)?;
+    }
+
+    if js_lint {
+        rustdoc_js::lint(outdir, librustdoc_path, tools_path)?;
+        rustdoc_js::es_check(outdir, librustdoc_path)?;
+    }
+
+    if js_typecheck {
+        rustdoc_js::typecheck(outdir, librustdoc_path)?;
+    }
+
     Ok(())
 }
 
@@ -697,6 +730,7 @@ impl ExtraCheckArg {
             ExtraCheckLang::Py => ".py",
             ExtraCheckLang::Cpp => ".cpp",
             ExtraCheckLang::Shell => ".sh",
+            ExtraCheckLang::Js => ".js",
             ExtraCheckLang::Spellcheck => {
                 return !crate::files_modified(ci_info, |s| {
                     SPELLCHECK_DIRS.iter().any(|dir| Path::new(s).starts_with(dir))
@@ -717,6 +751,7 @@ impl ExtraCheckArg {
             ExtraCheckLang::Cpp => &[Fmt],
             ExtraCheckLang::Shell => &[Lint],
             ExtraCheckLang::Spellcheck => &[],
+            ExtraCheckLang::Js => &[Lint, Typecheck],
         };
         supported_kinds.contains(&kind)
     }
@@ -757,6 +792,7 @@ enum ExtraCheckLang {
     Shell,
     Cpp,
     Spellcheck,
+    Js,
 }
 
 impl FromStr for ExtraCheckLang {
@@ -768,6 +804,7 @@ impl FromStr for ExtraCheckLang {
             "shell" => Self::Shell,
             "cpp" => Self::Cpp,
             "spellcheck" => Self::Spellcheck,
+            "js" => Self::Js,
             _ => return Err(ExtraCheckParseError::UnknownLang(s.to_string())),
         })
     }
@@ -777,6 +814,7 @@ impl FromStr for ExtraCheckLang {
 enum ExtraCheckKind {
     Lint,
     Fmt,
+    Typecheck,
     /// Never parsed, but used as a placeholder for
     /// langs that never have a specific kind.
     None,
@@ -789,6 +827,7 @@ impl FromStr for ExtraCheckKind {
         Ok(match s {
             "lint" => Self::Lint,
             "fmt" => Self::Fmt,
+            "typecheck" => Self::Typecheck,
             _ => return Err(ExtraCheckParseError::UnknownKind(s.to_string())),
         })
     }
diff --git a/src/tools/tidy/src/ext_tool_checks/rustdoc_js.rs b/src/tools/tidy/src/ext_tool_checks/rustdoc_js.rs
new file mode 100644
index 00000000000..7708b128e23
--- /dev/null
+++ b/src/tools/tidy/src/ext_tool_checks/rustdoc_js.rs
@@ -0,0 +1,113 @@
+//! Tidy check to ensure that rustdoc templates didn't forget a `{# #}` to strip extra whitespace
+//! characters.
+
+use std::ffi::OsStr;
+use std::io;
+use std::path::{Path, PathBuf};
+use std::process::{Child, Command};
+
+use build_helper::npm;
+use ignore::DirEntry;
+
+use crate::walk::walk_no_read;
+
+fn node_module_bin(outdir: &Path, name: &str) -> PathBuf {
+    outdir.join("node_modules/.bin").join(name)
+}
+
+fn spawn_cmd(cmd: &mut Command) -> Result<Child, io::Error> {
+    cmd.spawn().map_err(|err| {
+        eprintln!("unable to run {cmd:?} due to {err:?}");
+        err
+    })
+}
+
+/// install all js dependencies from package.json.
+pub(super) fn npm_install(root_path: &Path, outdir: &Path, npm: &Path) -> Result<(), super::Error> {
+    npm::install(root_path, outdir, npm)?;
+    Ok(())
+}
+
+fn rustdoc_js_files(librustdoc_path: &Path) -> Vec<PathBuf> {
+    let mut files = Vec::new();
+    walk_no_read(
+        &[&librustdoc_path.join("html/static/js")],
+        |path, is_dir| is_dir || path.extension().is_none_or(|ext| ext != OsStr::new("js")),
+        &mut |path: &DirEntry| {
+            files.push(path.path().into());
+        },
+    );
+    return files;
+}
+
+fn run_eslint(outdir: &Path, args: &[PathBuf], config_folder: PathBuf) -> Result<(), super::Error> {
+    let mut child = spawn_cmd(
+        Command::new(node_module_bin(outdir, "eslint"))
+            .arg("-c")
+            .arg(config_folder.join(".eslintrc.js"))
+            .args(args),
+    )?;
+    match child.wait() {
+        Ok(exit_status) => {
+            if exit_status.success() {
+                return Ok(());
+            }
+            Err(super::Error::FailedCheck("eslint command failed"))
+        }
+        Err(error) => Err(super::Error::Generic(format!("eslint command failed: {error:?}"))),
+    }
+}
+
+pub(super) fn lint(
+    outdir: &Path,
+    librustdoc_path: &Path,
+    tools_path: &Path,
+) -> Result<(), super::Error> {
+    let files_to_check = rustdoc_js_files(librustdoc_path);
+    println!("Running eslint on rustdoc JS files");
+    run_eslint(outdir, &files_to_check, librustdoc_path.join("html/static"))?;
+
+    run_eslint(outdir, &[tools_path.join("rustdoc-js/tester.js")], tools_path.join("rustdoc-js"))?;
+    run_eslint(
+        outdir,
+        &[tools_path.join("rustdoc-gui/tester.js")],
+        tools_path.join("rustdoc-gui"),
+    )?;
+    Ok(())
+}
+
+pub(super) fn typecheck(outdir: &Path, librustdoc_path: &Path) -> Result<(), super::Error> {
+    // use npx to ensure correct version
+    let mut child = spawn_cmd(
+        Command::new(node_module_bin(outdir, "tsc"))
+            .arg("-p")
+            .arg(librustdoc_path.join("html/static/js/tsconfig.json")),
+    )?;
+    match child.wait() {
+        Ok(exit_status) => {
+            if exit_status.success() {
+                return Ok(());
+            }
+            Err(super::Error::FailedCheck("tsc command failed"))
+        }
+        Err(error) => Err(super::Error::Generic(format!("tsc command failed: {error:?}"))),
+    }
+}
+
+pub(super) fn es_check(outdir: &Path, librustdoc_path: &Path) -> Result<(), super::Error> {
+    let files_to_check = rustdoc_js_files(librustdoc_path);
+    let mut cmd = Command::new(node_module_bin(outdir, "es-check"));
+    cmd.arg("es2019");
+    for f in files_to_check {
+        cmd.arg(f);
+    }
+    match spawn_cmd(&mut cmd)?.wait() {
+        Ok(exit_status) => {
+            if exit_status.success() {
+                return Ok(());
+            }
+            Err(super::Error::FailedCheck("es-check command failed"))
+        }
+        Err(error) => Err(super::Error::Generic(format!("es-check command failed: {error:?}"))),
+    }
+}
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 77414bec82d..ee06707415f 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -1364,1230 +1364,6 @@ ui/infinite/issue-41731-infinite-macro-println.rs
 ui/intrinsics/issue-28575.rs
 ui/intrinsics/issue-84297-reifying-copy.rs
 ui/invalid/issue-114435-layout-type-err.rs
-ui/issues/auxiliary/issue-11224.rs
-ui/issues/auxiliary/issue-11508.rs
-ui/issues/auxiliary/issue-11529.rs
-ui/issues/auxiliary/issue-11680.rs
-ui/issues/auxiliary/issue-12612-1.rs
-ui/issues/auxiliary/issue-12612-2.rs
-ui/issues/auxiliary/issue-12660-aux.rs
-ui/issues/auxiliary/issue-13507.rs
-ui/issues/auxiliary/issue-13620-1.rs
-ui/issues/auxiliary/issue-13620-2.rs
-ui/issues/auxiliary/issue-14344-1.rs
-ui/issues/auxiliary/issue-14344-2.rs
-ui/issues/auxiliary/issue-14422.rs
-ui/issues/auxiliary/issue-15562.rs
-ui/issues/auxiliary/issue-16643.rs
-ui/issues/auxiliary/issue-16725.rs
-ui/issues/auxiliary/issue-17662.rs
-ui/issues/auxiliary/issue-18501.rs
-ui/issues/auxiliary/issue-18514.rs
-ui/issues/auxiliary/issue-18711.rs
-ui/issues/auxiliary/issue-18913-1.rs
-ui/issues/auxiliary/issue-18913-2.rs
-ui/issues/auxiliary/issue-19293.rs
-ui/issues/auxiliary/issue-20389.rs
-ui/issues/auxiliary/issue-21202.rs
-ui/issues/auxiliary/issue-2170-lib.rs
-ui/issues/auxiliary/issue-2316-a.rs
-ui/issues/auxiliary/issue-2316-b.rs
-ui/issues/auxiliary/issue-2380.rs
-ui/issues/auxiliary/issue-2414-a.rs
-ui/issues/auxiliary/issue-2414-b.rs
-ui/issues/auxiliary/issue-2472-b.rs
-ui/issues/auxiliary/issue-25185-1.rs
-ui/issues/auxiliary/issue-25185-2.rs
-ui/issues/auxiliary/issue-2526.rs
-ui/issues/auxiliary/issue-25467.rs
-ui/issues/auxiliary/issue-2631-a.rs
-ui/issues/auxiliary/issue-2723-a.rs
-ui/issues/auxiliary/issue-29265.rs
-ui/issues/auxiliary/issue-29485.rs
-ui/issues/auxiliary/issue-3012-1.rs
-ui/issues/auxiliary/issue-30123-aux.rs
-ui/issues/auxiliary/issue-3136-a.rs
-ui/issues/auxiliary/issue-31702-1.rs
-ui/issues/auxiliary/issue-31702-2.rs
-ui/issues/auxiliary/issue-34796-aux.rs
-ui/issues/auxiliary/issue-36954.rs
-ui/issues/auxiliary/issue-38190.rs
-ui/issues/auxiliary/issue-38226-aux.rs
-ui/issues/auxiliary/issue-3979-traits.rs
-ui/issues/auxiliary/issue-41053.rs
-ui/issues/auxiliary/issue-41549.rs
-ui/issues/auxiliary/issue-42007-s.rs
-ui/issues/auxiliary/issue-4208-cc.rs
-ui/issues/auxiliary/issue-4545.rs
-ui/issues/auxiliary/issue-48984-aux.rs
-ui/issues/auxiliary/issue-49544.rs
-ui/issues/auxiliary/issue-51798.rs
-ui/issues/auxiliary/issue-52489.rs
-ui/issues/auxiliary/issue-5518.rs
-ui/issues/auxiliary/issue-5521.rs
-ui/issues/auxiliary/issue-56943.rs
-ui/issues/auxiliary/issue-57271-lib.rs
-ui/issues/auxiliary/issue-5844-aux.rs
-ui/issues/auxiliary/issue-7178.rs
-ui/issues/auxiliary/issue-73112.rs
-ui/issues/auxiliary/issue-7899.rs
-ui/issues/auxiliary/issue-8044.rs
-ui/issues/auxiliary/issue-8259.rs
-ui/issues/auxiliary/issue-8401.rs
-ui/issues/auxiliary/issue-9123.rs
-ui/issues/auxiliary/issue-9155.rs
-ui/issues/auxiliary/issue-9188.rs
-ui/issues/auxiliary/issue-9906.rs
-ui/issues/auxiliary/issue-9968.rs
-ui/issues/issue-10228.rs
-ui/issues/issue-10291.rs
-ui/issues/issue-102964.rs
-ui/issues/issue-10396.rs
-ui/issues/issue-10412.rs
-ui/issues/issue-10436.rs
-ui/issues/issue-10456.rs
-ui/issues/issue-10465.rs
-ui/issues/issue-10545.rs
-ui/issues/issue-10638.rs
-ui/issues/issue-10656.rs
-ui/issues/issue-106755.rs
-ui/issues/issue-10683.rs
-ui/issues/issue-10718.rs
-ui/issues/issue-10734.rs
-ui/issues/issue-10764.rs
-ui/issues/issue-10767.rs
-ui/issues/issue-10802.rs
-ui/issues/issue-10806.rs
-ui/issues/issue-10853.rs
-ui/issues/issue-10877.rs
-ui/issues/issue-10902.rs
-ui/issues/issue-11004.rs
-ui/issues/issue-11047.rs
-ui/issues/issue-11085.rs
-ui/issues/issue-11192.rs
-ui/issues/issue-11205.rs
-ui/issues/issue-11224.rs
-ui/issues/issue-11267.rs
-ui/issues/issue-11374.rs
-ui/issues/issue-11382.rs
-ui/issues/issue-11384.rs
-ui/issues/issue-11508.rs
-ui/issues/issue-11529.rs
-ui/issues/issue-11552.rs
-ui/issues/issue-11592.rs
-ui/issues/issue-11677.rs
-ui/issues/issue-11680.rs
-ui/issues/issue-11681.rs
-ui/issues/issue-11709.rs
-ui/issues/issue-11740.rs
-ui/issues/issue-11771.rs
-ui/issues/issue-11820.rs
-ui/issues/issue-11844.rs
-ui/issues/issue-11869.rs
-ui/issues/issue-11958.rs
-ui/issues/issue-12033.rs
-ui/issues/issue-12041.rs
-ui/issues/issue-12127.rs
-ui/issues/issue-12285.rs
-ui/issues/issue-12567.rs
-ui/issues/issue-12612.rs
-ui/issues/issue-12660.rs
-ui/issues/issue-12677.rs
-ui/issues/issue-12729.rs
-ui/issues/issue-12744.rs
-ui/issues/issue-12860.rs
-ui/issues/issue-12863.rs
-ui/issues/issue-12909.rs
-ui/issues/issue-12920.rs
-ui/issues/issue-13027.rs
-ui/issues/issue-13058.rs
-ui/issues/issue-13105.rs
-ui/issues/issue-13167.rs
-ui/issues/issue-13202.rs
-ui/issues/issue-13204.rs
-ui/issues/issue-13214.rs
-ui/issues/issue-13259-windows-tcb-trash.rs
-ui/issues/issue-13264.rs
-ui/issues/issue-13323.rs
-ui/issues/issue-13359.rs
-ui/issues/issue-13405.rs
-ui/issues/issue-13407.rs
-ui/issues/issue-13434.rs
-ui/issues/issue-13446.rs
-ui/issues/issue-13466.rs
-ui/issues/issue-13482-2.rs
-ui/issues/issue-13482.rs
-ui/issues/issue-13497-2.rs
-ui/issues/issue-13497.rs
-ui/issues/issue-13507-2.rs
-ui/issues/issue-13620.rs
-ui/issues/issue-13665.rs
-ui/issues/issue-13703.rs
-ui/issues/issue-13763.rs
-ui/issues/issue-13775.rs
-ui/issues/issue-13808.rs
-ui/issues/issue-13847.rs
-ui/issues/issue-13867.rs
-ui/issues/issue-14082.rs
-ui/issues/issue-14091-2.rs
-ui/issues/issue-14091.rs
-ui/issues/issue-14092.rs
-ui/issues/issue-14229.rs
-ui/issues/issue-14254.rs
-ui/issues/issue-14285.rs
-ui/issues/issue-14308.rs
-ui/issues/issue-14330.rs
-ui/issues/issue-14344.rs
-ui/issues/issue-14366.rs
-ui/issues/issue-14382.rs
-ui/issues/issue-14393.rs
-ui/issues/issue-14399.rs
-ui/issues/issue-14422.rs
-ui/issues/issue-14541.rs
-ui/issues/issue-14721.rs
-ui/issues/issue-14821.rs
-ui/issues/issue-14845.rs
-ui/issues/issue-14853.rs
-ui/issues/issue-14865.rs
-ui/issues/issue-14875.rs
-ui/issues/issue-14901.rs
-ui/issues/issue-14915.rs
-ui/issues/issue-14919.rs
-ui/issues/issue-14959.rs
-ui/issues/issue-15034.rs
-ui/issues/issue-15043.rs
-ui/issues/issue-15063.rs
-ui/issues/issue-15094.rs
-ui/issues/issue-15104.rs
-ui/issues/issue-15129-rpass.rs
-ui/issues/issue-15167.rs
-ui/issues/issue-15189.rs
-ui/issues/issue-15207.rs
-ui/issues/issue-15260.rs
-ui/issues/issue-15381.rs
-ui/issues/issue-15444.rs
-ui/issues/issue-15523-big.rs
-ui/issues/issue-15523.rs
-ui/issues/issue-15562.rs
-ui/issues/issue-15571.rs
-ui/issues/issue-15673.rs
-ui/issues/issue-15734.rs
-ui/issues/issue-15735.rs
-ui/issues/issue-15756.rs
-ui/issues/issue-15763.rs
-ui/issues/issue-15774.rs
-ui/issues/issue-15783.rs
-ui/issues/issue-15793.rs
-ui/issues/issue-15858.rs
-ui/issues/issue-15896.rs
-ui/issues/issue-15965.rs
-ui/issues/issue-16048.rs
-ui/issues/issue-16149.rs
-ui/issues/issue-16151.rs
-ui/issues/issue-16256.rs
-ui/issues/issue-16278.rs
-ui/issues/issue-16401.rs
-ui/issues/issue-16441.rs
-ui/issues/issue-16452.rs
-ui/issues/issue-16492.rs
-ui/issues/issue-16530.rs
-ui/issues/issue-16560.rs
-ui/issues/issue-16562.rs
-ui/issues/issue-16596.rs
-ui/issues/issue-16643.rs
-ui/issues/issue-16648.rs
-ui/issues/issue-16668.rs
-ui/issues/issue-16671.rs
-ui/issues/issue-16683.rs
-ui/issues/issue-16725.rs
-ui/issues/issue-16739.rs
-ui/issues/issue-16745.rs
-ui/issues/issue-16774.rs
-ui/issues/issue-16783.rs
-ui/issues/issue-16819.rs
-ui/issues/issue-16922-rpass.rs
-ui/issues/issue-16966.rs
-ui/issues/issue-16994.rs
-ui/issues/issue-17001.rs
-ui/issues/issue-17033.rs
-ui/issues/issue-17068.rs
-ui/issues/issue-17121.rs
-ui/issues/issue-17216.rs
-ui/issues/issue-17252.rs
-ui/issues/issue-17322.rs
-ui/issues/issue-17336.rs
-ui/issues/issue-17337.rs
-ui/issues/issue-17351.rs
-ui/issues/issue-17361.rs
-ui/issues/issue-17373.rs
-ui/issues/issue-17385.rs
-ui/issues/issue-17405.rs
-ui/issues/issue-17441.rs
-ui/issues/issue-17450.rs
-ui/issues/issue-17503.rs
-ui/issues/issue-17546.rs
-ui/issues/issue-17551.rs
-ui/issues/issue-17651.rs
-ui/issues/issue-17662.rs
-ui/issues/issue-17732.rs
-ui/issues/issue-17734.rs
-ui/issues/issue-17740.rs
-ui/issues/issue-17746.rs
-ui/issues/issue-17758.rs
-ui/issues/issue-17771.rs
-ui/issues/issue-17800.rs
-ui/issues/issue-17816.rs
-ui/issues/issue-17877.rs
-ui/issues/issue-17897.rs
-ui/issues/issue-17904-2.rs
-ui/issues/issue-17904.rs
-ui/issues/issue-17905-2.rs
-ui/issues/issue-17905.rs
-ui/issues/issue-17933.rs
-ui/issues/issue-17954.rs
-ui/issues/issue-17959.rs
-ui/issues/issue-17994.rs
-ui/issues/issue-17999.rs
-ui/issues/issue-18058.rs
-ui/issues/issue-18088.rs
-ui/issues/issue-18107.rs
-ui/issues/issue-18110.rs
-ui/issues/issue-18119.rs
-ui/issues/issue-18159.rs
-ui/issues/issue-18173.rs
-ui/issues/issue-18183.rs
-ui/issues/issue-18188.rs
-ui/issues/issue-18232.rs
-ui/issues/issue-18352.rs
-ui/issues/issue-18353.rs
-ui/issues/issue-18389.rs
-ui/issues/issue-18423.rs
-ui/issues/issue-18446-2.rs
-ui/issues/issue-18446.rs
-ui/issues/issue-18464.rs
-ui/issues/issue-18501.rs
-ui/issues/issue-18514.rs
-ui/issues/issue-18532.rs
-ui/issues/issue-18539.rs
-ui/issues/issue-18566.rs
-ui/issues/issue-18611.rs
-ui/issues/issue-18685.rs
-ui/issues/issue-18711.rs
-ui/issues/issue-18767.rs
-ui/issues/issue-18783.rs
-ui/issues/issue-18809.rs
-ui/issues/issue-18845.rs
-ui/issues/issue-18859.rs
-ui/issues/issue-18906.rs
-ui/issues/issue-18913.rs
-ui/issues/issue-18919.rs
-ui/issues/issue-18952.rs
-ui/issues/issue-18959.rs
-ui/issues/issue-18988.rs
-ui/issues/issue-19001.rs
-ui/issues/issue-19037.rs
-ui/issues/issue-19086.rs
-ui/issues/issue-19097.rs
-ui/issues/issue-19098.rs
-ui/issues/issue-19100.rs
-ui/issues/issue-19127.rs
-ui/issues/issue-19135.rs
-ui/issues/issue-19293.rs
-ui/issues/issue-19367.rs
-ui/issues/issue-19380.rs
-ui/issues/issue-19398.rs
-ui/issues/issue-19404.rs
-ui/issues/issue-19479.rs
-ui/issues/issue-19482.rs
-ui/issues/issue-19499.rs
-ui/issues/issue-19601.rs
-ui/issues/issue-19631.rs
-ui/issues/issue-19632.rs
-ui/issues/issue-19692.rs
-ui/issues/issue-19734.rs
-ui/issues/issue-19811-escape-unicode.rs
-ui/issues/issue-19850.rs
-ui/issues/issue-19922.rs
-ui/issues/issue-19982.rs
-ui/issues/issue-19991.rs
-ui/issues/issue-20009.rs
-ui/issues/issue-20055-box-trait.rs
-ui/issues/issue-20055-box-unsized-array.rs
-ui/issues/issue-20162.rs
-ui/issues/issue-20174.rs
-ui/issues/issue-20186.rs
-ui/issues/issue-20225.rs
-ui/issues/issue-20261.rs
-ui/issues/issue-20313-rpass.rs
-ui/issues/issue-20313.rs
-ui/issues/issue-20389.rs
-ui/issues/issue-20396.rs
-ui/issues/issue-20413.rs
-ui/issues/issue-20414.rs
-ui/issues/issue-20427.rs
-ui/issues/issue-20433.rs
-ui/issues/issue-20454.rs
-ui/issues/issue-20544.rs
-ui/issues/issue-20575.rs
-ui/issues/issue-20644.rs
-ui/issues/issue-20676.rs
-ui/issues/issue-20714.rs
-ui/issues/issue-2074.rs
-ui/issues/issue-20772.rs
-ui/issues/issue-20797.rs
-ui/issues/issue-20803.rs
-ui/issues/issue-20831-debruijn.rs
-ui/issues/issue-20847.rs
-ui/issues/issue-20939.rs
-ui/issues/issue-20953.rs
-ui/issues/issue-20971.rs
-ui/issues/issue-21033.rs
-ui/issues/issue-21140.rs
-ui/issues/issue-21160.rs
-ui/issues/issue-21174-2.rs
-ui/issues/issue-21174.rs
-ui/issues/issue-21177.rs
-ui/issues/issue-21202.rs
-ui/issues/issue-21245.rs
-ui/issues/issue-21291.rs
-ui/issues/issue-21306.rs
-ui/issues/issue-21332.rs
-ui/issues/issue-21361.rs
-ui/issues/issue-21384.rs
-ui/issues/issue-21400.rs
-ui/issues/issue-21402.rs
-ui/issues/issue-21449.rs
-ui/issues/issue-2150.rs
-ui/issues/issue-2151.rs
-ui/issues/issue-21546.rs
-ui/issues/issue-21554.rs
-ui/issues/issue-21600.rs
-ui/issues/issue-21622.rs
-ui/issues/issue-21634.rs
-ui/issues/issue-21655.rs
-ui/issues/issue-2170-exe.rs
-ui/issues/issue-21701.rs
-ui/issues/issue-21763.rs
-ui/issues/issue-21891.rs
-ui/issues/issue-2190-1.rs
-ui/issues/issue-21909.rs
-ui/issues/issue-21922.rs
-ui/issues/issue-21946.rs
-ui/issues/issue-21950.rs
-ui/issues/issue-21974.rs
-ui/issues/issue-22008.rs
-ui/issues/issue-22034.rs
-ui/issues/issue-22036.rs
-ui/issues/issue-2214.rs
-ui/issues/issue-22258.rs
-ui/issues/issue-22289.rs
-ui/issues/issue-22312.rs
-ui/issues/issue-22346.rs
-ui/issues/issue-22356.rs
-ui/issues/issue-22370.rs
-ui/issues/issue-22403.rs
-ui/issues/issue-22426.rs
-ui/issues/issue-22434.rs
-ui/issues/issue-22468.rs
-ui/issues/issue-22471.rs
-ui/issues/issue-22577.rs
-ui/issues/issue-22599.rs
-ui/issues/issue-22603.rs
-ui/issues/issue-22629.rs
-ui/issues/issue-22638.rs
-ui/issues/issue-22644.rs
-ui/issues/issue-22673.rs
-ui/issues/issue-22684.rs
-ui/issues/issue-22706.rs
-ui/issues/issue-22777.rs
-ui/issues/issue-22781.rs
-ui/issues/issue-22789.rs
-ui/issues/issue-2281-part1.rs
-ui/issues/issue-22814.rs
-ui/issues/issue-2284.rs
-ui/issues/issue-22872.rs
-ui/issues/issue-22874.rs
-ui/issues/issue-2288.rs
-ui/issues/issue-22886.rs
-ui/issues/issue-22894.rs
-ui/issues/issue-22992-2.rs
-ui/issues/issue-22992.rs
-ui/issues/issue-23024.rs
-ui/issues/issue-23036.rs
-ui/issues/issue-23041.rs
-ui/issues/issue-23046.rs
-ui/issues/issue-23073.rs
-ui/issues/issue-2311-2.rs
-ui/issues/issue-2311.rs
-ui/issues/issue-2312.rs
-ui/issues/issue-2316-c.rs
-ui/issues/issue-23173.rs
-ui/issues/issue-23189.rs
-ui/issues/issue-23217.rs
-ui/issues/issue-23253.rs
-ui/issues/issue-23261.rs
-ui/issues/issue-23281.rs
-ui/issues/issue-23311.rs
-ui/issues/issue-23336.rs
-ui/issues/issue-23354-2.rs
-ui/issues/issue-23354.rs
-ui/issues/issue-23406.rs
-ui/issues/issue-23433.rs
-ui/issues/issue-23442.rs
-ui/issues/issue-23477.rs
-ui/issues/issue-23485.rs
-ui/issues/issue-23491.rs
-ui/issues/issue-23543.rs
-ui/issues/issue-23544.rs
-ui/issues/issue-23550.rs
-ui/issues/issue-23589.rs
-ui/issues/issue-23699.rs
-ui/issues/issue-2380-b.rs
-ui/issues/issue-2383.rs
-ui/issues/issue-23891.rs
-ui/issues/issue-23898.rs
-ui/issues/issue-23958.rs
-ui/issues/issue-23966.rs
-ui/issues/issue-23992.rs
-ui/issues/issue-24013.rs
-ui/issues/issue-24036.rs
-ui/issues/issue-24086.rs
-ui/issues/issue-2414-c.rs
-ui/issues/issue-24161.rs
-ui/issues/issue-24227.rs
-ui/issues/issue-2428.rs
-ui/issues/issue-24308.rs
-ui/issues/issue-24322.rs
-ui/issues/issue-24352.rs
-ui/issues/issue-24353.rs
-ui/issues/issue-24357.rs
-ui/issues/issue-24363.rs
-ui/issues/issue-24365.rs
-ui/issues/issue-24389.rs
-ui/issues/issue-24424.rs
-ui/issues/issue-24434.rs
-ui/issues/issue-2445-b.rs
-ui/issues/issue-2445.rs
-ui/issues/issue-24533.rs
-ui/issues/issue-24589.rs
-ui/issues/issue-2463.rs
-ui/issues/issue-24682.rs
-ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs
-ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs
-ui/issues/issue-2470-bounds-check-overflow.rs
-ui/issues/issue-2472.rs
-ui/issues/issue-24779.rs
-ui/issues/issue-24819.rs
-ui/issues/issue-2487-a.rs
-ui/issues/issue-24945-repeat-dash-opts.rs
-ui/issues/issue-24947.rs
-ui/issues/issue-24954.rs
-ui/issues/issue-2502.rs
-ui/issues/issue-25076.rs
-ui/issues/issue-25089.rs
-ui/issues/issue-25145.rs
-ui/issues/issue-25180.rs
-ui/issues/issue-25185.rs
-ui/issues/issue-2526-a.rs
-ui/issues/issue-25279.rs
-ui/issues/issue-25343.rs
-ui/issues/issue-25368.rs
-ui/issues/issue-25386.rs
-ui/issues/issue-25394.rs
-ui/issues/issue-25467.rs
-ui/issues/issue-25497.rs
-ui/issues/issue-2550.rs
-ui/issues/issue-25515.rs
-ui/issues/issue-25549-multiple-drop.rs
-ui/issues/issue-25579.rs
-ui/issues/issue-25679.rs
-ui/issues/issue-25693.rs
-ui/issues/issue-25746-bool-transmute.rs
-ui/issues/issue-25757.rs
-ui/issues/issue-25810.rs
-ui/issues/issue-2590.rs
-ui/issues/issue-25901.rs
-ui/issues/issue-26056.rs
-ui/issues/issue-26093.rs
-ui/issues/issue-26095.rs
-ui/issues/issue-26127.rs
-ui/issues/issue-26186.rs
-ui/issues/issue-26205.rs
-ui/issues/issue-26217.rs
-ui/issues/issue-26237.rs
-ui/issues/issue-2631-b.rs
-ui/issues/issue-2642.rs
-ui/issues/issue-26468.rs
-ui/issues/issue-26472.rs
-ui/issues/issue-26484.rs
-ui/issues/issue-26614.rs
-ui/issues/issue-26619.rs
-ui/issues/issue-26641.rs
-ui/issues/issue-26646.rs
-ui/issues/issue-26655.rs
-ui/issues/issue-26709.rs
-ui/issues/issue-26802.rs
-ui/issues/issue-26805.rs
-ui/issues/issue-26812.rs
-ui/issues/issue-26948.rs
-ui/issues/issue-26997.rs
-ui/issues/issue-27008.rs
-ui/issues/issue-27033.rs
-ui/issues/issue-27042.rs
-ui/issues/issue-27054-primitive-binary-ops.rs
-ui/issues/issue-27078.rs
-ui/issues/issue-2708.rs
-ui/issues/issue-27105.rs
-ui/issues/issue-2723-b.rs
-ui/issues/issue-27240.rs
-ui/issues/issue-27268.rs
-ui/issues/issue-27281.rs
-ui/issues/issue-27340.rs
-ui/issues/issue-27401-dropflag-reinit.rs
-ui/issues/issue-27433.rs
-ui/issues/issue-27592.rs
-ui/issues/issue-2761.rs
-ui/issues/issue-27639.rs
-ui/issues/issue-27697.rs
-ui/issues/issue-27815.rs
-ui/issues/issue-27842.rs
-ui/issues/issue-27889.rs
-ui/issues/issue-27942.rs
-ui/issues/issue-27949.rs
-ui/issues/issue-27997.rs
-ui/issues/issue-28105.rs
-ui/issues/issue-28109.rs
-ui/issues/issue-28181.rs
-ui/issues/issue-28279.rs
-ui/issues/issue-28344.rs
-ui/issues/issue-28433.rs
-ui/issues/issue-28472.rs
-ui/issues/issue-2848.rs
-ui/issues/issue-2849.rs
-ui/issues/issue-28498-must-work-ex1.rs
-ui/issues/issue-28498-must-work-ex2.rs
-ui/issues/issue-28498-ugeh-ex1.rs
-ui/issues/issue-28550.rs
-ui/issues/issue-28561.rs
-ui/issues/issue-28568.rs
-ui/issues/issue-28586.rs
-ui/issues/issue-28600.rs
-ui/issues/issue-28625.rs
-ui/issues/issue-28776.rs
-ui/issues/issue-28828.rs
-ui/issues/issue-28839.rs
-ui/issues/issue-28936.rs
-ui/issues/issue-2895.rs
-ui/issues/issue-28971.rs
-ui/issues/issue-28983.rs
-ui/issues/issue-28999.rs
-ui/issues/issue-29030.rs
-ui/issues/issue-29037.rs
-ui/issues/issue-2904.rs
-ui/issues/issue-29048.rs
-ui/issues/issue-29053.rs
-ui/issues/issue-29071-2.rs
-ui/issues/issue-29071.rs
-ui/issues/issue-29092.rs
-ui/issues/issue-29147-rpass.rs
-ui/issues/issue-29147.rs
-ui/issues/issue-29265.rs
-ui/issues/issue-29276.rs
-ui/issues/issue-2935.rs
-ui/issues/issue-29466.rs
-ui/issues/issue-29485.rs
-ui/issues/issue-2951.rs
-ui/issues/issue-29516.rs
-ui/issues/issue-29522.rs
-ui/issues/issue-29540.rs
-ui/issues/issue-29663.rs
-ui/issues/issue-29668.rs
-ui/issues/issue-29710.rs
-ui/issues/issue-29723.rs
-ui/issues/issue-29740.rs
-ui/issues/issue-29743.rs
-ui/issues/issue-29821.rs
-ui/issues/issue-29857.rs
-ui/issues/issue-29861.rs
-ui/issues/issue-2989.rs
-ui/issues/issue-29948.rs
-ui/issues/issue-2995.rs
-ui/issues/issue-30018-panic.rs
-ui/issues/issue-30081.rs
-ui/issues/issue-3012-2.rs
-ui/issues/issue-30123.rs
-ui/issues/issue-3021-b.rs
-ui/issues/issue-3021-d.rs
-ui/issues/issue-30236.rs
-ui/issues/issue-30255.rs
-ui/issues/issue-3026.rs
-ui/issues/issue-3029.rs
-ui/issues/issue-3037.rs
-ui/issues/issue-30371.rs
-ui/issues/issue-3038.rs
-ui/issues/issue-30380.rs
-ui/issues/issue-3052.rs
-ui/issues/issue-30530.rs
-ui/issues/issue-30589.rs
-ui/issues/issue-30615.rs
-ui/issues/issue-30756.rs
-ui/issues/issue-30891.rs
-ui/issues/issue-3091.rs
-ui/issues/issue-31011.rs
-ui/issues/issue-3109.rs
-ui/issues/issue-3121.rs
-ui/issues/issue-31267-additional.rs
-ui/issues/issue-31267.rs
-ui/issues/issue-31299.rs
-ui/issues/issue-3136-b.rs
-ui/issues/issue-3149.rs
-ui/issues/issue-31511.rs
-ui/issues/issue-3154.rs
-ui/issues/issue-31702.rs
-ui/issues/issue-31769.rs
-ui/issues/issue-31776.rs
-ui/issues/issue-31910.rs
-ui/issues/issue-32004.rs
-ui/issues/issue-32008.rs
-ui/issues/issue-32086.rs
-ui/issues/issue-3220.rs
-ui/issues/issue-32292.rs
-ui/issues/issue-32324.rs
-ui/issues/issue-32326.rs
-ui/issues/issue-32377.rs
-ui/issues/issue-32389.rs
-ui/issues/issue-32518.rs
-ui/issues/issue-32655.rs
-ui/issues/issue-32782.rs
-ui/issues/issue-32797.rs
-ui/issues/issue-32805.rs
-ui/issues/issue-3290.rs
-ui/issues/issue-32995-2.rs
-ui/issues/issue-32995.rs
-ui/issues/issue-33202.rs
-ui/issues/issue-33241.rs
-ui/issues/issue-33287.rs
-ui/issues/issue-33293.rs
-ui/issues/issue-33387.rs
-ui/issues/issue-3344.rs
-ui/issues/issue-33461.rs
-ui/issues/issue-33504.rs
-ui/issues/issue-33525.rs
-ui/issues/issue-33571.rs
-ui/issues/issue-33687.rs
-ui/issues/issue-33770.rs
-ui/issues/issue-3389.rs
-ui/issues/issue-33941.rs
-ui/issues/issue-34047.rs
-ui/issues/issue-34074.rs
-ui/issues/issue-34209.rs
-ui/issues/issue-34229.rs
-ui/issues/issue-3424.rs
-ui/issues/issue-3429.rs
-ui/issues/issue-34334.rs
-ui/issues/issue-34349.rs
-ui/issues/issue-34373.rs
-ui/issues/issue-34418.rs
-ui/issues/issue-34427.rs
-ui/issues/issue-3447.rs
-ui/issues/issue-34503.rs
-ui/issues/issue-34569.rs
-ui/issues/issue-34571.rs
-ui/issues/issue-34751.rs
-ui/issues/issue-3477.rs
-ui/issues/issue-34780.rs
-ui/issues/issue-34796.rs
-ui/issues/issue-34839.rs
-ui/issues/issue-3500.rs
-ui/issues/issue-35139.rs
-ui/issues/issue-3521-2.rs
-ui/issues/issue-35241.rs
-ui/issues/issue-35423.rs
-ui/issues/issue-3556.rs
-ui/issues/issue-35570.rs
-ui/issues/issue-3559.rs
-ui/issues/issue-35600.rs
-ui/issues/issue-3574.rs
-ui/issues/issue-35815.rs
-ui/issues/issue-35976.rs
-ui/issues/issue-35988.rs
-ui/issues/issue-36023.rs
-ui/issues/issue-36036-associated-type-layout.rs
-ui/issues/issue-36075.rs
-ui/issues/issue-3609.rs
-ui/issues/issue-36116.rs
-ui/issues/issue-36260.rs
-ui/issues/issue-36278-prefix-nesting.rs
-ui/issues/issue-36299.rs
-ui/issues/issue-36379.rs
-ui/issues/issue-36400.rs
-ui/issues/issue-36474.rs
-ui/issues/issue-3656.rs
-ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.rs
-ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.rs
-ui/issues/issue-36744-bitcast-args-if-needed.rs
-ui/issues/issue-36786-resolve-call.rs
-ui/issues/issue-3680.rs
-ui/issues/issue-36816.rs
-ui/issues/issue-36836.rs
-ui/issues/issue-36839.rs
-ui/issues/issue-36856.rs
-ui/issues/issue-36936.rs
-ui/issues/issue-36954.rs
-ui/issues/issue-3702-2.rs
-ui/issues/issue-3702.rs
-ui/issues/issue-37051.rs
-ui/issues/issue-37109.rs
-ui/issues/issue-37131.rs
-ui/issues/issue-37311-type-length-limit/issue-37311.rs
-ui/issues/issue-37510.rs
-ui/issues/issue-3753.rs
-ui/issues/issue-37534.rs
-ui/issues/issue-37576.rs
-ui/issues/issue-3763.rs
-ui/issues/issue-37665.rs
-ui/issues/issue-37686.rs
-ui/issues/issue-37725.rs
-ui/issues/issue-37733.rs
-ui/issues/issue-3779.rs
-ui/issues/issue-37884.rs
-ui/issues/issue-38160.rs
-ui/issues/issue-38190.rs
-ui/issues/issue-38226.rs
-ui/issues/issue-38381.rs
-ui/issues/issue-38412.rs
-ui/issues/issue-38437.rs
-ui/issues/issue-38458.rs
-ui/issues/issue-3847.rs
-ui/issues/issue-38556.rs
-ui/issues/issue-38727.rs
-ui/issues/issue-3874.rs
-ui/issues/issue-38763.rs
-ui/issues/issue-38857.rs
-ui/issues/issue-38875/auxiliary/issue-38875-b.rs
-ui/issues/issue-38875/issue-38875.rs
-ui/issues/issue-3888-2.rs
-ui/issues/issue-38919.rs
-ui/issues/issue-38942.rs
-ui/issues/issue-3895.rs
-ui/issues/issue-38954.rs
-ui/issues/issue-38987.rs
-ui/issues/issue-39089.rs
-ui/issues/issue-39211.rs
-ui/issues/issue-39367.rs
-ui/issues/issue-39548.rs
-ui/issues/issue-39687.rs
-ui/issues/issue-39709.rs
-ui/issues/issue-3979-2.rs
-ui/issues/issue-3979-xcrate.rs
-ui/issues/issue-3979.rs
-ui/issues/issue-39808.rs
-ui/issues/issue-39827.rs
-ui/issues/issue-39848.rs
-ui/issues/issue-3991.rs
-ui/issues/issue-3993.rs
-ui/issues/issue-39970.rs
-ui/issues/issue-39984.rs
-ui/issues/issue-40000.rs
-ui/issues/issue-4025.rs
-ui/issues/issue-40288-2.rs
-ui/issues/issue-40288.rs
-ui/issues/issue-40951.rs
-ui/issues/issue-41053.rs
-ui/issues/issue-41229-ref-str.rs
-ui/issues/issue-41298.rs
-ui/issues/issue-41479.rs
-ui/issues/issue-41498.rs
-ui/issues/issue-41549.rs
-ui/issues/issue-41604.rs
-ui/issues/issue-41652/auxiliary/issue-41652-b.rs
-ui/issues/issue-41652/issue-41652.rs
-ui/issues/issue-41677.rs
-ui/issues/issue-41696.rs
-ui/issues/issue-41726.rs
-ui/issues/issue-41742.rs
-ui/issues/issue-41744.rs
-ui/issues/issue-41849-variance-req.rs
-ui/issues/issue-41880.rs
-ui/issues/issue-41888.rs
-ui/issues/issue-41936-variance-coerce-unsized-cycle.rs
-ui/issues/issue-41974.rs
-ui/issues/issue-41998.rs
-ui/issues/issue-42007.rs
-ui/issues/issue-4208.rs
-ui/issues/issue-42106.rs
-ui/issues/issue-42148.rs
-ui/issues/issue-42210.rs
-ui/issues/issue-4228.rs
-ui/issues/issue-42312.rs
-ui/issues/issue-42453.rs
-ui/issues/issue-42467.rs
-ui/issues/issue-4252.rs
-ui/issues/issue-42552.rs
-ui/issues/issue-4265.rs
-ui/issues/issue-42755.rs
-ui/issues/issue-42796.rs
-ui/issues/issue-42880.rs
-ui/issues/issue-42956.rs
-ui/issues/issue-43057.rs
-ui/issues/issue-43205.rs
-ui/issues/issue-43250.rs
-ui/issues/issue-43291.rs
-ui/issues/issue-4333.rs
-ui/issues/issue-4335.rs
-ui/issues/issue-43355.rs
-ui/issues/issue-43357.rs
-ui/issues/issue-43420-no-over-suggest.rs
-ui/issues/issue-43424.rs
-ui/issues/issue-43431.rs
-ui/issues/issue-43483.rs
-ui/issues/issue-43692.rs
-ui/issues/issue-43806.rs
-ui/issues/issue-43853.rs
-ui/issues/issue-4387.rs
-ui/issues/issue-43910.rs
-ui/issues/issue-43923.rs
-ui/issues/issue-43988.rs
-ui/issues/issue-44023.rs
-ui/issues/issue-44056.rs
-ui/issues/issue-44078.rs
-ui/issues/issue-44216-add-instant.rs
-ui/issues/issue-44216-add-system-time.rs
-ui/issues/issue-44216-sub-instant.rs
-ui/issues/issue-44216-sub-system-time.rs
-ui/issues/issue-44239.rs
-ui/issues/issue-44247.rs
-ui/issues/issue-44405.rs
-ui/issues/issue-4464.rs
-ui/issues/issue-44730.rs
-ui/issues/issue-44851.rs
-ui/issues/issue-4517.rs
-ui/issues/issue-4541.rs
-ui/issues/issue-4542.rs
-ui/issues/issue-45425.rs
-ui/issues/issue-4545.rs
-ui/issues/issue-45510.rs
-ui/issues/issue-45562.rs
-ui/issues/issue-45697-1.rs
-ui/issues/issue-45697.rs
-ui/issues/issue-45730.rs
-ui/issues/issue-45731.rs
-ui/issues/issue-45801.rs
-ui/issues/issue-45965.rs
-ui/issues/issue-46069.rs
-ui/issues/issue-46101.rs
-ui/issues/issue-46302.rs
-ui/issues/issue-46311.rs
-ui/issues/issue-46332.rs
-ui/issues/issue-46471-1.rs
-ui/issues/issue-46472.rs
-ui/issues/issue-46604.rs
-ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.rs
-ui/issues/issue-46771.rs
-ui/issues/issue-46855.rs
-ui/issues/issue-46964.rs
-ui/issues/issue-46983.rs
-ui/issues/issue-47073-zero-padded-tuple-struct-indices.rs
-ui/issues/issue-47094.rs
-ui/issues/issue-47184.rs
-ui/issues/issue-47309.rs
-ui/issues/issue-4734.rs
-ui/issues/issue-4735.rs
-ui/issues/issue-4736.rs
-ui/issues/issue-47364.rs
-ui/issues/issue-47377.rs
-ui/issues/issue-47380.rs
-ui/issues/issue-47486.rs
-ui/issues/issue-4759-1.rs
-ui/issues/issue-4759.rs
-ui/issues/issue-47638.rs
-ui/issues/issue-47673.rs
-ui/issues/issue-47703-1.rs
-ui/issues/issue-47703-tuple.rs
-ui/issues/issue-47703.rs
-ui/issues/issue-47715.rs
-ui/issues/issue-47722.rs
-ui/issues/issue-48006.rs
-ui/issues/issue-48131.rs
-ui/issues/issue-48132.rs
-ui/issues/issue-48159.rs
-ui/issues/issue-48276.rs
-ui/issues/issue-4830.rs
-ui/issues/issue-48364.rs
-ui/issues/issue-48728.rs
-ui/issues/issue-4875.rs
-ui/issues/issue-48984.rs
-ui/issues/issue-49298.rs
-ui/issues/issue-4935.rs
-ui/issues/issue-49544.rs
-ui/issues/issue-49632.rs
-ui/issues/issue-4968.rs
-ui/issues/issue-4972.rs
-ui/issues/issue-49824.rs
-ui/issues/issue-49854.rs
-ui/issues/issue-49919.rs
-ui/issues/issue-49934-errors.rs
-ui/issues/issue-49934.rs
-ui/issues/issue-49955.rs
-ui/issues/issue-49973.rs
-ui/issues/issue-50187.rs
-ui/issues/issue-50411.rs
-ui/issues/issue-50415.rs
-ui/issues/issue-50442.rs
-ui/issues/issue-50471.rs
-ui/issues/issue-50518.rs
-ui/issues/issue-50581.rs
-ui/issues/issue-50582.rs
-ui/issues/issue-50585.rs
-ui/issues/issue-50600.rs
-ui/issues/issue-50618.rs
-ui/issues/issue-5062.rs
-ui/issues/issue-5067.rs
-ui/issues/issue-50688.rs
-ui/issues/issue-50714.rs
-ui/issues/issue-50761.rs
-ui/issues/issue-50781.rs
-ui/issues/issue-50802.rs
-ui/issues/issue-50811.rs
-ui/issues/issue-5100.rs
-ui/issues/issue-51022.rs
-ui/issues/issue-51044.rs
-ui/issues/issue-51102.rs
-ui/issues/issue-51116.rs
-ui/issues/issue-51154.rs
-ui/issues/issue-51515.rs
-ui/issues/issue-51632-try-desugar-incompatible-types.rs
-ui/issues/issue-51655.rs
-ui/issues/issue-51714.rs
-ui/issues/issue-51798.rs
-ui/issues/issue-51874.rs
-ui/issues/issue-51907.rs
-ui/issues/issue-5192.rs
-ui/issues/issue-51947.rs
-ui/issues/issue-52049.rs
-ui/issues/issue-52126-assign-op-invariance.rs
-ui/issues/issue-52262.rs
-ui/issues/issue-52489.rs
-ui/issues/issue-52533.rs
-ui/issues/issue-52717.rs
-ui/issues/issue-5280.rs
-ui/issues/issue-5315.rs
-ui/issues/issue-5321-immediates-with-bare-self.rs
-ui/issues/issue-53251.rs
-ui/issues/issue-53275.rs
-ui/issues/issue-53300.rs
-ui/issues/issue-53333.rs
-ui/issues/issue-53348.rs
-ui/issues/issue-53419.rs
-ui/issues/issue-53568.rs
-ui/issues/issue-5358-1.rs
-ui/issues/issue-53728.rs
-ui/issues/issue-53843.rs
-ui/issues/issue-54044.rs
-ui/issues/issue-54062.rs
-ui/issues/issue-54094.rs
-ui/issues/issue-5439.rs
-ui/issues/issue-54410.rs
-ui/issues/issue-54462-mutable-noalias-correctness.rs
-ui/issues/issue-54477-reduced-2.rs
-ui/issues/issue-54696.rs
-ui/issues/issue-5518.rs
-ui/issues/issue-5521.rs
-ui/issues/issue-55376.rs
-ui/issues/issue-55380.rs
-ui/issues/issue-5550.rs
-ui/issues/issue-5554.rs
-ui/issues/issue-55587.rs
-ui/issues/issue-5572.rs
-ui/issues/issue-55731.rs
-ui/issues/issue-56128.rs
-ui/issues/issue-56175.rs
-ui/issues/issue-56199.rs
-ui/issues/issue-56229.rs
-ui/issues/issue-56237.rs
-ui/issues/issue-5666.rs
-ui/issues/issue-56806.rs
-ui/issues/issue-56835.rs
-ui/issues/issue-56870.rs
-ui/issues/issue-5688.rs
-ui/issues/issue-56943.rs
-ui/issues/issue-5708.rs
-ui/issues/issue-57156.rs
-ui/issues/issue-57162.rs
-ui/issues/issue-5718.rs
-ui/issues/issue-57198-pass.rs
-ui/issues/issue-57271.rs
-ui/issues/issue-57399-self-return-impl-trait.rs
-ui/issues/issue-5741.rs
-ui/issues/issue-5754.rs
-ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.rs
-ui/issues/issue-57741-dereference-boxed-value/issue-57741.rs
-ui/issues/issue-57781.rs
-ui/issues/issue-57924.rs
-ui/issues/issue-58212.rs
-ui/issues/issue-58375-monomorphize-default-impls.rs
-ui/issues/issue-5844.rs
-ui/issues/issue-58463.rs
-ui/issues/issue-58712.rs
-ui/issues/issue-58734.rs
-ui/issues/issue-5883.rs
-ui/issues/issue-5884.rs
-ui/issues/issue-58857.rs
-ui/issues/issue-5900.rs
-ui/issues/issue-59020.rs
-ui/issues/issue-5917.rs
-ui/issues/issue-59326.rs
-ui/issues/issue-59488.rs
-ui/issues/issue-59494.rs
-ui/issues/issue-5950.rs
-ui/issues/issue-59756.rs
-ui/issues/issue-5988.rs
-ui/issues/issue-5997-outer-generic-parameter/issue-5997-enum.rs
-ui/issues/issue-5997-outer-generic-parameter/issue-5997-struct.rs
-ui/issues/issue-5997-outer-generic-parameter/issue-5997.rs
-ui/issues/issue-60218.rs
-ui/issues/issue-60622.rs
-ui/issues/issue-60989.rs
-ui/issues/issue-61106.rs
-ui/issues/issue-61108.rs
-ui/issues/issue-6117.rs
-ui/issues/issue-6130.rs
-ui/issues/issue-61475.rs
-ui/issues/issue-6153.rs
-ui/issues/issue-61623.rs
-ui/issues/issue-61894.rs
-ui/issues/issue-62480.rs
-ui/issues/issue-6318.rs
-ui/issues/issue-6344-let.rs
-ui/issues/issue-6344-match.rs
-ui/issues/issue-63983.rs
-ui/issues/issue-64430.rs
-ui/issues/issue-64559.rs
-ui/issues/issue-64593.rs
-ui/issues/issue-64792-bad-unicode-ctor.rs
-ui/issues/issue-65131.rs
-ui/issues/issue-65230.rs
-ui/issues/issue-65462.rs
-ui/issues/issue-6557.rs
-ui/issues/issue-66308.rs
-ui/issues/issue-66353.rs
-ui/issues/issue-66667-function-cmp-cycle.rs
-ui/issues/issue-66702-break-outside-loop-val.rs
-ui/issues/issue-66706.rs
-ui/issues/issue-66923-show-error-for-correct-call.rs
-ui/issues/issue-67039-unsound-pin-partialeq.rs
-ui/issues/issue-6738.rs
-ui/issues/issue-67535.rs
-ui/issues/issue-67552.rs
-ui/issues/issue-68010-large-zst-consts.rs
-ui/issues/issue-68696-catch-during-unwind.rs
-ui/issues/issue-6892.rs
-ui/issues/issue-68951.rs
-ui/issues/issue-6898.rs
-ui/issues/issue-69130.rs
-ui/issues/issue-6919.rs
-ui/issues/issue-69306.rs
-ui/issues/issue-6936.rs
-ui/issues/issue-69455.rs
-ui/issues/issue-69602-type-err-during-codegen-ice.rs
-ui/issues/issue-69683.rs
-ui/issues/issue-7012.rs
-ui/issues/issue-70381.rs
-ui/issues/issue-7044.rs
-ui/issues/issue-7061.rs
-ui/issues/issue-70673.rs
-ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs
-ui/issues/issue-70746.rs
-ui/issues/issue-7092.rs
-ui/issues/issue-71406.rs
-ui/issues/issue-7178.rs
-ui/issues/issue-72002.rs
-ui/issues/issue-72076.rs
-ui/issues/issue-72278.rs
-ui/issues/issue-7246.rs
-ui/issues/issue-7268.rs
-ui/issues/issue-72839-error-overflow.rs
-ui/issues/issue-72933-match-stack-overflow.rs
-ui/issues/issue-73112.rs
-ui/issues/issue-73229.rs
-ui/issues/issue-7344.rs
-ui/issues/issue-7364.rs
-ui/issues/issue-74082.rs
-ui/issues/issue-74564-if-expr-stack-overflow.rs
-ui/issues/issue-7519-match-unit-in-arg.rs
-ui/issues/issue-75283.rs
-ui/issues/issue-7563.rs
-ui/issues/issue-75704.rs
-ui/issues/issue-7575.rs
-ui/issues/issue-76042.rs
-ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.rs
-ui/issues/issue-76077-inaccesible-private-fields/issue-76077.rs
-ui/issues/issue-76191.rs
-ui/issues/issue-7660.rs
-ui/issues/issue-7663.rs
-ui/issues/issue-7673-cast-generically-implemented-trait.rs
-ui/issues/issue-77218/issue-77218-2.rs
-ui/issues/issue-77218/issue-77218.rs
-ui/issues/issue-7784.rs
-ui/issues/issue-77919.rs
-ui/issues/issue-78192.rs
-ui/issues/issue-78622.rs
-ui/issues/issue-7867.rs
-ui/issues/issue-78957.rs
-ui/issues/issue-7899.rs
-ui/issues/issue-7911.rs
-ui/issues/issue-7970a.rs
-ui/issues/issue-8044.rs
-ui/issues/issue-80607.rs
-ui/issues/issue-81584.rs
-ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs
-ui/issues/issue-81918.rs
-ui/issues/issue-8248.rs
-ui/issues/issue-8249.rs
-ui/issues/issue-8259.rs
-ui/issues/issue-83048.rs
-ui/issues/issue-8391.rs
-ui/issues/issue-8398.rs
-ui/issues/issue-8401.rs
-ui/issues/issue-8498.rs
-ui/issues/issue-8506.rs
-ui/issues/issue-8521.rs
-ui/issues/issue-85461.rs
-ui/issues/issue-8578.rs
-ui/issues/issue-86756.rs
-ui/issues/issue-87199.rs
-ui/issues/issue-8727.rs
-ui/issues/issue-87490.rs
-ui/issues/issue-8761.rs
-ui/issues/issue-8767.rs
-ui/issues/issue-87707.rs
-ui/issues/issue-8783.rs
-ui/issues/issue-88150.rs
-ui/issues/issue-8860.rs
-ui/issues/issue-8898.rs
-ui/issues/issue-9047.rs
-ui/issues/issue-9110.rs
-ui/issues/issue-9123.rs
-ui/issues/issue-9129.rs
-ui/issues/issue-91489.rs
-ui/issues/issue-9155.rs
-ui/issues/issue-9188.rs
-ui/issues/issue-9243.rs
-ui/issues/issue-9249.rs
-ui/issues/issue-9259.rs
-ui/issues/issue-92741.rs
-ui/issues/issue-9446.rs
-ui/issues/issue-9725.rs
-ui/issues/issue-9737.rs
-ui/issues/issue-9814.rs
-ui/issues/issue-98299.rs
-ui/issues/issue-9837.rs
-ui/issues/issue-9906.rs
-ui/issues/issue-9918.rs
-ui/issues/issue-9942.rs
-ui/issues/issue-9951.rs
-ui/issues/issue-9968.rs
-ui/issues/issue-99838.rs
 ui/iterators/issue-28098.rs
 ui/iterators/issue-58952-filter-type-length.rs
 ui/lang-items/issue-83471.rs
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index cb875504e1e..5f6796a9150 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -179,7 +179,6 @@ pub mod mir_opt_tests;
 pub mod pal;
 pub mod rustdoc_css_themes;
 pub mod rustdoc_gui_tests;
-pub mod rustdoc_js;
 pub mod rustdoc_json;
 pub mod rustdoc_templates;
 pub mod style;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index 0f1116a632e..11ee2ae688d 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -29,6 +29,7 @@ fn main() {
     let concurrency: NonZeroUsize =
         FromStr::from_str(&env::args().nth(4).expect("need concurrency"))
             .expect("concurrency must be a number");
+    let npm: PathBuf = env::args_os().nth(5).expect("need name/path of npm command").into();
 
     let root_manifest = root_path.join("Cargo.toml");
     let src_path = root_path.join("src");
@@ -112,7 +113,6 @@ fn main() {
         check!(rustdoc_gui_tests, &tests_path);
         check!(rustdoc_css_themes, &librustdoc_path);
         check!(rustdoc_templates, &librustdoc_path);
-        check!(rustdoc_js, &librustdoc_path, &tools_path, &src_path);
         check!(rustdoc_json, &src_path, &ci_info);
         check!(known_bug, &crashes_path);
         check!(unknown_revision, &tests_path);
@@ -181,6 +181,9 @@ fn main() {
             &root_path,
             &output_directory,
             &ci_info,
+            &librustdoc_path,
+            &tools_path,
+            &npm,
             bless,
             extra_checks,
             pos_args
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index b7d4a331891..5b8b44429bb 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -37,6 +37,7 @@ use crate::walk::{filter_dirs, walk};
 // Paths that may contain platform-specific code.
 const EXCEPTION_PATHS: &[&str] = &[
     "library/compiler-builtins",
+    "library/std_detect",
     "library/windows_targets",
     "library/panic_abort",
     "library/panic_unwind",
diff --git a/src/tools/tidy/src/rustdoc_js.rs b/src/tools/tidy/src/rustdoc_js.rs
deleted file mode 100644
index 5737fcbafc0..00000000000
--- a/src/tools/tidy/src/rustdoc_js.rs
+++ /dev/null
@@ -1,101 +0,0 @@
-//! Tidy check to ensure that rustdoc templates didn't forget a `{# #}` to strip extra whitespace
-//! characters.
-
-use std::ffi::OsStr;
-use std::path::{Path, PathBuf};
-use std::process::Command;
-
-use ignore::DirEntry;
-
-use crate::walk::walk_no_read;
-
-fn run_eslint(args: &[PathBuf], config_folder: PathBuf, bad: &mut bool) {
-    let mut child = match Command::new("npx")
-        .arg("eslint")
-        .arg("-c")
-        .arg(config_folder.join(".eslintrc.js"))
-        .args(args)
-        .spawn()
-    {
-        Ok(child) => child,
-        Err(error) => {
-            *bad = true;
-            eprintln!("failed to run eslint: {error:?}");
-            return;
-        }
-    };
-    match child.wait() {
-        Ok(exit_status) => {
-            if exit_status.success() {
-                return;
-            }
-            eprintln!("eslint command failed");
-        }
-        Err(error) => eprintln!("eslint command failed: {error:?}"),
-    }
-    *bad = true;
-}
-
-fn get_eslint_version_inner(global: bool) -> Option<String> {
-    let mut command = Command::new("npm");
-    command.arg("list").arg("--parseable").arg("--long").arg("--depth=0");
-    if global {
-        command.arg("--global");
-    }
-    let output = command.output().ok()?;
-    let lines = String::from_utf8_lossy(&output.stdout);
-    lines.lines().find_map(|l| l.split(':').nth(1)?.strip_prefix("eslint@")).map(|v| v.to_owned())
-}
-
-fn get_eslint_version() -> Option<String> {
-    get_eslint_version_inner(false).or_else(|| get_eslint_version_inner(true))
-}
-
-pub fn check(librustdoc_path: &Path, tools_path: &Path, src_path: &Path, bad: &mut bool) {
-    let eslint_version_path = src_path.join("ci/docker/host-x86_64/tidy/eslint.version");
-    let eslint_version = match std::fs::read_to_string(&eslint_version_path) {
-        Ok(version) => version.trim().to_string(),
-        Err(error) => {
-            *bad = true;
-            eprintln!("failed to read `{}`: {error:?}", eslint_version_path.display());
-            return;
-        }
-    };
-    // Having the correct `eslint` version installed via `npm` isn't strictly necessary, since we're invoking it via `npx`,
-    // but this check allows the vast majority that is not working on the rustdoc frontend to avoid the penalty of running
-    // `eslint` in tidy. See also: https://github.com/rust-lang/rust/pull/142851
-    match get_eslint_version() {
-        Some(version) => {
-            if version != eslint_version {
-                *bad = true;
-                eprintln!(
-                    "⚠️ Installed version of eslint (`{version}`) is different than the \
-                     one used in the CI (`{eslint_version}`)",
-                );
-                eprintln!(
-                    "You can install this version using `npm update eslint` or by using \
-                     `npm install eslint@{eslint_version}`",
-                );
-                return;
-            }
-        }
-        None => {
-            eprintln!("`eslint` doesn't seem to be installed. Skipping tidy check for JS files.");
-            eprintln!("You can install it using `npm install eslint@{eslint_version}`");
-            return;
-        }
-    }
-    let mut files_to_check = Vec::new();
-    walk_no_read(
-        &[&librustdoc_path.join("html/static/js")],
-        |path, is_dir| is_dir || path.extension().is_none_or(|ext| ext != OsStr::new("js")),
-        &mut |path: &DirEntry| {
-            files_to_check.push(path.path().into());
-        },
-    );
-    println!("Running eslint on rustdoc JS files");
-    run_eslint(&files_to_check, librustdoc_path.join("html/static"), bad);
-
-    run_eslint(&[tools_path.join("rustdoc-js/tester.js")], tools_path.join("rustdoc-js"), bad);
-    run_eslint(&[tools_path.join("rustdoc-gui/tester.js")], tools_path.join("rustdoc-gui"), bad);
-}
diff --git a/src/tools/tidy/src/target_policy.rs b/src/tools/tidy/src/target_policy.rs
index 776221d3062..550932dbfdc 100644
--- a/src/tools/tidy/src/target_policy.rs
+++ b/src/tools/tidy/src/target_policy.rs
@@ -8,7 +8,7 @@ use std::path::Path;
 use crate::walk::{filter_not_rust, walk};
 
 const TARGET_DEFINITIONS_PATH: &str = "compiler/rustc_target/src/spec/targets/";
-const ASSEMBLY_TEST_PATH: &str = "tests/assembly/targets/";
+const ASSEMBLY_LLVM_TEST_PATH: &str = "tests/assembly-llvm/targets/";
 const REVISION_LINE_START: &str = "//@ revisions: ";
 const EXCEPTIONS: &[&str] = &[
     // FIXME: disabled since it fails on CI saying the csky component is missing
@@ -43,7 +43,7 @@ pub fn check(root_path: &Path, bad: &mut bool) {
         let _ = targets_to_find.insert(target_name);
     }
 
-    walk(&root_path.join(ASSEMBLY_TEST_PATH), |_, _| false, &mut |_, contents| {
+    walk(&root_path.join(ASSEMBLY_LLVM_TEST_PATH), |_, _| false, &mut |_, contents| {
         for line in contents.lines() {
             let Some(_) = line.find(REVISION_LINE_START) else {
                 continue;
@@ -55,7 +55,7 @@ pub fn check(root_path: &Path, bad: &mut bool) {
 
     for target in targets_to_find {
         if !EXCEPTIONS.contains(&target.as_str()) {
-            tidy_error!(bad, "{ASSEMBLY_TEST_PATH}: missing assembly test for {target}")
+            tidy_error!(bad, "{ASSEMBLY_LLVM_TEST_PATH}: missing assembly test for {target}")
         }
     }
 }
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index b9d22ece597..4d195b3952e 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -1,24 +1,12 @@
 //! Tidy check to ensure below in UI test directories:
-//! - the number of entries in each directory must be less than `ENTRY_LIMIT`
 //! - there are no stray `.stderr` files
 
-use std::collections::{BTreeSet, HashMap};
+use std::collections::BTreeSet;
 use std::ffi::OsStr;
 use std::fs;
 use std::io::Write;
 use std::path::{Path, PathBuf};
 
-use ignore::Walk;
-
-// FIXME: GitHub's UI truncates file lists that exceed 1000 entries, so these
-// should all be 1000 or lower. Limits significantly smaller than 1000 are also
-// desirable, because large numbers of files are unwieldy in general. See issue
-// #73494.
-const ENTRY_LIMIT: u32 = 901;
-// FIXME: The following limits should be reduced eventually.
-
-const ISSUES_ENTRY_LIMIT: u32 = 1616;
-
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
     "stderr", // expected stderr file, corresponds to a rs file
@@ -54,42 +42,6 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
     "tests/ui/std/windows-bat-args3.bat", // tests escaping arguments through batch files
 ];
 
-fn check_entries(tests_path: &Path, bad: &mut bool) {
-    let mut directories: HashMap<PathBuf, u32> = HashMap::new();
-
-    for entry in Walk::new(tests_path.join("ui")).flatten() {
-        let parent = entry.path().parent().unwrap().to_path_buf();
-        *directories.entry(parent).or_default() += 1;
-    }
-
-    let (mut max, mut max_issues) = (0, 0);
-    for (dir_path, count) in directories {
-        let is_issues_dir = tests_path.join("ui/issues") == dir_path;
-        let (limit, maxcnt) = if is_issues_dir {
-            (ISSUES_ENTRY_LIMIT, &mut max_issues)
-        } else {
-            (ENTRY_LIMIT, &mut max)
-        };
-        *maxcnt = (*maxcnt).max(count);
-        if count > limit {
-            tidy_error!(
-                bad,
-                "following path contains more than {} entries, \
-                    you should move the test to some relevant subdirectory (current: {}): {}",
-                limit,
-                count,
-                dir_path.display()
-            );
-        }
-    }
-    if ISSUES_ENTRY_LIMIT > max_issues {
-        tidy_error!(
-            bad,
-            "`ISSUES_ENTRY_LIMIT` is too high (is {ISSUES_ENTRY_LIMIT}, should be {max_issues})"
-        );
-    }
-}
-
 pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
     let issues_txt_header = r#"============================================================
     ⚠️⚠️⚠️NOTHING SHOULD EVER BE ADDED TO THIS LIST⚠️⚠️⚠️
@@ -97,7 +49,6 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
 "#;
 
     let path = &root_path.join("tests");
-    check_entries(path, bad);
 
     // the list of files in ui tests that are allowed to start with `issue-XXXX`
     // BTreeSet because we would like a stable ordering so --bless works
@@ -179,7 +130,9 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
                     .unwrap()
                     .replace(std::path::MAIN_SEPARATOR_STR, "/");
 
-                if !remaining_issue_names.remove(stripped_path.as_str()) {
+                if !remaining_issue_names.remove(stripped_path.as_str())
+                    && !stripped_path.starts_with("ui/issues/")
+                {
                     tidy_error!(
                         bad,
                         "file `tests/{stripped_path}` must begin with a descriptive name, consider `{{reason}}-issue-{issue_n}.rs`",
diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs
index 90ef36d5882..df9146b5147 100644
--- a/src/tools/tidy/src/unit_tests.rs
+++ b/src/tools/tidy/src/unit_tests.rs
@@ -56,7 +56,8 @@ pub fn check(root_path: &Path, bad: &mut bool) {
             let line = line.trim();
             let is_test = || line.contains("#[test]") && !line.contains("`#[test]");
             let is_bench = || line.contains("#[bench]") && !line.contains("`#[bench]");
-            if !line.starts_with("//") && (is_test() || is_bench()) {
+            let manual_skip = line.contains("//tidy:skip");
+            if !line.starts_with("//") && (is_test() || is_bench()) && !manual_skip {
                 let explanation = if is_core {
                     "`core` unit tests and benchmarks must be placed into `coretests`"
                 } else if is_alloc {