diff --git a/tests/run-make/doctests-keep-binaries-2024/rmake.rs b/tests/run-make/doctests-keep-binaries-2024/rmake.rs
new file mode 100644
index 00000000000..a6fddf6d336
--- /dev/null
+++ b/tests/run-make/doctests-keep-binaries-2024/rmake.rs
@@ -0,0 +1,65 @@
+// Check that valid binaries are persisted by running them, regardless of whether the
+// --run or --no-run option is used.
+
+use run_make_support::fs_wrapper::{create_dir, remove_dir_all};
+use run_make_support::{run, rustc, rustdoc};
+use std::path::Path;
+
+fn setup_test_env<F: FnOnce(&Path, &Path)>(callback: F) {
+    let out_dir = Path::new("doctests");
+    create_dir(&out_dir);
+    rustc().input("t.rs").crate_type("rlib").run();
+    callback(&out_dir, Path::new("libt.rlib"));
+    remove_dir_all(out_dir);
+}
+
+fn check_generated_binaries() {
+    run("doctests/merged_doctest_2024/rust_out");
+}
+
+fn main() {
+    setup_test_env(|out_dir, extern_path| {
+        rustdoc()
+            .input("t.rs")
+            .arg("-Zunstable-options")
+            .arg("--test")
+            .arg("--persist-doctests")
+            .arg(out_dir)
+            .extern_("t", extern_path)
+            .edition("2024")
+            .run();
+        check_generated_binaries();
+    });
+    setup_test_env(|out_dir, extern_path| {
+        rustdoc()
+            .input("t.rs")
+            .arg("-Zunstable-options")
+            .arg("--test")
+            .arg("--persist-doctests")
+            .arg(out_dir)
+            .extern_("t", extern_path)
+            .arg("--no-run")
+            .edition("2024")
+            .run();
+        check_generated_binaries();
+    });
+    // Behavior with --test-run-directory with relative paths.
+    setup_test_env(|_, _| {
+        let run_dir_path = Path::new("rundir");
+        create_dir(&run_dir_path);
+
+        rustdoc()
+            .input("t.rs")
+            .arg("-Zunstable-options")
+            .arg("--test")
+            .arg("--persist-doctests")
+            .arg("doctests")
+            .arg("--test-run-directory")
+            .arg(run_dir_path)
+            .extern_("t", "libt.rlib")
+            .edition("2024")
+            .run();
+
+        remove_dir_all(run_dir_path);
+    });
+}
diff --git a/tests/run-make/doctests-keep-binaries-2024/t.rs b/tests/run-make/doctests-keep-binaries-2024/t.rs
new file mode 100644
index 00000000000..c38cf0a0b25
--- /dev/null
+++ b/tests/run-make/doctests-keep-binaries-2024/t.rs
@@ -0,0 +1,11 @@
+/// Fungle the foople.
+/// ```
+/// t::foople();
+/// ```
+pub fn foople() {}
+
+/// Flomble the florp
+/// ```
+/// t::florp();
+/// ```
+pub fn florp() {}
diff --git a/tests/run-make/doctests-merge/doctest-2021.stdout b/tests/run-make/doctests-merge/doctest-2021.stdout
new file mode 100644
index 00000000000..7da08d68faa
--- /dev/null
+++ b/tests/run-make/doctests-merge/doctest-2021.stdout
@@ -0,0 +1,7 @@
+
+running 2 tests
+test doctest.rs - (line 4) ... ok
+test doctest.rs - init (line 8) ... ok
+
+test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/run-make/doctests-merge/doctest-2024.stdout b/tests/run-make/doctests-merge/doctest-2024.stdout
new file mode 100644
index 00000000000..7da08d68faa
--- /dev/null
+++ b/tests/run-make/doctests-merge/doctest-2024.stdout
@@ -0,0 +1,7 @@
+
+running 2 tests
+test doctest.rs - (line 4) ... ok
+test doctest.rs - init (line 8) ... ok
+
+test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/run-make/doctests-merge/doctest-standalone.rs b/tests/run-make/doctests-merge/doctest-standalone.rs
new file mode 100644
index 00000000000..134ffb58285
--- /dev/null
+++ b/tests/run-make/doctests-merge/doctest-standalone.rs
@@ -0,0 +1,18 @@
+#![crate_name = "foo"]
+#![crate_type = "lib"]
+
+//! ```standalone
+//! foo::init();
+//! ```
+
+/// ```standalone
+/// foo::init();
+/// ```
+pub fn init() {
+    static mut IS_INIT: bool = false;
+
+    unsafe {
+        assert!(!IS_INIT);
+        IS_INIT = true;
+    }
+}
diff --git a/tests/run-make/doctests-merge/doctest-standalone.stdout b/tests/run-make/doctests-merge/doctest-standalone.stdout
new file mode 100644
index 00000000000..ee9f62326ab
--- /dev/null
+++ b/tests/run-make/doctests-merge/doctest-standalone.stdout
@@ -0,0 +1,7 @@
+
+running 2 tests
+test doctest-standalone.rs - (line 4) ... ok
+test doctest-standalone.rs - init (line 8) ... ok
+
+test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/run-make/doctests-merge/doctest.rs b/tests/run-make/doctests-merge/doctest.rs
new file mode 100644
index 00000000000..66a5d88db67
--- /dev/null
+++ b/tests/run-make/doctests-merge/doctest.rs
@@ -0,0 +1,18 @@
+#![crate_name = "foo"]
+#![crate_type = "lib"]
+
+//! ```
+//! foo::init();
+//! ```
+
+/// ```
+/// foo::init();
+/// ```
+pub fn init() {
+    static mut IS_INIT: bool = false;
+
+    unsafe {
+        assert!(!IS_INIT);
+        IS_INIT = true;
+    }
+}
diff --git a/tests/run-make/doctests-merge/rmake.rs b/tests/run-make/doctests-merge/rmake.rs
new file mode 100644
index 00000000000..ac3951c6ceb
--- /dev/null
+++ b/tests/run-make/doctests-merge/rmake.rs
@@ -0,0 +1,38 @@
+use run_make_support::{cwd, diff, rustc, rustdoc};
+use std::path::Path;
+
+fn test_and_compare(input_file: &str, stdout_file: &str, edition: &str, dep: &Path) {
+    let mut cmd = rustdoc();
+
+    let output = cmd
+        .input(input_file)
+        .arg("--test")
+        .arg("-Zunstable-options")
+        .edition(edition)
+        .arg("--test-args=--test-threads=1")
+        .extern_("foo", dep.display().to_string())
+        .env("RUST_BACKTRACE", "short")
+        .run();
+
+    diff()
+        .expected_file(stdout_file)
+        .actual_text("output", output.stdout_utf8())
+        .normalize(r#"finished in \d+\.\d+s"#, "finished in $$TIME")
+        .run();
+}
+
+fn main() {
+    let out_file = cwd().join("libfoo.rlib");
+
+    rustc().input("doctest.rs").crate_type("rlib").output(&out_file).run();
+
+    // First we ensure that running with the 2024 edition will not fail at runtime.
+    test_and_compare("doctest.rs", "doctest-2024.stdout", "2024", &out_file);
+
+    // Then we ensure that running with an edition < 2024 will not fail at runtime.
+    test_and_compare("doctest.rs", "doctest-2021.stdout", "2021", &out_file);
+
+    // Now we check with the standalone attribute which should succeed in all cases.
+    test_and_compare("doctest-standalone.rs", "doctest-standalone.stdout", "2024", &out_file);
+    test_and_compare("doctest-standalone.rs", "doctest-standalone.stdout", "2021", &out_file);
+}