diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 0a277fea49c12..d60bfb9faa1aa 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -970,6 +970,10 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
 
 /// Type utilities
 impl<'tcx> Ty<'tcx> {
+    // It would be nicer if this returned the value instead of a reference,
+    // like how `Predicate::kind` and `Region::kind` do. (It would result in
+    // many fewer subsequent dereferences.) But that gives a small but
+    // noticeable performance hit. See #126069 for details.
     #[inline(always)]
     pub fn kind(self) -> &'tcx TyKind<'tcx> {
         self.0.0
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index 29932c0d1ffeb..7e5c1574f5367 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -530,10 +530,18 @@ impl Waker {
 
     /// Returns a reference to a `Waker` that does nothing when used.
     ///
+    // Note!  Much of the documentation for this method is duplicated
+    // in the docs for `LocalWaker::noop`.
+    // If you edit it, consider editing the other copy too.
+    //
     /// This is mostly useful for writing tests that need a [`Context`] to poll
     /// some futures, but are not expecting those futures to wake the waker or
     /// do not need to do anything specific if it happens.
     ///
+    /// More generally, using `Waker::noop()` to poll a future
+    /// means discarding the notification of when the future should be polled again.
+    /// So it should only be used when such a notification will not be needed to make progress.
+    ///
     /// If an owned `Waker` is needed, `clone()` this one.
     ///
     /// # Examples
@@ -783,12 +791,22 @@ impl LocalWaker {
         Self { waker }
     }
 
-    /// Creates a new `LocalWaker` that does nothing when `wake` is called.
+    /// Returns a reference to a `LocalWaker` that does nothing when used.
     ///
+    // Note!  Much of the documentation for this method is duplicated
+    // in the docs for `Waker::noop`.
+    // If you edit it, consider editing the other copy too.
+    //
     /// This is mostly useful for writing tests that need a [`Context`] to poll
     /// some futures, but are not expecting those futures to wake the waker or
     /// do not need to do anything specific if it happens.
     ///
+    /// More generally, using `LocalWaker::noop()` to poll a future
+    /// means discarding the notification of when the future should be polled again,
+    /// So it should only be used when such a notification will not be needed to make progress.
+    ///
+    /// If an owned `LocalWaker` is needed, `clone()` this one.
+    ///
     /// # Examples
     ///
     /// ```
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index fd85650bc5620..0e44bd287c06d 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -703,9 +703,7 @@ download-rustc = false
             let file_times = fs::FileTimes::new().set_accessed(now).set_modified(now);
 
             let llvm_config = llvm_root.join("bin").join(exe("llvm-config", self.build));
-            let llvm_config_file = t!(File::options().write(true).open(llvm_config));
-
-            t!(llvm_config_file.set_times(file_times));
+            t!(crate::utils::helpers::set_file_times(llvm_config, file_times));
 
             if self.should_fix_bins_and_dylibs() {
                 let llvm_lib = llvm_root.join("lib");
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 1e2e90105a9a9..784519a20a2d8 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -37,7 +37,9 @@ use crate::core::builder;
 use crate::core::builder::{Builder, Kind};
 use crate::core::config::{flags, DryRun, LldMode, LlvmLibunwind, Target, TargetSelection};
 use crate::utils::exec::{command, BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode};
-use crate::utils::helpers::{self, dir_is_empty, exe, libdir, mtime, output, symlink_dir};
+use crate::utils::helpers::{
+    self, dir_is_empty, exe, libdir, mtime, output, set_file_times, symlink_dir,
+};
 
 mod core;
 mod utils;
@@ -1792,21 +1794,20 @@ Executed at: {executed_at}"#,
             }
         }
         if let Ok(()) = fs::hard_link(&src, dst) {
-            // Attempt to "easy copy" by creating a hard link
-            // (symlinks don't work on windows), but if that fails
-            // just fall back to a slow `copy` operation.
+            // Attempt to "easy copy" by creating a hard link (symlinks are priviledged on windows),
+            // but if that fails just fall back to a slow `copy` operation.
         } else {
             if let Err(e) = fs::copy(&src, dst) {
                 panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
             }
             t!(fs::set_permissions(dst, metadata.permissions()));
 
+            // Restore file times because changing permissions on e.g. Linux using `chmod` can cause
+            // file access time to change.
             let file_times = fs::FileTimes::new()
                 .set_accessed(t!(metadata.accessed()))
                 .set_modified(t!(metadata.modified()));
-
-            let dst_file = t!(fs::File::open(dst));
-            t!(dst_file.set_times(file_times));
+            t!(set_file_times(dst, file_times));
         }
     }
 
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 65e75f114bbeb..a856c99ff55a5 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -544,3 +544,15 @@ pub fn get_closest_merge_base_commit(
 
     Ok(output_result(git.as_command_mut())?.trim().to_owned())
 }
+
+/// Sets the file times for a given file at `path`.
+pub fn set_file_times<P: AsRef<Path>>(path: P, times: fs::FileTimes) -> io::Result<()> {
+    // Windows requires file to be writable to modify file times. But on Linux CI the file does not
+    // need to be writable to modify file times and might be read-only.
+    let f = if cfg!(windows) {
+        fs::File::options().write(true).open(path)?
+    } else {
+        fs::File::open(path)?
+    };
+    f.set_times(times)
+}
diff --git a/src/bootstrap/src/utils/helpers/tests.rs b/src/bootstrap/src/utils/helpers/tests.rs
index 103c4d26a1854..12719861f974b 100644
--- a/src/bootstrap/src/utils/helpers/tests.rs
+++ b/src/bootstrap/src/utils/helpers/tests.rs
@@ -3,7 +3,8 @@ use std::io::Write;
 use std::path::PathBuf;
 
 use crate::utils::helpers::{
-    check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, symlink_dir,
+    check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, set_file_times,
+    symlink_dir,
 };
 use crate::{Config, Flags};
 
@@ -92,3 +93,24 @@ fn test_symlink_dir() {
     #[cfg(not(windows))]
     fs::remove_file(link_path).unwrap();
 }
+
+#[test]
+fn test_set_file_times_sanity_check() {
+    let config = Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]);
+    let tempfile = config.tempdir().join(".tmp-file");
+
+    {
+        File::create(&tempfile).unwrap().write_all(b"dummy value").unwrap();
+        assert!(tempfile.exists());
+    }
+
+    // This might only fail on Windows (if file is default read-only then we try to modify file
+    // times).
+    let unix_epoch = std::time::SystemTime::UNIX_EPOCH;
+    let target_time = fs::FileTimes::new().set_accessed(unix_epoch).set_modified(unix_epoch);
+    set_file_times(&tempfile, target_time).unwrap();
+
+    let found_metadata = fs::metadata(tempfile).unwrap();
+    assert_eq!(found_metadata.accessed().unwrap(), unix_epoch);
+    assert_eq!(found_metadata.modified().unwrap(), unix_epoch)
+}
diff --git a/src/tools/run-make-support/src/external_deps/llvm.rs b/src/tools/run-make-support/src/external_deps/llvm.rs
index e1b7190f476d1..e9315856cd775 100644
--- a/src/tools/run-make-support/src/external_deps/llvm.rs
+++ b/src/tools/run-make-support/src/external_deps/llvm.rs
@@ -297,6 +297,12 @@ impl LlvmAr {
         self
     }
 
