diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 1f5956168d7e..569206d6ec88 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -156,21 +156,22 @@ impl<'a> BuildDocTestBuilder<'a> { // Up until now, we've been dealing with settings for the whole crate. // Now, infer settings for this particular test. + // + // Avoid tests with incompatible attributes. + let opt_out = lang_str.is_some_and(|lang_str| { + lang_str.compile_fail || lang_str.test_harness || lang_str.standalone_crate + }); let can_be_merged = if can_merge_doctests == MergeDoctests::Auto { - let mut can_merge = false; - // Avoid tests with incompatible attributes. - can_merge |= lang_str.is_some_and(|lang_str| { - !lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate - }); - // If it contains `#[feature]` or `#[no_std]`, we don't want it to be merged either. - can_merge &= !has_global_allocator - && crate_attrs.is_empty() + // We try to look at the contents of the test to detect whether it should be merged. + // This is not a complete list of possible failures, but it catches many cases. + let will_probably_fail = has_global_allocator + || !crate_attrs.is_empty() // If this is a merged doctest and a defined macro uses `$crate`, then the path will // not work, so better not put it into merged doctests. - && !(has_macro_def && everything_else.contains("$crate")); - can_merge + || (has_macro_def && everything_else.contains("$crate")); + !opt_out && !will_probably_fail } else { - can_merge_doctests != MergeDoctests::Never + can_merge_doctests != MergeDoctests::Never && !opt_out }; DocTestBuilder { supports_color, diff --git a/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs b/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs new file mode 100644 index 000000000000..9a1e86ade67f --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ edition: 2024 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't +// emitted as JSON. Instead the .stderr file tests that this doesn't contains a +// "merged compilation took ..." message. + +/// ```standalone_crate +/// let x = 12; +/// ``` +/// +/// These two doctests should be not be merged, even though this passes `--merge-doctests=yes`. +/// +/// ```standalone_crate +/// fn main() { +/// println!("owo"); +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout b/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout new file mode 100644 index 000000000000..24b16ec82f45 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/force-merge-default-not-override.rs - Foo (line 14) ... ok +test $DIR/force-merge-default-not-override.rs - Foo (line 20) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME +