diff --git a/compiler/rustc_error_codes/src/error_codes/E0373.md b/compiler/rustc_error_codes/src/error_codes/E0373.md
index effa597aad9..d4d26007aa5 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0373.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0373.md
@@ -70,4 +70,4 @@ fn spawn<F: Future + Send + 'static>(future: F) {
 
 Similarly to closures, `async` blocks are not executed immediately and may
 capture closed-over data by reference. For more information, see
-https://rust-lang.github.io/async-book/03_async_await/01_chapter.html.
+<https://rust-lang.github.io/async-book/03_async_await/01_chapter.html>.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0378.md b/compiler/rustc_error_codes/src/error_codes/E0378.md
index c6fe997f3dc..7d939b99b04 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0378.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0378.md
@@ -20,7 +20,7 @@ where
 
 The `DispatchFromDyn` trait currently can only be implemented for
 builtin pointer types and structs that are newtype wrappers around them
-— that is, the struct must have only one field (except for`PhantomData`),
+— that is, the struct must have only one field (except for `PhantomData`),
 and that field must itself implement `DispatchFromDyn`.
 
 ```
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 2086d4030f9..2a850d9303c 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -15,6 +15,7 @@
 #![feature(box_patterns)]
 #![feature(error_reporter)]
 #![feature(extract_if)]
+#![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(negative_impls)]
 #![feature(never_type)]
diff --git a/compiler/rustc_errors/src/markdown/parse.rs b/compiler/rustc_errors/src/markdown/parse.rs
index 67e4963fddf..69e7120e714 100644
--- a/compiler/rustc_errors/src/markdown/parse.rs
+++ b/compiler/rustc_errors/src/markdown/parse.rs
@@ -10,15 +10,15 @@ const CBK: &[u8] = b"```";
 const CIL: &[u8] = b"`";
 const CMT_E: &[u8] = b"-->";
 const CMT_S: &[u8] = b"<!--";
-const EMP: &[u8] = b"_";
+const EMP_U: &[u8] = b"_";
+const EMP_A: &[u8] = b"*";
 const HDG: &[u8] = b"#";
 const LNK_CHARS: &str = "$-_.+!*'()/&?=:%";
 const LNK_E: &[u8] = b"]";
 const LNK_S: &[u8] = b"[";
-const STG: &[u8] = b"**";
+const STG_U: &[u8] = b"__";
+const STG_A: &[u8] = b"**";
 const STK: &[u8] = b"~~";
-const UL1: &[u8] = b"* ";
-const UL2: &[u8] = b"- ";
 
 /// Pattern replacements
 const REPLACEMENTS: &[(&str, &str)] = &[
@@ -100,22 +100,29 @@ fn parse_recursive<'a>(buf: &'a [u8], ctx: Context) -> MdStream<'_> {
         };
 
         let res: ParseResult<'_> = match (top_blk, prev) {
