@@ -33,7 +33,7 @@ use tempfile::{Builder as TempFileBuilder, TempDir};
3333use tracing:: debug;
3434
3535use self :: rust:: HirCollector ;
36- use crate :: config:: { Options as RustdocOptions , OutputFormat } ;
36+ use crate :: config:: { MergeDoctests , Options as RustdocOptions , OutputFormat } ;
3737use crate :: html:: markdown:: { ErrorCodes , Ignore , LangString , MdRelLine } ;
3838use crate :: lint:: init_lints;
3939
@@ -123,8 +123,13 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) ->
123123 Ok ( ( ) )
124124}
125125
126- fn get_doctest_dir ( ) -> io:: Result < TempDir > {
127- TempFileBuilder :: new ( ) . prefix ( "rustdoctest" ) . tempdir ( )
126+ fn get_doctest_dir ( opts : & RustdocOptions ) -> io:: Result < TempDir > {
127+ let mut builder = TempFileBuilder :: new ( ) ;
128+ builder. prefix ( "rustdoctest" ) ;
129+ if opts. codegen_options . save_temps {
130+ builder. disable_cleanup ( true ) ;
131+ }
132+ builder. tempdir ( )
128133}
129134
130135pub ( crate ) fn run ( dcx : DiagCtxtHandle < ' _ > , input : Input , options : RustdocOptions ) {
@@ -197,7 +202,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
197202 let externs = options. externs . clone ( ) ;
198203 let json_unused_externs = options. json_unused_externs ;
199204
200- let temp_dir = match get_doctest_dir ( )
205+ let temp_dir = match get_doctest_dir ( & options )
201206 . map_err ( |error| format ! ( "failed to create temporary directory: {error:?}" ) )
202207 {
203208 Ok ( temp_dir) => temp_dir,
@@ -207,6 +212,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
207212 crate :: wrap_return ( dcx, generate_args_file ( & args_path, & options) ) ;
208213
209214 let extract_doctests = options. output_format == OutputFormat :: Doctest ;
215+ let save_temps = options. codegen_options . save_temps ;
210216 let result = interface:: run_compiler ( config, |compiler| {
211217 let krate = rustc_interface:: passes:: parse ( & compiler. sess ) ;
212218
@@ -259,12 +265,15 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
259265 eprintln ! ( "{error}" ) ;
260266 // Since some files in the temporary folder are still owned and alive, we need
261267 // to manually remove the folder.
262- let _ = std:: fs:: remove_dir_all ( temp_dir. path ( ) ) ;
268+ if !save_temps {
269+ let _ = std:: fs:: remove_dir_all ( temp_dir. path ( ) ) ;
270+ }
263271 std:: process:: exit ( 1 ) ;
264272 }
265273 } ;
266274
267275 run_tests (
276+ dcx,
268277 opts,
269278 & rustdoc_options,
270279 & unused_extern_reports,
@@ -316,6 +325,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
316325}
317326
318327pub ( crate ) fn run_tests (
328+ dcx : DiagCtxtHandle < ' _ > ,
319329 opts : GlobalTestOptions ,
320330 rustdoc_options : & Arc < RustdocOptions > ,
321331 unused_extern_reports : & Arc < Mutex < Vec < UnusedExterns > > > ,
@@ -368,6 +378,13 @@ pub(crate) fn run_tests(
368378 }
369379 continue ;
370380 }
381+
382+ if rustdoc_options. merge_doctests == MergeDoctests :: Always {
383+ let mut diag = dcx. struct_fatal ( "failed to merge doctests" ) ;
384+ diag. note ( "requested explicitly on the command line with `--merge-doctests=yes`" ) ;
385+ diag. emit ( ) ;
386+ }
387+
371388 // We failed to compile all compatible tests as one so we push them into the
372389 // `standalone_tests` doctests.
373390 debug ! ( "Failed to compile compatible doctests for edition {} all at once" , edition) ;
@@ -645,9 +662,9 @@ fn run_test(
645662 // tested as standalone tests.
646663 return ( Duration :: default ( ) , Err ( TestFailure :: CompileError ) ) ;
647664 }
648- if !rustdoc_options. no_capture {
649- // If `no_capture` is disabled, then we don't display rustc's output when compiling
650- // the merged doctests.
665+ if !rustdoc_options. no_capture && rustdoc_options . merge_doctests == MergeDoctests :: Auto {
666+ // If `no_capture` is disabled, and we might fallback to standalone tests, then we don't
667+ // display rustc's output when compiling the merged doctests.
651668 compiler. stderr ( Stdio :: null ( ) ) ;
652669 }
653670 // bundled tests are an rlib, loaded by a separate runner executable
@@ -728,10 +745,12 @@ fn run_test(
728745 // tested as standalone tests.
729746 return ( instant. elapsed ( ) , Err ( TestFailure :: CompileError ) ) ;
730747 }
731- if !rustdoc_options. no_capture {
732- // If `no_capture` is disabled, then we don't display rustc's output when compiling
733- // the merged doctests.
748+ if !rustdoc_options. no_capture && rustdoc_options . merge_doctests == MergeDoctests :: Auto {
749+ // If `no_capture` is disabled and we're autodetecting whether to merge,
750+ // we don't display rustc's output when compiling the merged doctests.
734751 runner_compiler. stderr ( Stdio :: null ( ) ) ;
752+ } else {
753+ runner_compiler. stderr ( Stdio :: inherit ( ) ) ;
735754 }
736755 runner_compiler. arg ( "--error-format=short" ) ;
737756 debug ! ( "compiler invocation for doctest runner: {runner_compiler:?}" ) ;
@@ -888,7 +907,7 @@ impl IndividualTestOptions {
888907
889908 DirState :: Perm ( path)
890909 } else {
891- DirState :: Temp ( get_doctest_dir ( ) . expect ( "rustdoc needs a tempdir" ) )
910+ DirState :: Temp ( get_doctest_dir ( options ) . expect ( "rustdoc needs a tempdir" ) )
892911 } ;
893912
894913 Self { outdir, path : test_path }
@@ -977,21 +996,20 @@ struct CreateRunnableDocTests {
977996 visited_tests : FxHashMap < ( String , usize ) , usize > ,
978997 unused_extern_reports : Arc < Mutex < Vec < UnusedExterns > > > ,
979998 compiling_test_count : AtomicUsize ,
980- can_merge_doctests : bool ,
999+ can_merge_doctests : MergeDoctests ,
9811000}
9821001
9831002impl CreateRunnableDocTests {
9841003 fn new ( rustdoc_options : RustdocOptions , opts : GlobalTestOptions ) -> CreateRunnableDocTests {
985- let can_merge_doctests = rustdoc_options. edition >= Edition :: Edition2024 ;
9861004 CreateRunnableDocTests {
9871005 standalone_tests : Vec :: new ( ) ,
9881006 mergeable_tests : FxIndexMap :: default ( ) ,
989- rustdoc_options : Arc :: new ( rustdoc_options) ,
9901007 opts,
9911008 visited_tests : FxHashMap :: default ( ) ,
9921009 unused_extern_reports : Default :: default ( ) ,
9931010 compiling_test_count : AtomicUsize :: new ( 0 ) ,
994- can_merge_doctests,
1011+ can_merge_doctests : rustdoc_options. merge_doctests ,
1012+ rustdoc_options : Arc :: new ( rustdoc_options) ,
9951013 }
9961014 }
9971015
0 commit comments