@@ -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:: 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;
@@ -313,7 +314,7 @@ pub(crate) fn run_tests(
313314 rustdoc_options : & Arc < RustdocOptions > ,
314315 unused_extern_reports : & Arc < Mutex < Vec < UnusedExterns > > > ,
315316 mut standalone_tests : Vec < test:: TestDescAndFn > ,
316- mergeable_tests : FxIndexMap < Edition , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
317+ mergeable_tests : FxIndexMap < MergeableTestKey , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
317318) {
318319 let mut test_args = Vec :: with_capacity ( rustdoc_options. test_args . len ( ) + 1 ) ;
319320 test_args. insert ( 0 , "rustdoctest" . to_string ( ) ) ;
@@ -326,7 +327,7 @@ pub(crate) fn run_tests(
326327 let mut ran_edition_tests = 0 ;
327328 let target_str = rustdoc_options. target . to_string ( ) ;
328329
329- for ( edition, mut doctests) in mergeable_tests {
330+ for ( MergeableTestKey { edition, global_crate_attrs_hash } , mut doctests) in mergeable_tests {
330331 if doctests. is_empty ( ) {
331332 continue ;
332333 }
@@ -336,8 +337,8 @@ pub(crate) fn run_tests(
336337
337338 let rustdoc_test_options = IndividualTestOptions :: new (
338339 rustdoc_options,
339- & Some ( format ! ( "merged_doctest_{edition}" ) ) ,
340- PathBuf :: from ( format ! ( "doctest_{edition}.rs" ) ) ,
340+ & Some ( format ! ( "merged_doctest_{edition}_{global_crate_attrs_hash} " ) ) ,
341+ PathBuf :: from ( format ! ( "doctest_{edition}_{global_crate_attrs_hash} .rs" ) ) ,
341342 ) ;
342343
343344 for ( doctest, scraped_test) in & doctests {
@@ -910,9 +911,15 @@ pub(crate) trait DocTestVisitor {
910911 fn visit_header ( & mut self , _name : & str , _level : u32 ) { }
911912}
912913
914+ #[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
915+ pub ( crate ) struct MergeableTestKey {
916+ edition : Edition ,
917+ global_crate_attrs_hash : u64 ,
918+ }
919+
913920struct CreateRunnableDocTests {
914921 standalone_tests : Vec < test:: TestDescAndFn > ,
915- mergeable_tests : FxIndexMap < Edition , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
922+ mergeable_tests : FxIndexMap < MergeableTestKey , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
916923
917924 rustdoc_options : Arc < RustdocOptions > ,
918925 opts : GlobalTestOptions ,
@@ -980,7 +987,17 @@ impl CreateRunnableDocTests {
980987 let test_desc = self . generate_test_desc_and_fn ( doctest, scraped_test) ;
981988 self . standalone_tests . push ( test_desc) ;
982989 } else {
983- self . mergeable_tests . entry ( edition) . or_default ( ) . push ( ( doctest, scraped_test) ) ;
990+ self . mergeable_tests
991+ . entry ( MergeableTestKey {
992+ edition,
993+ global_crate_attrs_hash : {
994+ let mut hasher = FxHasher :: default ( ) ;
995+ scraped_test. global_crate_attrs . hash ( & mut hasher) ;
996+ hasher. finish ( )
997+ } ,
998+ } )
999+ . or_default ( )
1000+ . push ( ( doctest, scraped_test) ) ;
9841001 }
9851002 }
9861003
0 commit comments