@@ -5,6 +5,7 @@ mod runner;
55mod rust;
66
77use std:: fs:: File ;
8+ use std:: hash:: { Hash , Hasher } ;
89use std:: io:: { self , Write } ;
910use std:: path:: { Path , PathBuf } ;
1011use std:: process:: { self , Command , Stdio } ;
@@ -14,7 +15,7 @@ use std::{panic, str};
1415
1516pub ( crate ) use make:: { BuildDocTestBuilder , DocTestBuilder } ;
1617pub ( 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 } ;
1819use rustc_errors:: emitter:: HumanReadableErrorType ;
1920use rustc_errors:: { ColorConfig , DiagCtxtHandle } ;
2021use 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+
890897struct 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
0 commit comments