Skip to content

Commit 041d95d

Browse files
committed
Allow #![doc(test(attr(..)))] doctests to be again merged together
1 parent 9d9705f commit 041d95d

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

src/librustdoc/doctest.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod runner;
55
mod rust;
66

77
use std::fs::File;
8+
use std::hash::{Hash, Hasher};
89
use std::io::{self, Write};
910
use std::path::{Path, PathBuf};
1011
use std::process::{self, Command, Stdio};
@@ -14,7 +15,7 @@ use std::{panic, str};
1415

1516
pub(crate) use make::{BuildDocTestBuilder, DocTestBuilder};
1617
pub(crate) use markdown::test as test_markdown;
17-
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
18+
use rustc_data_structures::fx::{FxHashMap, FxHasher, FxIndexMap, FxIndexSet};
1819
use rustc_errors::emitter::HumanReadableErrorType;
1920
use rustc_errors::{ColorConfig, DiagCtxtHandle};
2021
use rustc_hir as hir;
@@ -281,7 +282,7 @@ pub(crate) fn run_tests(
281282
rustdoc_options: &Arc<RustdocOptions>,
282283
unused_extern_reports: &Arc<Mutex<Vec<UnusedExterns>>>,
283284
mut standalone_tests: Vec<test::TestDescAndFn>,
284-
mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>,
285+
mergeable_tests: FxIndexMap<MergeableTestKey, Vec<(DocTestBuilder, ScrapedDocTest)>>,
285286
// We pass this argument so we can drop it manually before using `exit`.
286287
mut temp_dir: Option<TempDir>,
287288
) {
@@ -296,7 +297,7 @@ pub(crate) fn run_tests(
296297
let mut ran_edition_tests = 0;
297298
let target_str = rustdoc_options.target.to_string();
298299

299-
for (edition, mut doctests) in mergeable_tests {
300+
for (MergeableTestKey { edition, global_crate_attrs_hash }, mut doctests) in mergeable_tests {
300301
if doctests.is_empty() {
301302
continue;
302303
}
@@ -306,8 +307,8 @@ pub(crate) fn run_tests(
306307

307308
let rustdoc_test_options = IndividualTestOptions::new(
308309
rustdoc_options,
309-
&Some(format!("merged_doctest_{edition}")),
310-
PathBuf::from(format!("doctest_{edition}.rs")),
310+
&Some(format!("merged_doctest_{edition}_{global_crate_attrs_hash}")),
311+
PathBuf::from(format!("doctest_{edition}_{global_crate_attrs_hash}.rs")),
311312
);
312313

313314
for (doctest, scraped_test) in &doctests {
@@ -887,9 +888,15 @@ pub(crate) trait DocTestVisitor {
887888
fn visit_header(&mut self, _name: &str, _level: u32) {}
888889
}
889890

891+
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
892+
pub(crate) struct MergeableTestKey {
893+
edition: Edition,
894+
global_crate_attrs_hash: u64,
895+
}
896+
890897
struct CreateRunnableDocTests {
891898
standalone_tests: Vec<test::TestDescAndFn>,
892-
mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>,
899+
mergeable_tests: FxIndexMap<MergeableTestKey, Vec<(DocTestBuilder, ScrapedDocTest)>>,
893900

894901
rustdoc_options: Arc<RustdocOptions>,
895902
opts: GlobalTestOptions,
@@ -957,7 +964,17 @@ impl CreateRunnableDocTests {
957964
let test_desc = self.generate_test_desc_and_fn(doctest, scraped_test);
958965
self.standalone_tests.push(test_desc);
959966
} else {
960-
self.mergeable_tests.entry(edition).or_default().push((doctest, scraped_test));
967+
self.mergeable_tests
968+
.entry(MergeableTestKey {
969+
edition,
970+
global_crate_attrs_hash: {
971+
let mut hasher = FxHasher::default();
972+
scraped_test.global_crate_attrs.hash(&mut hasher);
973+
hasher.finish()
974+
},
975+
})
976+
.or_default()
977+
.push((doctest, scraped_test));
961978
}
962979
}
963980

tests/run-make/doctests-keep-binaries-2024/rmake.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,22 @@ fn setup_test_env<F: FnOnce(&Path, &Path)>(callback: F) {
1616
}
1717

1818
fn check_generated_binaries() {
19-
run("doctests/merged_doctest_2024/rust_out");
19+
let mut found_merged_doctest = false;
20+
rfs::read_dir_entries("doctests/", |path| {
21+
if path
22+
.file_name()
23+
.and_then(|name| name.to_str())
24+
.is_some_and(|name| name.starts_with("merged_doctest_2024"))
25+
{
26+
found_merged_doctest = true;
27+
let rust_out = path.join("rust_out");
28+
let rust_out = rust_out.to_string_lossy();
29+
run(&*rust_out);
30+
}
31+
});
32+
if !found_merged_doctest {
33+
panic!("no directory starting with `merged_doctest_2024` found under `doctests/`");
34+
}
2035
}
2136

2237
fn main() {

tests/rustdoc-ui/doctest/dead-code-module-2.stdout

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11

2-
running 2 tests
3-
test $DIR/dead-code-module-2.rs - my_mod::f (line 16) - compile ... FAILED
2+
running 1 test
43
test $DIR/dead-code-module-2.rs - g (line 24) - compile ... ok
54

5+
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
6+
7+
8+
running 1 test
9+
test $DIR/dead-code-module-2.rs - my_mod::f (line 16) - compile ... FAILED
10+
611
failures:
712

813
---- $DIR/dead-code-module-2.rs - my_mod::f (line 16) stdout ----
@@ -26,5 +31,5 @@ Couldn't compile the test.
2631
failures:
2732
$DIR/dead-code-module-2.rs - my_mod::f (line 16)
2833

29-
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
34+
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
3035

0 commit comments

Comments
 (0)