-            (_, Newline | Whitespace) if loop_buf.starts_with(CMT_S) => {
+            _ if loop_buf.starts_with(CMT_S) => {
                 parse_simple_pat(loop_buf, CMT_S, CMT_E, Po::TrimNoEsc, MdTree::Comment)
             }
             (true, Newline) if loop_buf.starts_with(CBK) => Some(parse_codeblock(loop_buf)),
-            (_, Newline | Whitespace) if loop_buf.starts_with(CIL) => parse_codeinline(loop_buf),
+            _ if loop_buf.starts_with(CIL) => parse_codeinline(loop_buf),
             (true, Newline | Whitespace) if loop_buf.starts_with(HDG) => parse_heading(loop_buf),
             (true, Newline) if loop_buf.starts_with(BRK) => {
                 Some((MdTree::HorizontalRule, parse_to_newline(loop_buf).1))
             }
-            (_, Newline | Whitespace) if loop_buf.starts_with(EMP) => {
-                parse_simple_pat(loop_buf, EMP, EMP, Po::None, MdTree::Emphasis)
+            (_, Newline) if unordered_list_start(loop_buf) => Some(parse_unordered_li(loop_buf)),
+            (_, Newline | Whitespace) if loop_buf.starts_with(STG_U) => {
+                parse_simple_pat(loop_buf, STG_U, STG_U, Po::None, MdTree::Strong)
             }
-            (_, Newline | Whitespace) if loop_buf.starts_with(STG) => {
-                parse_simple_pat(loop_buf, STG, STG, Po::None, MdTree::Strong)
+            _ if loop_buf.starts_with(STG_A) => {
+                parse_simple_pat(loop_buf, STG_A, STG_A, Po::None, MdTree::Strong)
             }
-            (_, Newline | Whitespace) if loop_buf.starts_with(STK) => {
+            (_, Newline | Whitespace) if loop_buf.starts_with(EMP_U) => {
+                parse_simple_pat(loop_buf, EMP_U, EMP_U, Po::None, MdTree::Emphasis)
+            }
+            _ if loop_buf.starts_with(EMP_A) => {
+                parse_simple_pat(loop_buf, EMP_A, EMP_A, Po::None, MdTree::Emphasis)
+            }
+            _ if loop_buf.starts_with(STK) => {
                 parse_simple_pat(loop_buf, STK, STK, Po::None, MdTree::Strikethrough)
             }
             (_, Newline | Whitespace) if loop_buf.starts_with(ANC_S) => {
@@ -130,11 +137,8 @@ fn parse_recursive<'a>(buf: &'a [u8], ctx: Context) -> MdStream<'_> {
                     _ => None,
                 }
             }
-            (_, Newline) if (loop_buf.starts_with(UL1) || loop_buf.starts_with(UL2)) => {
-                Some(parse_unordered_li(loop_buf))
-            }
             (_, Newline) if ord_list_start(loop_buf).is_some() => Some(parse_ordered_li(loop_buf)),
-            (_, Newline | Whitespace) if loop_buf.starts_with(LNK_S) => {
+            _ if loop_buf.starts_with(LNK_S) => {
                 parse_any_link(loop_buf, top_blk && prev == Prev::Newline)
             }
             (_, Escape | _) => None,
@@ -251,7 +255,6 @@ fn parse_heading(buf: &[u8]) -> ParseResult<'_> {
 
 /// Bulleted list
 fn parse_unordered_li(buf: &[u8]) -> Parsed<'_> {
-    debug_assert!(buf.starts_with(b"* ") || buf.starts_with(b"- "));
     let (txt, rest) = get_indented_section(&buf[2..]);
     let ctx = Context { top_block: false, prev: Prev::Whitespace };
     let stream = parse_recursive(trim_ascii_start(txt), ctx);
@@ -267,25 +270,28 @@ fn parse_ordered_li(buf: &[u8]) -> Parsed<'_> {
     (MdTree::OrderedListItem(num, stream), rest)
 }
 
-/// Find first line that isn't empty or doesn't start with whitespace, that will
-/// be our contents
 fn get_indented_section(buf: &[u8]) -> (&[u8], &[u8]) {
-    let mut end = buf.len();
-    for (idx, window) in buf.windows(2).enumerate() {
-        let &[ch, next_ch] = window else { unreachable!("always 2 elements") };
-        if idx >= buf.len().saturating_sub(2) && next_ch == b'\n' {
-            // End of stream
-            end = buf.len().saturating_sub(1);
-            break;
-        } else if ch == b'\n' && (!next_ch.is_ascii_whitespace() || next_ch == b'\n') {
-            end = idx;
-            break;
+    let mut lines = buf.split(|&byte| byte == b'\n');
+    let mut end = lines.next().map_or(0, |line| line.len());
+    for line in lines {
+        if let Some(first) = line.first() {
+            if unordered_list_start(line) || !first.is_ascii_whitespace() {
+                break;
+            }
         }
+        end += line.len() + 1;
     }
 
     (&buf[..end], &buf[end..])
 }
 
+fn unordered_list_start(mut buf: &[u8]) -> bool {
+    while let [b' ', rest @ ..] = buf {
+        buf = rest;
+    }
+    matches!(buf, [b'*' | b'-', b' ', ..])
+}
+
 /// Verify a valid ordered list start (e.g. `1.`) and parse it. Returns the
 /// parsed number and offset of character after the dot.
 fn ord_list_start(buf: &[u8]) -> Option<(u16, usize)> {
diff --git a/compiler/rustc_errors/src/markdown/tests/parse.rs b/compiler/rustc_errors/src/markdown/tests/parse.rs
index e39e8c89b35..e2e3f354ff6 100644
--- a/compiler/rustc_errors/src/markdown/tests/parse.rs
+++ b/compiler/rustc_errors/src/markdown/tests/parse.rs
@@ -4,13 +4,13 @@ use ParseOpt as PO;
 #[test]
 fn test_parse_simple() {
     let buf = "**abcd** rest";
-    let (t, r) = parse_simple_pat(buf.as_bytes(), STG, STG, PO::None, MdTree::Strong).unwrap();
+    let (t, r) = parse_simple_pat(buf.as_bytes(), b"**", b"**", PO::None, MdTree::Strong).unwrap();
     assert_eq!(t, MdTree::Strong("abcd"));
     assert_eq!(r, b" rest");
 
     // Escaping should fail
     let buf = r"**abcd\** rest";
-    let res = parse_simple_pat(buf.as_bytes(), STG, STG, PO::None, MdTree::Strong);
+    let res = parse_simple_pat(buf.as_bytes(), b"**", b"**", PO::None, MdTree::Strong);
     assert!(res.is_none());
 }
 
@@ -141,12 +141,12 @@ fn test_indented_section() {
     assert_eq!(str::from_utf8(r).unwrap(), "\nnot ind");
 
     let (txt, rest) = get_indented_section(IND2.as_bytes());
-    assert_eq!(str::from_utf8(txt).unwrap(), "test end of stream\n  1\n  2");
-    assert_eq!(str::from_utf8(rest).unwrap(), "\n");
+    assert_eq!(str::from_utf8(txt).unwrap(), "test end of stream\n  1\n  2\n");
+    assert_eq!(str::from_utf8(rest).unwrap(), "");
 
     let (txt, rest) = get_indented_section(IND3.as_bytes());
-    assert_eq!(str::from_utf8(txt).unwrap(), "test empty lines\n  1\n  2");
-    assert_eq!(str::from_utf8(rest).unwrap(), "\n\nnot ind");
+    assert_eq!(str::from_utf8(txt).unwrap(), "test empty lines\n  1\n  2\n");
+    assert_eq!(str::from_utf8(rest).unwrap(), "\nnot ind");
 }
 
 const HBT: &str = r"# Heading
@@ -310,3 +310,56 @@ fn test_code_at_start() {
     let res = entrypoint(CODE_STARTLINE);
     assert_eq!(res, expected);
 }
+
+#[test]
+fn test_code_in_parens() {
+    let expected =
+        vec![MdTree::PlainText("("), MdTree::CodeInline("Foo"), MdTree::PlainText(")")].into();
+    let res = entrypoint("(`Foo`)");
+    assert_eq!(res, expected);
+}
+
+const LIST_WITH_SPACE: &str = "
+para
+ * l1
+ * l2
+";
+
+#[test]
+fn test_list_with_space() {
+    let expected = vec![
+        MdTree::PlainText("para"),
+        MdTree::ParagraphBreak,
+        MdTree::UnorderedListItem(vec![MdTree::PlainText("l1")].into()),
+        MdTree::LineBreak,
+        MdTree::UnorderedListItem(vec![MdTree::PlainText("l2")].into()),
+    ]
+    .into();
+    let res = entrypoint(LIST_WITH_SPACE);
+    assert_eq!(res, expected);
+}
+
+const SNAKE_CASE: &str = "
+foo*bar*
+foo**bar**
+foo_bar_
+foo__bar__
+";
+
+#[test]
+fn test_snake_case() {
+    let expected = vec![
+        MdTree::PlainText("foo"),
+        MdTree::Emphasis("bar"),
+        MdTree::PlainText(" "),
+        MdTree::PlainText("foo"),
+        MdTree::Strong("bar"),
+        MdTree::PlainText(" "),
+        MdTree::PlainText("foo_bar_"),
+        MdTree::PlainText(" "),
+        MdTree::PlainText("foo__bar__"),
+    ]
+    .into();
+    let res = entrypoint(SNAKE_CASE);
+    assert_eq!(res, expected);
+}
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 341d533492d..65229722771 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -495,6 +495,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                     err.span_label(self.span, "invalid cast");
                 }
 
+                fcx.suggest_no_capture_closure(&mut err, self.cast_ty, self.expr_ty);
                 self.try_suggest_collection_to_bool(fcx, &mut err);
 
                 err.emit();
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 7d67cc3b36e..649bcdd8733 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -472,6 +472,11 @@ impl Step for Rustc {
                     );
                 }
             }
+            if builder.build_wasm_component_ld() {
+                let src_dir = builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin");
+                let ld = exe("wasm-component-ld", compiler.host);
+                builder.copy_link(&src_dir.join(&ld), &dst_dir.join(&ld));
+            }
 
             // Man pages
             t!(fs::create_dir_all(image.join("share/man/man1")));
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 9d5aa795c6c..e32288e2caf 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -1570,11 +1570,22 @@ impl Config {
         let mut is_user_configured_rust_channel = false;
 
         if let Some(rust) = toml.rust {
-            config.download_rustc_commit =
-                config.download_ci_rustc_commit(rust.download_rustc.clone());
+            if let Some(commit) = config.download_ci_rustc_commit(rust.download_rustc.clone()) {
+                // Primarily used by CI runners to avoid handling download-rustc incompatible
+                // options one by one on shell scripts.
+                let disable_ci_rustc_if_incompatible =
+                    env::var_os("DISABLE_CI_RUSTC_IF_INCOMPATIBLE")
+                        .is_some_and(|s| s == "1" || s == "true");
 
-            if config.download_rustc_commit.is_some() {
-                check_incompatible_options_for_ci_rustc(&rust);
+                if let Err(e) = check_incompatible_options_for_ci_rustc(&rust) {
+                    if disable_ci_rustc_if_incompatible {
+                        config.download_rustc_commit = None;
+                    } else {
+                        panic!("{}", e);
+                    }
+                } else {
+                    config.download_rustc_commit = Some(commit);
+                }
             }
 
             let Rust {
@@ -2612,14 +2623,15 @@ impl Config {
 
 /// Checks the CI rustc incompatible options by destructuring the `Rust` instance
 /// and makes sure that no rust options from config.toml are missed.
-fn check_incompatible_options_for_ci_rustc(rust: &Rust) {
+fn check_incompatible_options_for_ci_rustc(rust: &Rust) -> Result<(), String> {
     macro_rules! err {
         ($name:expr) => {
-            assert!(
-                $name.is_none(),
-                "ERROR: Setting `rust.{}` is incompatible with `rust.download-rustc`.",
-                stringify!($name).replace("_", "-")
-            );
+            if $name.is_some() {
+                return Err(format!(
+                    "ERROR: Setting `rust.{}` is incompatible with `rust.download-rustc`.",
+                    stringify!($name).replace("_", "-")
+                ));
+            }
         };
     }
 
@@ -2715,6 +2727,8 @@ fn check_incompatible_options_for_ci_rustc(rust: &Rust) {
     warn!(channel);
     warn!(description);
     warn!(incremental);
+
+    Ok(())
 }
 
 fn set<T>(field: &mut T, val: Option<T>) {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 16c08f709df..78c06551ff2 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -3378,6 +3378,7 @@ impl<'test> TestCx<'test> {
             cmd.env("IS_MSVC", "1")
                 .env("IS_WINDOWS", "1")
                 .env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
+                .env("MSVC_LIB_PATH", format!("{}", lib.display()))
                 .env("CC", format!("'{}' {}", self.config.cc, cflags))
                 .env("CXX", format!("'{}' {}", &self.config.cxx, cxxflags));
         } else {
@@ -3748,6 +3749,7 @@ impl<'test> TestCx<'test> {
             cmd.env("IS_MSVC", "1")
                 .env("IS_WINDOWS", "1")
                 .env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
+                .env("MSVC_LIB_PATH", format!("{}", lib.display()))
                 // Note: we diverge from legacy run_make and don't lump `CC` the compiler and
                 // default flags together.
                 .env("CC_DEFAULT_FLAGS", &cflags)
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 158d5cc8ade..4042bac8dac 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -27,7 +27,6 @@ run-make/foreign-rust-exceptions/Makefile
 run-make/incr-add-rust-src-component/Makefile
 run-make/incr-foreign-head-span/Makefile
 run-make/interdependent-c-libraries/Makefile
-run-make/issue-15460/Makefile
 run-make/issue-35164/Makefile
 run-make/issue-36710/Makefile
 run-make/issue-47551/Makefile
@@ -40,21 +39,17 @@ run-make/libtest-json/Makefile
 run-make/libtest-junit/Makefile
 run-make/libtest-thread-limit/Makefile
 run-make/link-cfg/Makefile
-run-make/link-framework/Makefile
 run-make/long-linker-command-lines-cmd-exe/Makefile
 run-make/long-linker-command-lines/Makefile
-run-make/lto-linkage-used-attr/Makefile
 run-make/macos-deployment-target/Makefile
 run-make/min-global-align/Makefile
 run-make/native-link-modifier-bundle/Makefile
 run-make/native-link-modifier-whole-archive/Makefile
 run-make/no-alloc-shim/Makefile
 run-make/no-builtins-attribute/Makefile
-run-make/no-duplicate-libs/Makefile
 run-make/panic-abort-eh_frame/Makefile
 run-make/pdb-buildinfo-cl-cmd/Makefile
 run-make/pgo-gen-lto/Makefile
-run-make/pgo-gen-no-imp-symbols/Makefile
 run-make/pgo-indirect-call-promotion/Makefile
 run-make/pointer-auth-link-with-c/Makefile
 run-make/print-calling-conventions/Makefile
diff --git a/tests/run-make/issue-15460/Makefile b/tests/run-make/issue-15460/Makefile
deleted file mode 100644
index a36a085fa6f..00000000000
--- a/tests/run-make/issue-15460/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-all: $(call NATIVE_STATICLIB,foo)
-	$(RUSTC) foo.rs -C extra-filename=-383hf8 -C prefer-dynamic
-	$(RUSTC) bar.rs
-	$(call RUN,bar)
diff --git a/tests/run-make/link-framework/Makefile b/tests/run-make/link-framework/Makefile
deleted file mode 100644
index 96d832ad4a8..00000000000
--- a/tests/run-make/link-framework/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-# only-apple
-#
-# Check that linking to a framework actually makes it to the linker.
-
-include ../tools.mk
-
-all:
-	$(RUSTC) dep-link-framework.rs
-	$(RUSTC) dep-link-weak-framework.rs
-
-	$(RUSTC) empty.rs
-	otool -L $(TMPDIR)/no-link | $(CGREP) -v CoreFoundation
-
-	$(RUSTC) link-framework.rs
-	otool -L $(TMPDIR)/link-framework | $(CGREP) CoreFoundation | $(CGREP) -v weak
-
-	$(RUSTC) link-weak-framework.rs
-	otool -L $(TMPDIR)/link-weak-framework | $(CGREP) CoreFoundation | $(CGREP) weak
-
-# When linking the framework both normally, and weakly, the weak linking takes preference
-
-	$(RUSTC) link-both.rs
-	otool -L $(TMPDIR)/link-both | $(CGREP) CoreFoundation | $(CGREP) weak
diff --git a/tests/run-make/link-framework/rmake.rs b/tests/run-make/link-framework/rmake.rs
new file mode 100644
index 00000000000..e5df93b181a
--- /dev/null
+++ b/tests/run-make/link-framework/rmake.rs
@@ -0,0 +1,38 @@
+// Check that linking to a framework actually makes it to the linker.
+
+//@ only-apple
+
+use run_make_support::{cmd, rustc};
+
+fn main() {
+    rustc().input("dep-link-framework.rs").run();
+    rustc().input("dep-link-weak-framework.rs").run();
+
+    rustc().input("empty.rs").run();
+    cmd("otool").arg("-L").arg("no-link").run_fail().assert_stdout_not_contains("CoreFoundation");
+
+    rustc().input("link-framework.rs").run();
+    cmd("otool")
+        .arg("-L")
+        .arg("link-framework")
+        .run()
+        .assert_stdout_contains("CoreFoundation")
+        .assert_stdout_not_contains("weak");
+
+    rustc().input("link-weak-framework.rs").run();
+    cmd("otool")
+        .arg("-L")
+        .arg("link-weak-framework")
+        .run()
+        .assert_stdout_contains("CoreFoundation")
+        .assert_stdout_contains("weak");
+
+    // When linking the framework both normally, and weakly, the weak linking takes preference.
+    rustc().input("link-both.rs").run();
+    cmd("otool")
+        .arg("-L")
+        .arg("link-both")
+        .run()
+        .assert_stdout_contains("CoreFoundation")
+        .assert_stdout_contains("weak");
+}
diff --git a/tests/run-make/issue-15460/bar.rs b/tests/run-make/link-native-static-lib-to-dylib/bar.rs
similarity index 100%
rename from tests/run-make/issue-15460/bar.rs
rename to tests/run-make/link-native-static-lib-to-dylib/bar.rs
diff --git a/tests/run-make/issue-15460/foo.c b/tests/run-make/link-native-static-lib-to-dylib/foo.c
similarity index 100%
rename from tests/run-make/issue-15460/foo.c
rename to tests/run-make/link-native-static-lib-to-dylib/foo.c
diff --git a/tests/run-make/issue-15460/foo.rs b/tests/run-make/link-native-static-lib-to-dylib/foo.rs
similarity index 100%
rename from tests/run-make/issue-15460/foo.rs
rename to tests/run-make/link-native-static-lib-to-dylib/foo.rs
diff --git a/tests/run-make/link-native-static-lib-to-dylib/rmake.rs b/tests/run-make/link-native-static-lib-to-dylib/rmake.rs
new file mode 100644
index 00000000000..0746c396314
--- /dev/null
+++ b/tests/run-make/link-native-static-lib-to-dylib/rmake.rs
@@ -0,0 +1,14 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/15460>.
+
+//@ ignore-cross-compile
+
+use run_make_support::{build_native_static_lib, run, rustc};
+
+fn main() {
+    build_native_static_lib("foo");
+
+    rustc().input("foo.rs").extra_filename("-383hf8").arg("-Cprefer-dynamic").run();
+    rustc().input("bar.rs").run();
+
+    run("bar");
+}
diff --git a/tests/run-make/lto-linkage-used-attr/Makefile b/tests/run-make/lto-linkage-used-attr/Makefile
deleted file mode 100644
index fed41a00f84..00000000000
--- a/tests/run-make/lto-linkage-used-attr/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-include ../tools.mk
-
-# Verify that the impl_* symbols are preserved. #108030
-# only-x86_64-unknown-linux-gnu
-
-all:
-	$(RUSTC) -Cdebuginfo=0 -Copt-level=3 lib.rs
-	$(RUSTC) -Clto=fat -Cdebuginfo=0 -Copt-level=3 main.rs
diff --git a/tests/run-make/lto-linkage-used-attr/rmake.rs b/tests/run-make/lto-linkage-used-attr/rmake.rs
new file mode 100644
index 00000000000..12463b79a75
--- /dev/null
+++ b/tests/run-make/lto-linkage-used-attr/rmake.rs
@@ -0,0 +1,15 @@
+// Link time optimizations (LTO) used to snip away some important symbols
+// when setting optimization level to 3 or higher.
+// This is an LLVM, not a rustc bug, fixed here: https://reviews.llvm.org/D145293
+// This test checks that the impl_* symbols are preserved as they should.
+// See https://github.com/rust-lang/rust/issues/108030
+
+//@ only-x86_64-unknown-linux-gnu
+// Reason: some of the inline assembly directives are architecture-specific.
+
+use run_make_support::rustc;
+
+fn main() {
+    rustc().arg("-Cdebuginfo=0").opt_level("3").input("lib.rs").run();
+    rustc().arg("-Clto=fat").arg("-Cdebuginfo=0").opt_level("3").input("main.rs").run();
+}
diff --git a/tests/run-make/no-duplicate-libs/Makefile b/tests/run-make/no-duplicate-libs/Makefile
deleted file mode 100644
index 4be8c026294..00000000000
--- a/tests/run-make/no-duplicate-libs/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-ifdef IS_MSVC
-# FIXME(#27979)
-all:
-else
-all: $(call STATICLIB,foo) $(call STATICLIB,bar)
-	$(RUSTC) main.rs
-	$(call RUN,main)
-endif
diff --git a/tests/run-make/no-duplicate-libs/rmake.rs b/tests/run-make/no-duplicate-libs/rmake.rs
new file mode 100644
index 00000000000..469348e266c
--- /dev/null
+++ b/tests/run-make/no-duplicate-libs/rmake.rs
@@ -0,0 +1,22 @@
+// The rust compiler used to try to detect duplicated libraries in
+// the linking order and remove the duplicates... but certain edge cases,
+// such as the one presented in `foo` and `bar` in this test, demand precise
+// control over the link order, including duplicates. As the anti-duplication
+// filter was removed, this test should now successfully see main be compiled
+// and executed.
+// See https://github.com/rust-lang/rust/pull/12688
+
+//@ ignore-cross-compile
+// Reason: the compiled binary is executed
+
+//@ ignore-msvc
+// Reason: native compilation results in an unresolved external symbol
+
+use run_make_support::{build_native_static_lib, run, rustc};
+
+fn main() {
+    build_native_static_lib("foo");
+    build_native_static_lib("bar");
+    rustc().input("main.rs").run();
+    run("main");
+}
diff --git a/tests/run-make/pgo-gen-no-imp-symbols/Makefile b/tests/run-make/pgo-gen-no-imp-symbols/Makefile
deleted file mode 100644
index d2baa145ba5..00000000000
--- a/tests/run-make/pgo-gen-no-imp-symbols/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-include ../tools.mk
-
-COMPILE_FLAGS=-O -Ccodegen-units=1 -Cprofile-generate="$(TMPDIR)" -Zno-profiler-runtime
-
-all:
-	$(RUSTC) $(COMPILE_FLAGS) --emit=llvm-ir test.rs
-	# We expect symbols starting with "__llvm_profile_".
-	$(CGREP) "__llvm_profile_" < $(TMPDIR)/test.ll
-	# We do NOT expect the "__imp_" version of these symbols.
-	$(CGREP) -v "__imp___llvm_profile_" < $(TMPDIR)/test.ll # 64 bit
-	$(CGREP) -v "__imp____llvm_profile_" < $(TMPDIR)/test.ll # 32 bit
diff --git a/tests/run-make/pgo-gen-no-imp-symbols/rmake.rs b/tests/run-make/pgo-gen-no-imp-symbols/rmake.rs
new file mode 100644
index 00000000000..85ade7885ce
--- /dev/null
+++ b/tests/run-make/pgo-gen-no-imp-symbols/rmake.rs
@@ -0,0 +1,27 @@
+// LLVM's profiling instrumentation adds a few symbols that are used by the profiler runtime.
+// Since these show up as globals in the LLVM IR, the compiler generates dllimport-related
+// __imp_ stubs for them. This can lead to linker errors because the instrumentation
+// symbols have weak linkage or are in a comdat section, but the __imp_ stubs aren't.
+// Since profiler-related symbols were excluded from stub-generation in #59812, this has
+// been fixed, and this test checks that the llvm profile symbol appear, but without the
+// anomalous __imp_ stubs.
+// See https://github.com/rust-lang/rust/pull/59812
+
+use run_make_support::{cwd, rfs, rustc};
+
+fn main() {
+    rustc()
+        .input("test.rs")
+        .emit("llvm-ir")
+        .opt()
+        .codegen_units(1)
+        .profile_generate(cwd())
+        .arg("-Zno-profiler-runtime")
+        .run();
+    let out = rfs::read_to_string("test.ll");
+    // We expect symbols starting with "__llvm_profile_".
+    assert!(out.contains("__llvm_profile_"));
+    // We do NOT expect the "__imp_" version of these symbols.
+    assert!(!out.contains("__imp___llvm_profile_")); // 64 bit
+    assert!(!out.contains("__imp____llvm_profile_")); // 32 bit
+}
diff --git a/tests/ui/closures/closure-no-fn-3.stderr b/tests/ui/closures/closure-no-fn-3.stderr
index bbf3677fb72..7711347c568 100644
--- a/tests/ui/closures/closure-no-fn-3.stderr
+++ b/tests/ui/closures/closure-no-fn-3.stderr
@@ -3,6 +3,12 @@ error[E0605]: non-primitive cast: `{closure@$DIR/closure-no-fn-3.rs:6:28: 6:30}`
    |
 LL |     let baz: fn() -> u8 = (|| { b }) as fn() -> u8;
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
+   |
+note: closures can only be coerced to `fn` types if they do not capture any variables
+  --> $DIR/closure-no-fn-3.rs:6:33
+   |
+LL |     let baz: fn() -> u8 = (|| { b }) as fn() -> u8;
+   |                                 ^ `b` captured here
 
 error: aborting due to 1 previous error