+    /// Print the table of contents.
+    pub fn table_of_contents(&mut self) -> &mut Self {
+        self.cmd.arg("t");
+        self
+    }
+
     /// Provide an output, then an input file. Bundled in one function, as llvm-ar has
     /// no "--output"-style flag.
     pub fn output_input(&mut self, out: impl AsRef<Path>, input: impl AsRef<Path>) -> &mut Self {
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index bc4465557738e..2e09b5ff14a52 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -9,13 +9,9 @@ run-make/incr-add-rust-src-component/Makefile
 run-make/issue-84395-lto-embed-bitcode/Makefile
 run-make/jobserver-error/Makefile
 run-make/libs-through-symlinks/Makefile
-run-make/libtest-json/Makefile
-run-make/libtest-junit/Makefile
 run-make/libtest-thread-limit/Makefile
 run-make/macos-deployment-target/Makefile
-run-make/native-link-modifier-bundle/Makefile
 run-make/reproducible-build/Makefile
-run-make/rlib-format-packed-bundled-libs/Makefile
 run-make/split-debuginfo/Makefile
 run-make/symbol-mangling-hashed/Makefile
 run-make/translation/Makefile
diff --git a/tests/crashes/128695.rs b/tests/crashes/128695.rs
new file mode 100644
index 0000000000000..661f427dc0e99
--- /dev/null
+++ b/tests/crashes/128695.rs
@@ -0,0 +1,11 @@
+//@ known-bug: rust-lang/rust#128695
+//@ edition: 2021
+
+use core::pin::{pin, Pin};
+
+fn main() {
+    let fut = pin!(async {
+        let async_drop_fut = pin!(core::future::async_drop(async {}));
+        (async_drop_fut).await;
+    });
+}
diff --git a/tests/crashes/128810.rs b/tests/crashes/128810.rs
new file mode 100644
index 0000000000000..68214ff010c99
--- /dev/null
+++ b/tests/crashes/128810.rs
@@ -0,0 +1,25 @@
+//@ known-bug: rust-lang/rust#128810
+
+#![feature(fn_delegation)]
+
+use std::marker::PhantomData;
+
+pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>);
+
+impl<'a> InvariantRef<'a, ()> {
+    pub const NEW: Self = InvariantRef::new(&());
+}
+
+trait Trait {
+    fn foo(&self) -> u8 { 0 }
+    fn bar(&self) -> u8 { 1 }
+    fn meh(&self) -> u8 { 2 }
+}
+
+struct Z(u8);
+
+impl Trait for Z {
+    reuse <u8 as Trait>::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW } }
+}
+
+fn main() { }
diff --git a/tests/crashes/128848.rs b/tests/crashes/128848.rs
new file mode 100644
index 0000000000000..636811fc6b504
--- /dev/null
+++ b/tests/crashes/128848.rs
@@ -0,0 +1,5 @@
+//@ known-bug: rust-lang/rust#128848
+
+fn f<T>(a: T, b: T, c: T)  {
+    f.call_once()
+}
diff --git a/tests/crashes/128870.rs b/tests/crashes/128870.rs
new file mode 100644
index 0000000000000..2b7319621440c
--- /dev/null
+++ b/tests/crashes/128870.rs
@@ -0,0 +1,18 @@
+//@ known-bug: rust-lang/rust#128870
+//@ compile-flags: -Zvalidate-mir
+
+#[repr(packed)]
+#[repr(u32)]
+enum E {
+    A,
+    B,
+    C,
+}
+
+fn main() {
+    union InvalidTag {
+        int: u32,
+        e: E,
+    }
+    let _invalid_tag = InvalidTag { int: 4 };
+}
diff --git a/tests/crashes/129075.rs b/tests/crashes/129075.rs
new file mode 100644
index 0000000000000..4a0e920914cc5
--- /dev/null
+++ b/tests/crashes/129075.rs
@@ -0,0 +1,16 @@
+//@ known-bug: rust-lang/rust#129075
+//@ compile-flags: -Zvalidate-mir -Zinline-mir=yes
+
+struct Foo<T>([T; 2]);
+
+impl<T: Default + Copy> Default for Foo<T> {
+    fn default(&mut self) -> Self {
+        Foo([Default::default(); 2])
+    }
+}
+
+fn field_array() {
+    let a: i32;
+    let b;
+    Foo([a, b]) = Default::default();
+}
diff --git a/tests/crashes/129095.rs b/tests/crashes/129095.rs
new file mode 100644
index 0000000000000..ea70c0565fc36
--- /dev/null
+++ b/tests/crashes/129095.rs
@@ -0,0 +1,10 @@
+//@ known-bug: rust-lang/rust#129095
+//@ compile-flags: -Zmir-opt-level=5 -Zvalidate-mir
+
+pub fn function_with_bytes<const BYTES: &'static [u8; 4]>() -> &'static [u8] {
+    BYTES
+}
+
+pub fn main() {
+    assert_eq!(function_with_bytes::<b"AAAAb">(), &[0x41, 0x41, 0x41, 0x41]);
+}
diff --git a/tests/crashes/129099.rs b/tests/crashes/129099.rs
new file mode 100644
index 0000000000000..9aaab756b5b8d
--- /dev/null
+++ b/tests/crashes/129099.rs
@@ -0,0 +1,15 @@
+//@ known-bug: rust-lang/rust#129099
+
+#![feature(type_alias_impl_trait)]
+
+fn dyn_hoops<T: Sized>() -> dyn for<'a> Iterator<Item = impl Captures<'a>> {
+    loop {}
+}
+
+pub fn main() {
+    type Opaque = impl Sized;
+    fn define() -> Opaque {
+        let x: Opaque = dyn_hoops::<()>(0);
+        x
+    }
+}
diff --git a/tests/crashes/129109.rs b/tests/crashes/129109.rs
new file mode 100644
index 0000000000000..8b9ebdf03c779
--- /dev/null
+++ b/tests/crashes/129109.rs
@@ -0,0 +1,10 @@
+//@ known-bug: rust-lang/rust#129109
+//@ compile-flags: -Zmir-opt-level=5 -Zvalidate-mir
+
+extern "C" {
+    pub static mut symbol: [i8];
+}
+
+fn main() {
+    println!("C", unsafe { &symbol });
+}
diff --git a/tests/crashes/129127.rs b/tests/crashes/129127.rs
new file mode 100644
index 0000000000000..8ec848dbd0578
--- /dev/null
+++ b/tests/crashes/129127.rs
@@ -0,0 +1,21 @@
+//@ known-bug: rust-lang/rust#129127
+//@ compile-flags: -Zmir-opt-level=5 -Zvalidate-mir -Zcross-crate-inline-threshold=always
+
+
+
+
+pub struct Rows<'a>();
+
+impl<'a> Iterator for Rows<'a> {
+    type Item = ();
+
+    fn next() -> Option<Self::Item> {
+        let mut rows = Rows();
+        rows.map(|row| row).next()
+    }
+}
+
+fn main() {
+    let mut rows = Rows();
+    rows.next();
+}
diff --git a/tests/run-make/libtest-json/Makefile b/tests/run-make/libtest-json/Makefile
deleted file mode 100644
index c8bc7b5dd4a4c..0000000000000
--- a/tests/run-make/libtest-json/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# ignore-cross-compile
-# needs-unwind
-include ../tools.mk
-
-# Test expected libtest's JSON output
-
-OUTPUT_FILE_DEFAULT := $(TMPDIR)/libtest-json-output-default.json
-OUTPUT_FILE_STDOUT_SUCCESS := $(TMPDIR)/libtest-json-output-stdout-success.json
-
-all: f.rs validate_json.py output-default.json output-stdout-success.json
-	$(RUSTC) --test f.rs
-	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json > $(OUTPUT_FILE_DEFAULT) || true
-	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json --show-output > $(OUTPUT_FILE_STDOUT_SUCCESS) || true
-
-	cat $(OUTPUT_FILE_DEFAULT) | "$(PYTHON)" validate_json.py
-	cat $(OUTPUT_FILE_STDOUT_SUCCESS) | "$(PYTHON)" validate_json.py
-
-	# Normalize the actual output and compare to expected output file
-	cat $(OUTPUT_FILE_DEFAULT) | sed 's/"exec_time": [0-9.]*/"exec_time": $$TIME/' | diff output-default.json -
-	cat $(OUTPUT_FILE_STDOUT_SUCCESS) | sed 's/"exec_time": [0-9.]*/"exec_time": $$TIME/' | diff output-stdout-success.json -
diff --git a/tests/run-make/libtest-json/output-default.json b/tests/run-make/libtest-json/output-default.json
index 01710f59e5d74..a2293a032d012 100644
--- a/tests/run-make/libtest-json/output-default.json
+++ b/tests/run-make/libtest-json/output-default.json
@@ -7,4 +7,4 @@
 { "type": "test", "name": "c", "event": "ok" }
 { "type": "test", "event": "started", "name": "d" }
 { "type": "test", "name": "d", "event": "ignored", "message": "msg" }
