@@ -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:: { BuildDocTestBuilder , 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;
@@ -45,8 +46,6 @@ pub(crate) struct GlobalTestOptions {
45
46
/// Whether inserting extra indent spaces in code block,
46
47
/// default is `false`, only `true` for generating code link of Rust playground
47
48
pub ( crate ) insert_indent_space : bool ,
48
- /// Additional crate-level attributes to add to doctests.
49
- pub ( crate ) attrs : Vec < String > ,
50
49
/// Path to file containing arguments for the invocation of rustc.
51
50
pub ( crate ) args_file : PathBuf ,
52
51
}
@@ -283,7 +282,7 @@ pub(crate) fn run_tests(
283
282
rustdoc_options : & Arc < RustdocOptions > ,
284
283
unused_extern_reports : & Arc < Mutex < Vec < UnusedExterns > > > ,
285
284
mut standalone_tests : Vec < test:: TestDescAndFn > ,
286
- mergeable_tests : FxIndexMap < Edition , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
285
+ mergeable_tests : FxIndexMap < MergeableTestKey , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
287
286
// We pass this argument so we can drop it manually before using `exit`.
288
287
mut temp_dir : Option < TempDir > ,
289
288
) {
@@ -298,7 +297,7 @@ pub(crate) fn run_tests(
298
297
let mut ran_edition_tests = 0 ;
299
298
let target_str = rustdoc_options. target . to_string ( ) ;
300
299
301
- for ( edition, mut doctests) in mergeable_tests {
300
+ for ( MergeableTestKey { edition, global_crate_attrs_hash } , mut doctests) in mergeable_tests {
302
301
if doctests. is_empty ( ) {
303
302
continue ;
304
303
}
@@ -308,8 +307,8 @@ pub(crate) fn run_tests(
308
307
309
308
let rustdoc_test_options = IndividualTestOptions :: new (
310
309
rustdoc_options,
311
- & Some ( format ! ( "merged_doctest_{edition}" ) ) ,
312
- 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" ) ) ,
313
312
) ;
314
313
315
314
for ( doctest, scraped_test) in & doctests {
@@ -371,12 +370,9 @@ fn scrape_test_config(
371
370
attrs : & [ hir:: Attribute ] ,
372
371
args_file : PathBuf ,
373
372
) -> GlobalTestOptions {
374
- use rustc_ast_pretty:: pprust;
375
-
376
373
let mut opts = GlobalTestOptions {
377
374
crate_name,
378
375
no_crate_inject : false ,
379
- attrs : Vec :: new ( ) ,
380
376
insert_indent_space : false ,
381
377
args_file,
382
378
} ;
@@ -393,13 +389,7 @@ fn scrape_test_config(
393
389
if attr. has_name ( sym:: no_crate_inject) {
394
390
opts. no_crate_inject = true ;
395
391
}
396
- if attr. has_name ( sym:: attr)
397
- && let Some ( l) = attr. meta_item_list ( )
398
- {
399
- for item in l {
400
- opts. attrs . push ( pprust:: meta_list_item_to_string ( item) ) ;
401
- }
402
- }
392
+ // NOTE: `test(attr(..))` is handled when discovering the individual tests
403
393
}
404
394
405
395
opts
@@ -848,6 +838,7 @@ pub(crate) struct ScrapedDocTest {
848
838
text : String ,
849
839
name : String ,
850
840
span : Span ,
841
+ global_crate_attrs : Vec < String > ,
851
842
}
852
843
853
844
impl ScrapedDocTest {
@@ -858,6 +849,7 @@ impl ScrapedDocTest {
858
849
langstr : LangString ,
859
850
text : String ,
860
851
span : Span ,
852
+ global_crate_attrs : Vec < String > ,
861
853
) -> Self {
862
854
let mut item_path = logical_path. join ( "::" ) ;
863
855
item_path. retain ( |c| c != ' ' ) ;
@@ -867,7 +859,7 @@ impl ScrapedDocTest {
867
859
let name =
868
860
format ! ( "{} - {item_path}(line {line})" , filename. prefer_remapped_unconditionaly( ) ) ;
869
861
870
- Self { filename, line, langstr, text, name, span }
862
+ Self { filename, line, langstr, text, name, span, global_crate_attrs }
871
863
}
872
864
fn edition ( & self , opts : & RustdocOptions ) -> Edition {
873
865
self . langstr . edition . unwrap_or ( opts. edition )
@@ -896,9 +888,15 @@ pub(crate) trait DocTestVisitor {
896
888
fn visit_header ( & mut self , _name : & str , _level : u32 ) { }
897
889
}
898
890
891
+ #[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
892
+ pub ( crate ) struct MergeableTestKey {
893
+ edition : Edition ,
894
+ global_crate_attrs_hash : u64 ,
895
+ }
896
+
899
897
struct CreateRunnableDocTests {
900
898
standalone_tests : Vec < test:: TestDescAndFn > ,
901
- mergeable_tests : FxIndexMap < Edition , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
899
+ mergeable_tests : FxIndexMap < MergeableTestKey , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
902
900
903
901
rustdoc_options : Arc < RustdocOptions > ,
904
902
opts : GlobalTestOptions ,
@@ -949,6 +947,7 @@ impl CreateRunnableDocTests {
949
947
let edition = scraped_test. edition ( & self . rustdoc_options ) ;
950
948
let doctest = BuildDocTestBuilder :: new ( & scraped_test. text )
951
949
. crate_name ( & self . opts . crate_name )
950
+ . global_crate_attrs ( scraped_test. global_crate_attrs . clone ( ) )
952
951
. edition ( edition)
953
952
. can_merge_doctests ( self . can_merge_doctests )
954
953
. test_id ( test_id)
@@ -965,7 +964,17 @@ impl CreateRunnableDocTests {
965
964
let test_desc = self . generate_test_desc_and_fn ( doctest, scraped_test) ;
966
965
self . standalone_tests . push ( test_desc) ;
967
966
} else {
968
- 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) ) ;
969
978
}
970
979
}
971
980
0 commit comments