Skip to content

Commit ec1b2fa

Browse files
Gracefully handle in case we cannot run the compiler in doctests
1 parent f2bae99 commit ec1b2fa

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
@@ -500,7 +500,10 @@ fn add_exe_suffix(input: String, target: &TargetTuple) -> String {
500500
input + &exe_suffix
501501
}
502502

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

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

512-
command
515+
(command, rustc_wrappers.first().map(|p| &**p).unwrap_or(rustc_binary))
513516
}
514517

515518
/// Information needed for running a bundle of doctests.
@@ -629,7 +632,8 @@ fn run_test(
629632
.test_builder
630633
.as_deref()
631634
.unwrap_or_else(|| rustc_interface::util::rustc_path(sysroot).expect("found rustc"));
632-
let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
635+
let (mut compiler, binary_path) =
636+
wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
633637

634638
compiler.args(&compiler_args);
635639

@@ -670,7 +674,13 @@ fn run_test(
670674

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

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

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

0 commit comments

Comments
 (0)