@@ -369,57 +369,59 @@ fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Com
369369 command
370370}
371371
372+ struct RunnableDoctest {
373+ full_test_code : String ,
374+ full_test_line_offset : usize ,
375+ test_opts : IndividualTestOptions ,
376+ global_opts : GlobalTestOptions ,
377+ scraped_test : ScrapedDoctest ,
378+ }
379+
372380fn run_test (
373- test : & str ,
374- line : usize ,
381+ doctest : RunnableDoctest ,
375382 rustdoc_options : & RustdocOptions ,
376- test_options : IndividualTestOptions ,
377- mut lang_string : LangString ,
378- no_run : bool ,
379- opts : & GlobalTestOptions ,
380- edition : Edition ,
383+ supports_color : bool ,
381384 report_unused_externs : impl Fn ( UnusedExterns ) ,
382385) -> Result < ( ) , TestFailure > {
383- let ( test, line_offset, supports_color) = make_test (
384- test,
385- Some ( & opts. crate_name ) ,
386- lang_string. test_harness ,
387- opts,
388- edition,
389- Some ( & test_options. test_id ) ,
390- ) ;
391-
386+ let scraped_test = & doctest. scraped_test ;
387+ let langstr = & scraped_test. langstr ;
392388 // Make sure we emit well-formed executable names for our target.
393389 let rust_out = add_exe_suffix ( "rust_out" . to_owned ( ) , & rustdoc_options. target ) ;
394- let output_file = test_options . outdir . path ( ) . join ( rust_out) ;
390+ let output_file = doctest . test_opts . outdir . path ( ) . join ( rust_out) ;
395391
396392 let rustc_binary = rustdoc_options
397393 . test_builder
398394 . as_deref ( )
399395 . unwrap_or_else ( || rustc_interface:: util:: rustc_path ( ) . expect ( "found rustc" ) ) ;
400396 let mut compiler = wrapped_rustc_command ( & rustdoc_options. test_builder_wrappers , rustc_binary) ;
401397
402- compiler. arg ( & format ! ( "@{}" , opts . args_file. display( ) ) ) ;
398+ compiler. arg ( & format ! ( "@{}" , doctest . global_opts . args_file. display( ) ) ) ;
403399
404400 if let Some ( sysroot) = & rustdoc_options. maybe_sysroot {
405401 compiler. arg ( format ! ( "--sysroot={}" , sysroot. display( ) ) ) ;
406402 }
407403
408- compiler. arg ( "--edition" ) . arg ( & edition. to_string ( ) ) ;
409- compiler. env ( "UNSTABLE_RUSTDOC_TEST_PATH" , & test_options. path ) ;
410- compiler. env ( "UNSTABLE_RUSTDOC_TEST_LINE" , format ! ( "{}" , line as isize - line_offset as isize ) ) ;
404+ compiler. arg ( "--edition" ) . arg ( & scraped_test. edition ( rustdoc_options) . to_string ( ) ) ;
405+ compiler. env ( "UNSTABLE_RUSTDOC_TEST_PATH" , & doctest. test_opts . path ) ;
406+ compiler. env (
407+ "UNSTABLE_RUSTDOC_TEST_LINE" ,
408+ format ! ( "{}" , scraped_test. line as isize - doctest. full_test_line_offset as isize ) ,
409+ ) ;
411410 compiler. arg ( "-o" ) . arg ( & output_file) ;
412- if lang_string . test_harness {
411+ if langstr . test_harness {
413412 compiler. arg ( "--test" ) ;
414413 }
415- if rustdoc_options. json_unused_externs . is_enabled ( ) && !lang_string . compile_fail {
414+ if rustdoc_options. json_unused_externs . is_enabled ( ) && !langstr . compile_fail {
416415 compiler. arg ( "--error-format=json" ) ;
417416 compiler. arg ( "--json" ) . arg ( "unused-externs" ) ;
418417 compiler. arg ( "-W" ) . arg ( "unused_crate_dependencies" ) ;
419418 compiler. arg ( "-Z" ) . arg ( "unstable-options" ) ;
420419 }
421420
422- if no_run && !lang_string. compile_fail && rustdoc_options. persist_doctests . is_none ( ) {
421+ if scraped_test. no_run ( rustdoc_options)
422+ && !langstr. compile_fail
423+ && rustdoc_options. persist_doctests . is_none ( )
424+ {
423425 // FIXME: why does this code check if it *shouldn't* persist doctests
424426 // -- shouldn't it be the negation?
425427 compiler. arg ( "--emit=metadata" ) ;
@@ -459,7 +461,7 @@ fn run_test(
459461 let mut child = compiler. spawn ( ) . expect ( "Failed to spawn rustc process" ) ;
460462 {
461463 let stdin = child. stdin . as_mut ( ) . expect ( "Failed to open stdin" ) ;
462- stdin. write_all ( test . as_bytes ( ) ) . expect ( "could write out test sources" ) ;
464+ stdin. write_all ( doctest . full_test_code . as_bytes ( ) ) . expect ( "could write out test sources" ) ;
463465 }
464466 let output = child. wait_with_output ( ) . expect ( "Failed to read stdout" ) ;
465467
@@ -490,20 +492,26 @@ fn run_test(
490492 }
491493
492494 let _bomb = Bomb ( & out) ;
493- match ( output. status . success ( ) , lang_string . compile_fail ) {
495+ match ( output. status . success ( ) , langstr . compile_fail ) {
494496 ( true , true ) => {
495497 return Err ( TestFailure :: UnexpectedCompilePass ) ;
496498 }
497499 ( true , false ) => { }
498500 ( false , true ) => {
499- if !lang_string . error_codes . is_empty ( ) {
501+ if !langstr . error_codes . is_empty ( ) {
500502 // We used to check if the output contained "error[{}]: " but since we added the
501503 // colored output, we can't anymore because of the color escape characters before
502504 // the ":".
503- lang_string. error_codes . retain ( |err| !out. contains ( & format ! ( "error[{err}]" ) ) ) ;
504-
505- if !lang_string. error_codes . is_empty ( ) {
506- return Err ( TestFailure :: MissingErrorCodes ( lang_string. error_codes ) ) ;
505+ let missing_codes: Vec < String > = scraped_test
506+ . langstr
507+ . error_codes
508+ . iter ( )
509+ . filter ( |err| !out. contains ( & format ! ( "error[{err}]" ) ) )
510+ . cloned ( )
511+ . collect ( ) ;
512+
513+ if !missing_codes. is_empty ( ) {
514+ return Err ( TestFailure :: MissingErrorCodes ( missing_codes) ) ;
507515 }
508516 }
509517 }
@@ -512,7 +520,7 @@ fn run_test(
512520 }
513521 }
514522
515- if no_run {
523+ if scraped_test . no_run ( rustdoc_options ) {
516524 return Ok ( ( ) ) ;
517525 }
518526
@@ -544,9 +552,9 @@ fn run_test(
544552 match result {
545553 Err ( e) => return Err ( TestFailure :: ExecutionError ( e) ) ,
546554 Ok ( out) => {
547- if lang_string . should_panic && out. status . success ( ) {
555+ if langstr . should_panic && out. status . success ( ) {
548556 return Err ( TestFailure :: UnexpectedRunPass ) ;
549- } else if !lang_string . should_panic && !out. status . success ( ) {
557+ } else if !langstr . should_panic && !out. status . success ( ) {
550558 return Err ( TestFailure :: ExecutionFailure ( out) ) ;
551559 }
552560 }
@@ -1100,19 +1108,23 @@ fn doctest_run_fn(
11001108 let report_unused_externs = |uext| {
11011109 unused_externs. lock ( ) . unwrap ( ) . push ( uext) ;
11021110 } ;
1103- let no_run = scraped_test. no_run ( & rustdoc_options) ;
11041111 let edition = scraped_test. edition ( & rustdoc_options) ;
1105- let res = run_test (
1112+ let ( full_test_code , full_test_line_offset , supports_color ) = make_test (
11061113 & scraped_test. text ,
1107- scraped_test. line ,
1108- & rustdoc_options,
1109- test_opts,
1110- scraped_test. langstr ,
1111- no_run,
1114+ Some ( & global_opts. crate_name ) ,
1115+ scraped_test. langstr . test_harness ,
11121116 & global_opts,
11131117 edition,
1114- report_unused_externs ,
1118+ Some ( & test_opts . test_id ) ,
11151119 ) ;
1120+ let runnable_test = RunnableDoctest {
1121+ full_test_code,
1122+ full_test_line_offset,
1123+ test_opts,
1124+ global_opts,
1125+ scraped_test,
1126+ } ;
1127+ let res = run_test ( runnable_test, & rustdoc_options, supports_color, report_unused_externs) ;
11161128
11171129 if let Err ( err) = res {
11181130 match err {
0 commit comments