diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 913ccf8e68089..6847b175e60eb 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -1138,6 +1138,16 @@ pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorReported>
     })
 }
 
+/// Variant of `catch_fatal_errors` for the `interface::Result` return type
+/// that also computes the exit code.
+pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 {
+    let result = catch_fatal_errors(f).and_then(|result| result);
+    match result {
+        Ok(()) => EXIT_SUCCESS,
+        Err(_) => EXIT_FAILURE,
+    }
+}
+
 lazy_static! {
     static ref DEFAULT_HOOK: Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static> = {
         let hook = panic::take_hook();
@@ -1228,12 +1238,12 @@ pub fn init_rustc_env_logger() {
     env_logger::init_from_env("RUSTC_LOG");
 }
 
-pub fn main() {
+pub fn main() -> ! {
     let start = Instant::now();
     init_rustc_env_logger();
     let mut callbacks = TimePassesCallbacks::default();
     install_ice_hook();
-    let result = catch_fatal_errors(|| {
+    let exit_code = catch_with_exit_code(|| {
         let args = env::args_os()
             .enumerate()
             .map(|(i, arg)| {
@@ -1246,13 +1256,8 @@ pub fn main() {
             })
             .collect::<Vec<_>>();
         run_compiler(&args, &mut callbacks, None, None)
-    })
-    .and_then(|result| result);
-    let exit_code = match result {
-        Ok(_) => EXIT_SUCCESS,
-        Err(_) => EXIT_FAILURE,
-    };
+    });
     // The extra `\t` is necessary to align this label with the others.
     print_time_passes_entry(callbacks.time_passes, "\ttotal", start.elapsed());
-    process::exit(exit_code);
+    process::exit(exit_code)
 }
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index 2c699998ea90e..1ce0300f23904 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -296,7 +296,7 @@ pub fn main() {
     rustc_driver::init_rustc_env_logger();
     lazy_static::initialize(&ICE_HOOK);
     exit(
-        rustc_driver::catch_fatal_errors(move || {
+        rustc_driver::catch_with_exit_code(move || {
             let mut orig_args: Vec<String> = env::args().collect();
 
             if orig_args.iter().any(|a| a == "--version" || a == "-V") {
@@ -411,7 +411,5 @@ pub fn main() {
                 if clippy_enabled { &mut clippy } else { &mut default };
             rustc_driver::run_compiler(&args, callbacks, None, None)
         })
-        .and_then(|result| result)
-        .is_err() as i32,
     )
 }