Skip to content

Commit 64d9631

Browse files
Gracefully handle in case we cannot run the compiler in doctests
1 parent ebe145e commit 64d9631

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

src/librustdoc/doctest.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,10 @@ fn add_exe_suffix(input: String, target: &TargetTuple) -> String {
501501
input + &exe_suffix
502502
}
503503

504-
fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Command {
504+
fn wrapped_rustc_command<'a>(
505+
rustc_wrappers: &'a [PathBuf],
506+
rustc_binary: &'a Path,
507+
) -> (Command, &'a Path) {
505508
let mut args = rustc_wrappers.iter().map(PathBuf::as_path).chain([rustc_binary]);
506509

507510
let exe = args.next().expect("unable to create rustc command");
@@ -510,7 +513,7 @@ fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Com
510513
command.arg(arg);
511514
}
512515

513-
command
516+
(command, rustc_wrappers.first().map(|p| &**p).unwrap_or(rustc_binary))
514517
}
515518

516519
/// Information needed for running a bundle of doctests.
@@ -630,7 +633,8 @@ fn run_test(
630633
.test_builder
631634
.as_deref()
632635
.unwrap_or_else(|| rustc_interface::util::rustc_path(sysroot).expect("found rustc"));
633-
let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
636+
let (mut compiler, binary_path) =
637+
wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
634638

635639
compiler.args(&compiler_args);
636640

@@ -671,7 +675,13 @@ fn run_test(
671675

672676
debug!("compiler invocation for doctest: {compiler:?}");
673677

674-
let mut child = compiler.spawn().expect("Failed to spawn rustc process");
678+
let mut child = match compiler.spawn() {
679+
Ok(child) => child,
680+
Err(error) => {
681+
eprintln!("Failed to spawn {binary_path:?}: {error:?}");
682+
return (Duration::default(), Err(TestFailure::CompileError));
683+
}
684+
};
675685
let output = if let Some(merged_test_code) = &doctest.merged_test_code {
676686
// compile-fail tests never get merged, so this should always pass
677687
let status = child.wait().expect("Failed to wait");
@@ -680,7 +690,7 @@ fn run_test(
680690
// build it now
681691
let runner_input_file = doctest.path_for_merged_doctest_runner();
682692

683-
let mut runner_compiler =
693+
let (mut runner_compiler, binary_path) =
684694
wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
685695
// the test runner does not contain any user-written code, so this doesn't allow
686696
// the user to exploit nightly-only features on stable
@@ -733,7 +743,13 @@ fn run_test(
733743
let status = if !status.success() {
734744
status
735745
} else {
736-
let mut child_runner = runner_compiler.spawn().expect("Failed to spawn rustc process");
746+
let mut child_runner = match runner_compiler.spawn() {
747+
Ok(child) => child,
748+
Err(error) => {
749+
eprintln!("Failed to spawn {binary_path:?}: {error:?}");
750+
return (Duration::default(), Err(TestFailure::CompileError));
751+
}
752+
};
737753
child_runner.wait().expect("Failed to wait")
738754
};
739755

0 commit comments

Comments
 (0)