-{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
+{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": "$EXEC_TIME" }
diff --git a/tests/run-make/libtest-json/output-stdout-success.json b/tests/run-make/libtest-json/output-stdout-success.json
index 878eb6c7c260d..cf92f01f63aca 100644
--- a/tests/run-make/libtest-json/output-stdout-success.json
+++ b/tests/run-make/libtest-json/output-stdout-success.json
@@ -7,4 +7,4 @@
 { "type": "test", "name": "c", "event": "ok", "stdout": "thread 'c' panicked at f.rs:15:5:\nassertion failed: false\n" }
 { "type": "test", "event": "started", "name": "d" }
 { "type": "test", "name": "d", "event": "ignored", "message": "msg" }
-{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
+{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": "$EXEC_TIME" }
diff --git a/tests/run-make/libtest-json/rmake.rs b/tests/run-make/libtest-json/rmake.rs
new file mode 100644
index 0000000000000..acbd88dc46cb9
--- /dev/null
+++ b/tests/run-make/libtest-json/rmake.rs
@@ -0,0 +1,31 @@
+// Check libtest's JSON output against snapshots.
+
+//@ ignore-cross-compile
+//@ needs-unwind (test file contains #[should_panic] test)
+
+use run_make_support::{cmd, diff, python_command, rustc};
+
+fn main() {
+    rustc().arg("--test").input("f.rs").run();
+
+    run_tests(&[], "output-default.json");
+    run_tests(&["--show-output"], "output-stdout-success.json");
+}
+
+#[track_caller]
+fn run_tests(extra_args: &[&str], expected_file: &str) {
+    let cmd_out = cmd("./f")
+        .env("RUST_BACKTRACE", "0")
+        .args(&["-Zunstable-options", "--test-threads=1", "--format=json"])
+        .args(extra_args)
+        .run_fail();
+    let test_stdout = &cmd_out.stdout_utf8();
+
+    python_command().arg("validate_json.py").stdin(test_stdout).run();
+
+    diff()
+        .expected_file(expected_file)
+        .actual_text("stdout", test_stdout)
+        .normalize(r#"(?<prefix>"exec_time": )[0-9.]+"#, r#"${prefix}"$$EXEC_TIME""#)
+        .run();
+}
diff --git a/tests/run-make/libtest-junit/Makefile b/tests/run-make/libtest-junit/Makefile
deleted file mode 100644
index 26e56242dd239..0000000000000
--- a/tests/run-make/libtest-junit/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# ignore-cross-compile
-# needs-unwind contains should_panic test
-include ../tools.mk
-
-# Test expected libtest's junit output
-
-OUTPUT_FILE_DEFAULT := $(TMPDIR)/libtest-junit-output-default.xml
-OUTPUT_FILE_STDOUT_SUCCESS := $(TMPDIR)/libtest-junit-output-stdout-success.xml
-
-all: f.rs validate_junit.py output-default.xml output-stdout-success.xml
-	$(RUSTC) --test f.rs
-	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=junit > $(OUTPUT_FILE_DEFAULT) || true
-	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=junit --show-output > $(OUTPUT_FILE_STDOUT_SUCCESS) || true
-
-	cat $(OUTPUT_FILE_DEFAULT) | "$(PYTHON)" validate_junit.py
-	cat $(OUTPUT_FILE_STDOUT_SUCCESS) | "$(PYTHON)" validate_junit.py
-
-	# Normalize the actual output and compare to expected output file
-	cat $(OUTPUT_FILE_DEFAULT) | sed 's/time="[0-9.]*"/time="$$TIME"/g' | diff output-default.xml -
-	cat $(OUTPUT_FILE_STDOUT_SUCCESS) | sed 's/time="[0-9.]*"/time="$$TIME"/g' | diff output-stdout-success.xml -
diff --git a/tests/run-make/libtest-junit/rmake.rs b/tests/run-make/libtest-junit/rmake.rs
new file mode 100644
index 0000000000000..d631313ed9210
--- /dev/null
+++ b/tests/run-make/libtest-junit/rmake.rs
@@ -0,0 +1,31 @@
+// Check libtest's JUnit (XML) output against snapshots.
+
+//@ ignore-cross-compile
+//@ needs-unwind (test file contains #[should_panic] test)
+
+use run_make_support::{cmd, diff, python_command, rustc};
+
+fn main() {
+    rustc().arg("--test").input("f.rs").run();
+
+    run_tests(&[], "output-default.xml");
+    run_tests(&["--show-output"], "output-stdout-success.xml");
+}
+
+#[track_caller]
+fn run_tests(extra_args: &[&str], expected_file: &str) {
+    let cmd_out = cmd("./f")
+        .env("RUST_BACKTRACE", "0")
+        .args(&["-Zunstable-options", "--test-threads=1", "--format=junit"])
+        .args(extra_args)
+        .run_fail();
+    let test_stdout = &cmd_out.stdout_utf8();
+
+    python_command().arg("validate_junit.py").stdin(test_stdout).run();
+
+    diff()
+        .expected_file(expected_file)
+        .actual_text("stdout", test_stdout)
+        .normalize(r#"\btime="[0-9.]+""#, r#"time="$$TIME""#)
+        .run();
+}
diff --git a/tests/run-make/native-link-modifier-bundle/Makefile b/tests/run-make/native-link-modifier-bundle/Makefile
deleted file mode 100644
index 527720922fe58..0000000000000
--- a/tests/run-make/native-link-modifier-bundle/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# ignore-cross-compile
-# ignore-windows-msvc
-
-include ../tools.mk
-
-# We're using the llvm-nm instead of the system nm to ensure it is compatible
-# with the LLVM bitcode generated by rustc.
-# Except on Windows where piping/IO redirection under MSYS2 is wonky with llvm-nm.
-ifndef IS_WINDOWS
-NM = "$(LLVM_BIN_DIR)"/llvm-nm
-else
-NM = nm
-endif
-
-all: $(call NATIVE_STATICLIB,native-staticlib)
-	# Build a staticlib and a rlib, the `native_func` symbol will be bundled into them
-	$(RUSTC) bundled.rs --crate-type=staticlib --crate-type=rlib
-	$(NM) $(TMPDIR)/libbundled.a | $(CGREP) -e "T _*native_func"
-	$(NM) $(TMPDIR)/libbundled.a | $(CGREP) -e "U _*native_func"
-	$(NM) $(TMPDIR)/libbundled.rlib | $(CGREP) -e "T _*native_func"
-	$(NM) $(TMPDIR)/libbundled.rlib | $(CGREP) -e "U _*native_func"
-
-	# Build a staticlib and a rlib, the `native_func` symbol will not be bundled into it
-	$(RUSTC) non-bundled.rs --crate-type=staticlib --crate-type=rlib
-	$(NM) $(TMPDIR)/libnon_bundled.a | $(CGREP) -ve "T _*native_func"
-	$(NM) $(TMPDIR)/libnon_bundled.a | $(CGREP) -e "U _*native_func"
-	$(NM) $(TMPDIR)/libnon_bundled.rlib | $(CGREP) -ve "T _*native_func"
-	$(NM) $(TMPDIR)/libnon_bundled.rlib | $(CGREP) -e "U _*native_func"
-
-	# Build a cdylib, `native-staticlib` will not appear on the linker line because it was bundled previously
-	# The cdylib will contain the `native_func` symbol in the end
-	$(RUSTC) cdylib-bundled.rs --crate-type=cdylib --print link-args | $(CGREP) -ve '-l[" ]*native-staticlib'
-	$(NM) $(call DYLIB,cdylib_bundled) | $(CGREP) -e "[Tt] _*native_func"
-
-	# Build a cdylib, `native-staticlib` will appear on the linker line because it was not bundled previously
-	# The cdylib will contain the `native_func` symbol in the end
-	$(RUSTC) cdylib-non-bundled.rs --crate-type=cdylib --print link-args | $(CGREP) -e '-l[" ]*native-staticlib'
-	$(NM) $(call DYLIB,cdylib_non_bundled) | $(CGREP) -e "[Tt] _*native_func"
diff --git a/tests/run-make/native-link-modifier-bundle/rmake.rs b/tests/run-make/native-link-modifier-bundle/rmake.rs
new file mode 100644
index 0000000000000..058b66b15f12f
--- /dev/null
+++ b/tests/run-make/native-link-modifier-bundle/rmake.rs
@@ -0,0 +1,90 @@
+// This test exercises the `bundle` link argument, which can be turned on or off.
+
+// When building a rlib or staticlib, +bundle means that all object files from the native static
+// library will be added to the rlib or staticlib archive, and then used from it during linking of
+// the final binary.
+
+// When building a rlib -bundle means that the native static library is registered as a dependency
+// of that rlib "by name", and object files from it are included only during linking of the final
+// binary, the file search by that name is also performed during final linking.
+// When building a staticlib -bundle means that the native static library is simply not included
+// into the archive and some higher level build system will need to add it later during linking of
+// the final binary.
+
+// This modifier has no effect when building other targets like executables or dynamic libraries.
+
+// The default for this modifier is +bundle.
+// See https://github.com/rust-lang/rust/pull/95818
+
+//@ ignore-cross-compile
+// Reason: cross-compilation fails to export native symbols
+
+use run_make_support::{
+    build_native_static_lib, dynamic_lib_name, is_msvc, llvm_nm, rust_lib_name, rustc,
+    static_lib_name,
+};
+
+fn main() {
+    build_native_static_lib("native-staticlib");
+    // Build a staticlib and a rlib, the `native_func` symbol will be bundled into them
+    rustc().input("bundled.rs").crate_type("staticlib").crate_type("rlib").run();
+    llvm_nm()
+        .input(static_lib_name("bundled"))
+        .run()
+        .assert_stdout_contains_regex("T _*native_func");
+    llvm_nm()
+        .input(static_lib_name("bundled"))
+        .run()
+        .assert_stdout_contains_regex("U _*native_func");
+    llvm_nm().input(rust_lib_name("bundled")).run().assert_stdout_contains_regex("T _*native_func");
+    llvm_nm().input(rust_lib_name("bundled")).run().assert_stdout_contains_regex("U _*native_func");
+
+    // Build a staticlib and a rlib, the `native_func` symbol will not be bundled into it
+    build_native_static_lib("native-staticlib");
+    rustc().input("non-bundled.rs").crate_type("staticlib").crate_type("rlib").run();
+    llvm_nm()
+        .input(static_lib_name("non_bundled"))
+        .run()
+        .assert_stdout_not_contains_regex("T _*native_func");
+    llvm_nm()
+        .input(static_lib_name("non_bundled"))
+        .run()
+        .assert_stdout_contains_regex("U _*native_func");
+    llvm_nm()
+        .input(rust_lib_name("non_bundled"))
+        .run()
+        .assert_stdout_not_contains_regex("T _*native_func");
+    llvm_nm()
+        .input(rust_lib_name("non_bundled"))
+        .run()
+        .assert_stdout_contains_regex("U _*native_func");
+
+    // This part of the test does not function on Windows MSVC - no symbols are printed.
+    if !is_msvc() {
+        // Build a cdylib, `native-staticlib` will not appear on the linker line because it was
+        // bundled previously. The cdylib will contain the `native_func` symbol in the end.
+        rustc()
+            .input("cdylib-bundled.rs")
+            .crate_type("cdylib")
+            .print("link-args")
+            .run()
+            .assert_stdout_not_contains(r#"-l[" ]*native-staticlib"#);
+        llvm_nm()
+            .input(dynamic_lib_name("cdylib_bundled"))
+            .run()
+            .assert_stdout_contains_regex("[Tt] _*native_func");
+
+        // Build a cdylib, `native-staticlib` will appear on the linker line because it was not
+        // bundled previously. The cdylib will contain the `native_func` symbol in the end
+        rustc()
+            .input("cdylib-non-bundled.rs")
+            .crate_type("cdylib")
+            .print("link-args")
+            .run()
+            .assert_stdout_contains_regex(r#"-l[" ]*native-staticlib"#);
+        llvm_nm()
+            .input(dynamic_lib_name("cdylib_non_bundled"))
+            .run()
+            .assert_stdout_contains_regex("[Tt] _*native_func");
+    }
+}
diff --git a/tests/run-make/rlib-format-packed-bundled-libs/Makefile b/tests/run-make/rlib-format-packed-bundled-libs/Makefile
deleted file mode 100644
index f454da67893d0..0000000000000
--- a/tests/run-make/rlib-format-packed-bundled-libs/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-include ../tools.mk
-
-# ignore-cross-compile
-
-# Make sure rlib format with -Zpacked_bundled_libs is correct.
-
-# We're using the llvm-nm instead of the system nm to ensure it is compatible
-# with the LLVM bitcode generated by rustc.
-# Except on Windows where piping/IO redirection under MSYS2 is wonky with llvm-nm.
-ifndef IS_WINDOWS
-NM = "$(LLVM_BIN_DIR)"/llvm-nm
-else
-NM = nm
-endif
-
-all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3)
-	$(RUSTC) rust_dep_up.rs --crate-type=rlib -Zpacked_bundled_libs
-	$(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f2"
-	$(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f3"
-	$(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "T.*rust_dep_up"
-	$(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_2"
-	$(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_3"
-	$(RUSTC) rust_dep_local.rs --extern rlib=$(TMPDIR)/librust_dep_up.rlib -Zpacked_bundled_libs --crate-type=rlib
-	$(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "U.*native_f1"
-	$(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "T.*rust_dep_local"
-	$(AR) t $(TMPDIR)/librust_dep_local.rlib | $(CGREP) "native_dep_1"
-
-	# Make sure compiler doesn't use files, that it shouldn't know about.
-	rm $(TMPDIR)/*native_dep_*
-
-	$(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_local.rlib -o $(TMPDIR)/main.exe -Zpacked_bundled_libs --print link-args | $(CGREP) -e "native_dep_1.*native_dep_2.*native_dep_3"
-
-ifndef IS_MSVC
-	$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f1"
-	$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f2"
-	$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f3"
-	$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_local"
-	$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_up"
-endif
diff --git a/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs b/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs
new file mode 100644
index 0000000000000..ff0438a6b72be
--- /dev/null
+++ b/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs
@@ -0,0 +1,84 @@
+// `-Z packed_bundled_libs` is an unstable rustc flag that makes the compiler
+// only require a native library and no supplementary object files to compile.
+// Output files compiled with this flag should still contain all expected symbols -
+// that is what this test checks.
+// See https://github.com/rust-lang/rust/pull/100101
+
+//@ ignore-cross-compile
+// Reason: cross-compilation fails to export native symbols
+
+use run_make_support::{
+    bin_name, build_native_static_lib, cwd, filename_contains, is_msvc, llvm_ar, llvm_nm, rfs,
+    rust_lib_name, rustc, shallow_find_files,
+};
+
+fn main() {
+    build_native_static_lib("native_dep_1");
+    build_native_static_lib("native_dep_2");
+    build_native_static_lib("native_dep_3");
+    rustc().input("rust_dep_up.rs").crate_type("rlib").arg("-Zpacked_bundled_libs").run();
+    llvm_nm()
+        .input(rust_lib_name("rust_dep_up"))
+        .run()
+        .assert_stdout_contains_regex("U.*native_f2");
+    llvm_nm()
+        .input(rust_lib_name("rust_dep_up"))
+        .run()
+        .assert_stdout_contains_regex("U.*native_f3");
+    llvm_nm()
+        .input(rust_lib_name("rust_dep_up"))
+        .run()
+        .assert_stdout_contains_regex("T.*rust_dep_up");
+    llvm_ar()
+        .table_of_contents()
+        .arg(rust_lib_name("rust_dep_up"))
+        .run()
+        .assert_stdout_contains("native_dep_2");
+    llvm_ar()
+        .table_of_contents()
+        .arg(rust_lib_name("rust_dep_up"))
+        .run()
+        .assert_stdout_contains("native_dep_3");
+    rustc()
+        .input("rust_dep_local.rs")
+        .extern_("rlib", rust_lib_name("rust_dep_up"))
+        .arg("-Zpacked_bundled_libs")
+        .crate_type("rlib")
+        .run();
+    llvm_nm()
+        .input(rust_lib_name("rust_dep_local"))
+        .run()
+        .assert_stdout_contains_regex("U.*native_f1");
+    llvm_nm()
+        .input(rust_lib_name("rust_dep_local"))
+        .run()
+        .assert_stdout_contains_regex("T.*rust_dep_local");
+    llvm_ar()
+        .table_of_contents()
+        .arg(rust_lib_name("rust_dep_local"))
+        .run()
+        .assert_stdout_contains("native_dep_1");
+
+    // Ensure the compiler will not use files it should not know about.
+    for file in shallow_find_files(cwd(), |path| filename_contains(path, "native_dep_")) {
+        rfs::remove_file(file);
+    }
+
+    rustc()
+        .input("main.rs")
+        .extern_("lib", rust_lib_name("rust_dep_local"))
+        .output(bin_name("main"))
+        .arg("-Zpacked_bundled_libs")
+        .print("link-args")
+        .run()
+        .assert_stdout_contains_regex("native_dep_1.*native_dep_2.*native_dep_3");
+
+    // The binary "main" will not contain any symbols on MSVC.
+    if !is_msvc() {
+        llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f1");
+        llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f2");
+        llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f3");
+        llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*rust_dep_local");
+        llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*rust_dep_up");
+    }
+}
diff --git a/tests/run-make/sysroot-crates-are-unstable/rmake.rs b/tests/run-make/sysroot-crates-are-unstable/rmake.rs
index 24da387eb8016..2240d87237b1a 100644
--- a/tests/run-make/sysroot-crates-are-unstable/rmake.rs
+++ b/tests/run-make/sysroot-crates-are-unstable/rmake.rs
@@ -1,5 +1,102 @@
-use run_make_support::python_command;
+// Check that crates in the sysroot are treated as unstable, unless they are
+// on a list of known-stable sysroot crates.
+
+use std::path::{Path, PathBuf};
+use std::str;
+
+use run_make_support::{rfs, rustc, target};
+
+fn is_stable_crate(name: &str) -> bool {
+    matches!(name, "std" | "alloc" | "core" | "proc_macro")
+}
 
 fn main() {
-    python_command().arg("test.py").run();
+    for cr in get_unstable_sysroot_crates() {
+        check_crate_is_unstable(&cr);
+    }
+    println!("Done");
+}
+
+#[derive(Debug)]
+struct Crate {
+    name: String,
+    path: PathBuf,
+}
+
+fn check_crate_is_unstable(cr: &Crate) {
+    let Crate { name, path } = cr;
+
+    print!("- Verifying that sysroot crate '{name}' is an unstable crate ...");
+
+    // Trying to use this crate from a user program should fail.
+    let output = rustc()
+        .crate_type("rlib")
+        .target(target())
+        .extern_(name, path)
+        .input("-")
+        .stdin(format!("extern crate {name};"))
+        .run_fail();
+
+    // Make sure it failed for the intended reason, not some other reason.
+    // (The actual feature required varies between crates.)
+    output.assert_stderr_contains("use of unstable library feature");
+
+    println!(" OK");
+}
+
+fn get_unstable_sysroot_crates() -> Vec<Crate> {
+    let sysroot = PathBuf::from(rustc().print("sysroot").run().stdout_utf8().trim());
+    let sysroot_libs_dir = sysroot.join("lib").join("rustlib").join(target()).join("lib");
+    println!("Sysroot libs dir: {sysroot_libs_dir:?}");
+
+    // Generate a list of all library crates in the sysroot.
+    let sysroot_crates = get_all_crates_in_dir(&sysroot_libs_dir);
+    println!(
+        "Found {} sysroot crates: {:?}",
+        sysroot_crates.len(),
+        sysroot_crates.iter().map(|cr| &cr.name).collect::<Vec<_>>()
+    );
+
+    // Self-check: If we didn't find `core`, we probably checked the wrong directory.
+    assert!(
+        sysroot_crates.iter().any(|cr| cr.name == "core"),
+        "Couldn't find `core` in {sysroot_libs_dir:?}"
+    );
+
+    let unstable_sysroot_crates =
+        sysroot_crates.into_iter().filter(|cr| !is_stable_crate(&cr.name)).collect::<Vec<_>>();
+    // Self-check: There should be at least one unstable crate in the directory.
+    assert!(
+        !unstable_sysroot_crates.is_empty(),
+        "Couldn't find any unstable crates in {sysroot_libs_dir:?}"
+    );
+    unstable_sysroot_crates
+}
+
+fn get_all_crates_in_dir(libs_dir: &Path) -> Vec<Crate> {
+    let mut libs = vec![];
+    rfs::read_dir_entries(libs_dir, |path| {
+        if !path.is_file() {
+            return;
+        }
+        if let Some(name) = crate_name_from_path(path) {
+            libs.push(Crate { name, path: path.to_owned() });
+        }
+    });
+    libs.sort_by(|a, b| a.name.cmp(&b.name));
+    libs
+}
+
+/// Treat a file as a crate if its name begins with `lib` and ends with `.rlib`.
+/// The crate name is the part before the first hyphen (if any).
+fn crate_name_from_path(path: &Path) -> Option<String> {
+    let name = path
+        .file_name()?
+        .to_str()?
+        .strip_prefix("lib")?
+        .strip_suffix(".rlib")?
+        .split('-')
+        .next()
+        .expect("split always yields at least one string");
+    Some(name.to_owned())
 }
diff --git a/tests/run-make/sysroot-crates-are-unstable/test.py b/tests/run-make/sysroot-crates-are-unstable/test.py
deleted file mode 100644
index 45cfdd195b4e2..0000000000000
--- a/tests/run-make/sysroot-crates-are-unstable/test.py
+++ /dev/null
@@ -1,75 +0,0 @@
-import sys
-import os
-from os import listdir
-from os.path import isfile, join
-from subprocess import PIPE, Popen
-
-
-# This is n list of files which are stable crates or simply are not crates,
-# we don't check for the instability of these crates as they're all stable!
-STABLE_CRATES = ['std', 'alloc', 'core', 'proc_macro',
-                 'rsbegin.o', 'rsend.o', 'dllcrt2.o', 'crt2.o', 'clang_rt']
-
-
-def convert_to_string(s):
-    if s.__class__.__name__ == 'bytes':
-        return s.decode('utf-8')
-    return s
-
-
-def set_ld_lib_path():
-    var = os.environ.get("LD_LIB_PATH_ENVVAR")
-    rpath = os.environ.get("HOST_RPATH_DIR")
-    if var and rpath:
-        path = os.environ.get(var)
-        if path:
-            os.environ[var] = rpath + os.pathsep + path
-        else:
-            os.environ[var] = rpath
-
-
-def exec_command(command, to_input=None):
-    child = None
-    if to_input is None:
-        child = Popen(command, stdout=PIPE, stderr=PIPE)
-    else:
-        child = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
-    stdout, stderr = child.communicate(input=to_input)
-    return (convert_to_string(stdout), convert_to_string(stderr))
-
-
-def check_lib(lib):
-    if lib['name'] in STABLE_CRATES:
-        return True
-    print('verifying if {} is an unstable crate'.format(lib['name']))
-    stdout, stderr = exec_command([os.environ['RUSTC'], '-', '--crate-type', 'rlib',
-                                   '--target', os.environ['TARGET'],
-                                   '--extern', '{}={}'.format(lib['name'], lib['path'])],
-                                  to_input=('extern crate {};'.format(lib['name'])).encode('utf-8'))
-    if 'use of unstable library feature' not in '{}{}'.format(stdout, stderr):
-        print('crate {} "{}" is not unstable'.format(lib['name'], lib['path']))
-        print('{}{}'.format(stdout, stderr))
-        print('')
-        return False
-    return True
-
-# Generate a list of all crates in the sysroot. To do this we list all files in
-# rustc's sysroot, look at the filename, strip everything after the `-`, and
-# strip the leading `lib` (if present)
-def get_all_libs(dir_path):
-    return [{ 'path': join(dir_path, f), 'name': f[3:].split('-')[0] }
-            for f in listdir(dir_path)
-            if isfile(join(dir_path, f)) and f.endswith('.rlib') and f not in STABLE_CRATES]
-
-
-set_ld_lib_path()
-sysroot = exec_command([os.environ['RUSTC'], '--print', 'sysroot'])[0].replace('\n', '')
-assert sysroot, "Could not read the rustc sysroot!"
-libs = get_all_libs(join(sysroot, 'lib/rustlib/{}/lib'.format(os.environ['TARGET'])))
-
-ret = 0
-for lib in libs:
-    if not check_lib(lib):
-        # We continue so users can see all the not unstable crates.
-        ret = 1
-sys.exit(ret)