@@ -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;
@@ -45,8 +46,6 @@ pub(crate) struct GlobalTestOptions {
4546 /// Whether inserting extra indent spaces in code block,
4647 /// default is `false`, only `true` for generating code link of Rust playground
4748 pub ( crate ) insert_indent_space : bool ,
48- /// Additional crate-level attributes to add to doctests.
49- pub ( crate ) attrs : Vec < String > ,
5049 /// Path to file containing arguments for the invocation of rustc.
5150 pub ( crate ) args_file : PathBuf ,
5251}
@@ -283,7 +282,7 @@ pub(crate) fn run_tests(
283282 rustdoc_options : & Arc < RustdocOptions > ,
284283 unused_extern_reports : & Arc < Mutex < Vec < UnusedExterns > > > ,
285284 mut standalone_tests : Vec < test:: TestDescAndFn > ,
286- mergeable_tests : FxIndexMap < Edition , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
285+ mergeable_tests : FxIndexMap < MergeableTestKey , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
287286 // We pass this argument so we can drop it manually before using `exit`.
288287 mut temp_dir : Option < TempDir > ,
289288) {
@@ -298,7 +297,7 @@ pub(crate) fn run_tests(
298297 let mut ran_edition_tests = 0 ;
299298 let target_str = rustdoc_options. target . to_string ( ) ;
300299
301- for ( edition, mut doctests) in mergeable_tests {
300+ for ( MergeableTestKey { edition, global_crate_attrs_hash } , mut doctests) in mergeable_tests {
302301 if doctests. is_empty ( ) {
303302 continue ;
304303 }
@@ -308,8 +307,8 @@ pub(crate) fn run_tests(
308307
309308 let rustdoc_test_options = IndividualTestOptions :: new (
310309 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" ) ) ,
313312 ) ;
314313
315314 for ( doctest, scraped_test) in & doctests {
@@ -371,12 +370,9 @@ fn scrape_test_config(
371370 attrs : & [ hir:: Attribute ] ,
372371 args_file : PathBuf ,
373372) -> GlobalTestOptions {
374- use rustc_ast_pretty:: pprust;
375-
376373 let mut opts = GlobalTestOptions {
377374 crate_name,
378375 no_crate_inject : false ,
379- attrs : Vec :: new ( ) ,
380376 insert_indent_space : false ,
381377 args_file,
382378 } ;
@@ -393,13 +389,7 @@ fn scrape_test_config(
393389 if attr. has_name ( sym:: no_crate_inject) {
394390 opts. no_crate_inject = true ;
395391 }
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
403393 }
404394
405395 opts
@@ -848,6 +838,7 @@ pub(crate) struct ScrapedDocTest {
848838 text : String ,
849839 name : String ,
850840 span : Span ,
841+ global_crate_attrs : Vec < String > ,
851842}
852843
853844impl ScrapedDocTest {
@@ -858,6 +849,7 @@ impl ScrapedDocTest {
858849 langstr : LangString ,
859850 text : String ,
860851 span : Span ,
852+ global_crate_attrs : Vec < String > ,
861853 ) -> Self {
862854 let mut item_path = logical_path. join ( "::" ) ;
863855 item_path. retain ( |c| c != ' ' ) ;
@@ -867,7 +859,7 @@ impl ScrapedDocTest {
867859 let name =
868860 format ! ( "{} - {item_path}(line {line})" , filename. prefer_remapped_unconditionaly( ) ) ;
869861
870- Self { filename, line, langstr, text, name, span }
862+ Self { filename, line, langstr, text, name, span, global_crate_attrs }
871863 }
872864 fn edition ( & self , opts : & RustdocOptions ) -> Edition {
873865 self . langstr . edition . unwrap_or ( opts. edition )
@@ -896,9 +888,15 @@ pub(crate) trait DocTestVisitor {
896888 fn visit_header ( & mut self , _name : & str , _level : u32 ) { }
897889}
898890
891+ #[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
892+ pub ( crate ) struct MergeableTestKey {
893+ edition : Edition ,
894+ global_crate_attrs_hash : u64 ,
895+ }
896+
899897struct CreateRunnableDocTests {
900898 standalone_tests : Vec < test:: TestDescAndFn > ,
901- mergeable_tests : FxIndexMap < Edition , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
899+ mergeable_tests : FxIndexMap < MergeableTestKey , Vec < ( DocTestBuilder , ScrapedDocTest ) > > ,
902900
903901 rustdoc_options : Arc < RustdocOptions > ,
904902 opts : GlobalTestOptions ,
@@ -949,6 +947,7 @@ impl CreateRunnableDocTests {
949947 let edition = scraped_test. edition ( & self . rustdoc_options ) ;
950948 let doctest = BuildDocTestBuilder :: new ( & scraped_test. text )
951949 . crate_name ( & self . opts . crate_name )
950+ . global_crate_attrs ( scraped_test. global_crate_attrs . clone ( ) )
952951 . edition ( edition)
953952 . can_merge_doctests ( self . can_merge_doctests )
954953 . test_id ( test_id)
@@ -965,7 +964,17 @@ impl CreateRunnableDocTests {
965964 let test_desc = self . generate_test_desc_and_fn ( doctest, scraped_test) ;
966965 self . standalone_tests . push ( test_desc) ;
967966 } 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) ) ;
969978 }
970979 }
971980
0 commit comments