@@ -164,7 +164,8 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, options: RustdocOptions) -> Result<()
164
164
let args_path = temp_dir. path ( ) . join ( "rustdoc-cfgs" ) ;
165
165
crate :: wrap_return ( dcx, generate_args_file ( & args_path, & options) ) ?;
166
166
167
- let ( tests, unused_extern_reports, compiling_test_count) =
167
+ // FIXME: use mergeable tests!
168
+ let ( standalone_tests, unused_extern_reports, compiling_test_count) =
168
169
interface:: run_compiler ( config, |compiler| {
169
170
compiler. enter ( |queries| {
170
171
let collector = queries. global_ctxt ( ) ?. enter ( |tcx| {
@@ -192,11 +193,11 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, options: RustdocOptions) -> Result<()
192
193
193
194
let unused_extern_reports = collector. unused_extern_reports . clone ( ) ;
194
195
let compiling_test_count = collector. compiling_test_count . load ( Ordering :: SeqCst ) ;
195
- Ok ( ( collector. tests , unused_extern_reports, compiling_test_count) )
196
+ Ok ( ( collector. standalone_tests , unused_extern_reports, compiling_test_count) )
196
197
} )
197
198
} ) ?;
198
199
199
- run_tests ( test_args, nocapture, tests ) ;
200
+ run_tests ( test_args, nocapture, standalone_tests ) ;
200
201
201
202
// Collect and warn about unused externs, but only if we've gotten
202
203
// reports for each doctest
@@ -617,7 +618,8 @@ pub(crate) trait DoctestVisitor {
617
618
}
618
619
619
620
struct CreateRunnableDoctests {
620
- tests : Vec < test:: TestDescAndFn > ,
621
+ standalone_tests : Vec < test:: TestDescAndFn > ,
622
+ mergeable_tests : FxHashMap < Edition , Vec < ( DocTest , ScrapedDoctest ) > > ,
621
623
622
624
rustdoc_options : Arc < RustdocOptions > ,
623
625
opts : GlobalTestOptions ,
@@ -629,7 +631,8 @@ struct CreateRunnableDoctests {
629
631
impl CreateRunnableDoctests {
630
632
fn new ( rustdoc_options : RustdocOptions , opts : GlobalTestOptions ) -> CreateRunnableDoctests {
631
633
CreateRunnableDoctests {
632
- tests : Vec :: new ( ) ,
634
+ standalone_tests : Vec :: new ( ) ,
635
+ mergeable_tests : FxHashMap :: default ( ) ,
633
636
rustdoc_options : Arc :: new ( rustdoc_options) ,
634
637
opts,
635
638
visited_tests : FxHashMap :: default ( ) ,
@@ -647,16 +650,40 @@ impl CreateRunnableDoctests {
647
650
format ! ( "{} - {item_path}(line {line})" , filename. prefer_remapped_unconditionaly( ) )
648
651
}
649
652
650
- fn add_test ( & mut self , test : ScrapedDoctest ) {
651
- let name = self . generate_name ( & test. filename , test. line , & test. logical_path ) ;
653
+ fn add_test ( & mut self , scraped_test : ScrapedDoctest ) {
654
+ let edition = scraped_test. edition ( & self . rustdoc_options ) ;
655
+ let doctest = DocTest :: new ( & scraped_test. text , Some ( & self . opts . crate_name ) , edition) ;
656
+ let is_standalone = scraped_test. langstr . compile_fail
657
+ || scraped_test. langstr . test_harness
658
+ || self . rustdoc_options . nocapture
659
+ || self . rustdoc_options . test_args . iter ( ) . any ( |arg| arg == "--show-output" )
660
+ || doctest. crate_attrs . contains ( "#![no_std]" ) ;
661
+ if is_standalone {
662
+ let test_desc = self . generate_test_desc_and_fn ( doctest, scraped_test) ;
663
+ self . standalone_tests . push ( test_desc) ;
664
+ } else {
665
+ self . mergeable_tests . entry ( edition) . or_default ( ) . push ( ( doctest, scraped_test) ) ;
666
+ }
667
+ }
668
+
669
+ fn generate_test_desc_and_fn (
670
+ & mut self ,
671
+ test : DocTest ,
672
+ scraped_test : ScrapedDoctest ,
673
+ ) -> test:: TestDescAndFn {
674
+ let name = self . generate_name (
675
+ & scraped_test. filename ,
676
+ scraped_test. line ,
677
+ & scraped_test. logical_path ,
678
+ ) ;
652
679
let opts = self . opts . clone ( ) ;
653
680
let target_str = self . rustdoc_options . target . to_string ( ) ;
654
681
let unused_externs = self . unused_extern_reports . clone ( ) ;
655
- if !test . langstr . compile_fail {
682
+ if !scraped_test . langstr . compile_fail {
656
683
self . compiling_test_count . fetch_add ( 1 , Ordering :: SeqCst ) ;
657
684
}
658
685
659
- let path = match & test . filename {
686
+ let path = match & scraped_test . filename {
660
687
FileName :: Real ( path) => {
661
688
if let Some ( local_path) = path. local_path ( ) {
662
689
local_path. to_path_buf ( )
@@ -669,7 +696,7 @@ impl CreateRunnableDoctests {
669
696
} ;
670
697
671
698
// For example `module/file.rs` would become `module_file_rs`
672
- let file = test
699
+ let file = scraped_test
673
700
. filename
674
701
. prefer_local ( )
675
702
. to_string_lossy ( )
@@ -679,12 +706,12 @@ impl CreateRunnableDoctests {
679
706
let test_id = format ! (
680
707
"{file}_{line}_{number}" ,
681
708
file = file,
682
- line = test . line,
709
+ line = scraped_test . line,
683
710
number = {
684
711
// Increases the current test number, if this file already
685
712
// exists or it creates a new entry with a test number of 0.
686
713
self . visited_tests
687
- . entry( ( file. clone( ) , test . line) )
714
+ . entry( ( file. clone( ) , scraped_test . line) )
688
715
. and_modify( |v| * v += 1 )
689
716
. or_insert( 0 )
690
717
} ,
@@ -693,11 +720,11 @@ impl CreateRunnableDoctests {
693
720
let rustdoc_options = self . rustdoc_options . clone ( ) ;
694
721
let rustdoc_test_options = IndividualTestOptions :: new ( & self . rustdoc_options , test_id, path) ;
695
722
696
- debug ! ( "creating test {name}: {}" , test . text) ;
697
- self . tests . push ( test:: TestDescAndFn {
723
+ debug ! ( "creating test {name}: {}" , scraped_test . text) ;
724
+ test:: TestDescAndFn {
698
725
desc : test:: TestDesc {
699
726
name : test:: DynTestName ( name) ,
700
- ignore : match test . langstr . ignore {
727
+ ignore : match scraped_test . langstr . ignore {
701
728
Ignore :: All => true ,
702
729
Ignore :: None => false ,
703
730
Ignore :: Some ( ref ignores) => ignores. iter ( ) . any ( |s| target_str. contains ( s) ) ,
@@ -710,30 +737,37 @@ impl CreateRunnableDoctests {
710
737
end_col : 0 ,
711
738
// compiler failures are test failures
712
739
should_panic : test:: ShouldPanic :: No ,
713
- compile_fail : test . langstr . compile_fail ,
714
- no_run : test . no_run ( & rustdoc_options) ,
740
+ compile_fail : scraped_test . langstr . compile_fail ,
741
+ no_run : scraped_test . no_run ( & rustdoc_options) ,
715
742
test_type : test:: TestType :: DocTest ,
716
743
} ,
717
744
testfn : test:: DynTestFn ( Box :: new ( move || {
718
- doctest_run_fn ( rustdoc_test_options, opts, test, rustdoc_options, unused_externs)
745
+ doctest_run_fn (
746
+ rustdoc_test_options,
747
+ opts,
748
+ test,
749
+ scraped_test,
750
+ rustdoc_options,
751
+ unused_externs,
752
+ )
719
753
} ) ) ,
720
- } ) ;
754
+ }
721
755
}
722
756
}
723
757
724
758
fn doctest_run_fn (
725
759
test_opts : IndividualTestOptions ,
726
760
global_opts : GlobalTestOptions ,
761
+ doctest : DocTest ,
727
762
scraped_test : ScrapedDoctest ,
728
763
rustdoc_options : Arc < RustdocOptions > ,
729
764
unused_externs : Arc < Mutex < Vec < UnusedExterns > > > ,
730
765
) -> Result < ( ) , String > {
731
766
let report_unused_externs = |uext| {
732
767
unused_externs. lock ( ) . unwrap ( ) . push ( uext) ;
733
768
} ;
734
- let edition = scraped_test. edition ( & rustdoc_options) ;
735
- let doctest = DocTest :: new ( & scraped_test. text , Some ( & global_opts. crate_name ) , edition) ;
736
769
let ( full_test_code, full_test_line_offset) = doctest. generate_unique_doctest (
770
+ & scraped_test. text ,
737
771
scraped_test. langstr . test_harness ,
738
772
& global_opts,
739
773
Some ( & test_opts. test_id ) ,
0 commit comments