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;