diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index f560350d5105d..6a20980575a24 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -202,8 +202,8 @@ impl Impl { #[derive(Debug)] pub struct Error { - file: PathBuf, - error: io::Error, + pub file: PathBuf, + pub error: io::Error, } impl error::Error for Error { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 4b043b26d8650..b21f005c06bff 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -387,9 +387,21 @@ fn main_args(args: &[String]) -> isize { info!("going to format"); let (error_format, treat_err_as_bug, ui_testing) = diag_opts; let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing); - html::render::run(krate, renderopts, passes.into_iter().collect(), renderinfo, &diag) - .expect("failed to generate documentation"); - 0 + match html::render::run( + krate, + renderopts, + passes.into_iter().collect(), + renderinfo, + &diag, + ) { + Ok(_) => rustc_driver::EXIT_SUCCESS, + Err(e) => { + diag.struct_err(&format!("couldn't generate documentation: {}", e.error)) + .note(&format!("failed to create or modify \"{}\"", e.file.display())) + .emit(); + rustc_driver::EXIT_FAILURE + } + } }) } diff --git a/src/test/run-make-fulldeps/rustdoc-io-error/Makefile b/src/test/run-make-fulldeps/rustdoc-io-error/Makefile new file mode 100644 index 0000000000000..2055c9cbf2da0 --- /dev/null +++ b/src/test/run-make-fulldeps/rustdoc-io-error/Makefile @@ -0,0 +1,25 @@ +-include ../tools.mk + +# This test verifies that rustdoc doesn't ICE when it encounters an IO error +# while generating files. Ideally this would be a rustdoc-ui test, so we could +# verify the error message as well. + +OUTPUT_DIR := "$(TMPDIR)/rustdoc-io-error" + +# Ignore Windows: the test uses `chmod`. +ifndef IS_WINDOWS + +# This test operates by creating a temporary directory and modifying its +# permissions so that it is not writable. We have to take special care to set +# the permissions back to normal so that it's able to be deleted later. +all: + mkdir -p $(OUTPUT_DIR) + chmod u-w $(OUTPUT_DIR) + -$(shell $(RUSTDOC) -o $(OUTPUT_DIR) foo.rs) + chmod u+w $(OUTPUT_DIR) + exit $($(.SHELLSTATUS) -eq 1) + +else +all: + +endif diff --git a/src/test/run-make-fulldeps/rustdoc-io-error/foo.rs b/src/test/run-make-fulldeps/rustdoc-io-error/foo.rs new file mode 100644 index 0000000000000..4a835673a596b --- /dev/null +++ b/src/test/run-make-fulldeps/rustdoc-io-error/foo.rs @@ -0,0 +1 @@ +pub struct Foo;