@@ -5,6 +5,7 @@ mod runner;
5
5
mod rust;
6
6
7
7
use std:: fs:: File ;
8
+ use std:: hash:: { Hash , Hasher } ;
8
9
use std:: io:: { self , Write } ;
9
10
use std:: path:: { Path , PathBuf } ;
10
11
use std:: process:: { self , Command , Stdio } ;
@@ -14,7 +15,7 @@ use std::{panic, str};
14
15
15
16
pub ( crate ) use make:: DocTestBuilder ;
16
17
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 } ;
18
19
use rustc_errors:: emitter:: HumanReadableErrorType ;
19
20
use rustc_errors:: { ColorConfig , DiagCtxtHandle } ;
20
21
use rustc_hir as hir;
@@ -313,7 +314,7 @@ pub(crate) fn run_tests(
313
314
rustdoc_options : & Arc < RustdocOptions > ,
314
315
unused_extern_reports : & Arc < Mutex < Vec < UnusedExterns > > > ,
315
316
mut standalone_tests : Vec < test:: TestDescAndFn > ,
316
- mergeable_tests : FxIndexMap < Edition , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
317
+ mergeable_tests : FxIndexMap < MergeableTestKey , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
317
318
) {
318
319
let mut test_args = Vec :: with_capacity ( rustdoc_options. test_args . len ( ) + 1 ) ;
319
320
test_args. insert ( 0 , "rustdoctest" . to_string ( ) ) ;
@@ -326,7 +327,7 @@ pub(crate) fn run_tests(
326
327
let mut ran_edition_tests = 0 ;
327
328
let target_str = rustdoc_options. target . to_string ( ) ;
328
329
329
- for ( edition, mut doctests) in mergeable_tests {
330
+ for ( MergeableTestKey { edition, global_crate_attrs_hash } , mut doctests) in mergeable_tests {
330
331
if doctests. is_empty ( ) {
331
332
continue ;
332
333
}
@@ -336,8 +337,8 @@ pub(crate) fn run_tests(
336
337
337
338
let rustdoc_test_options = IndividualTestOptions :: new (
338
339
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" ) ) ,
341
342
) ;
342
343
343
344
for ( doctest, scraped_test) in & doctests {
@@ -910,9 +911,15 @@ pub(crate) trait DocTestVisitor {
910
911
fn visit_header ( & mut self , _name : & str , _level : u32 ) { }
911
912
}
912
913
914
+ #[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
915
+ pub ( crate ) struct MergeableTestKey {
916
+ edition : Edition ,
917
+ global_crate_attrs_hash : u64 ,
918
+ }
919
+
913
920
struct CreateRunnableDocTests {
914
921
standalone_tests : Vec < test:: TestDescAndFn > ,
915
- mergeable_tests : FxIndexMap < Edition , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
922
+ mergeable_tests : FxIndexMap < MergeableTestKey , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
916
923
917
924
rustdoc_options : Arc < RustdocOptions > ,
918
925
opts : GlobalTestOptions ,
@@ -980,7 +987,17 @@ impl CreateRunnableDocTests {
980
987
let test_desc = self . generate_test_desc_and_fn ( doctest, scraped_test) ;
981
988
self . standalone_tests . push ( test_desc) ;
982
989
} 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) ) ;
984
1001
}
985
1002
}
986
1003
0 commit comments