diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 6bb8c5452b989..6e870728bafc4 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -347,8 +347,14 @@ macro_rules! run_driver {
                         Err(CompilerError::Interrupted(value))
                     }
                     (Ok(Ok(_)), None) => Err(CompilerError::Skipped),
-                    (Ok(Err(_)), _) => Err(CompilerError::CompilationFailed),
-                    (Err(_), _) => Err(CompilerError::ICE),
+                    // Two cases here:
+                    // - `run` finished normally and returned `Err`
+                    // - `run` panicked with `FatalErr`
+                    // You might think that normal compile errors cause the former, and
+                    // ICEs cause the latter. But some normal compiler errors also cause
+                    // the latter. So we can't meaningfully distinguish them, and group
+                    // them together.
+                    (Ok(Err(_)), _) | (Err(_), _) => Err(CompilerError::Failed),
                 }
             }
         }
diff --git a/compiler/stable_mir/src/error.rs b/compiler/stable_mir/src/error.rs
index 7085fa937c98e..9e3f49369442d 100644
--- a/compiler/stable_mir/src/error.rs
+++ b/compiler/stable_mir/src/error.rs
@@ -15,10 +15,8 @@ macro_rules! error {
 /// An error type used to represent an error that has already been reported by the compiler.
 #[derive(Clone, Copy, PartialEq, Eq)]
 pub enum CompilerError<T> {
-    /// Internal compiler error (I.e.: Compiler crashed).
-    ICE,
-    /// Compilation failed.
-    CompilationFailed,
+    /// Compilation failed, either due to normal errors or ICE.
+    Failed,
     /// Compilation was interrupted.
     Interrupted(T),
     /// Compilation skipped. This happens when users invoke rustc to retrieve information such as
@@ -54,8 +52,7 @@ where
 {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         match self {
-            CompilerError::ICE => write!(f, "Internal Compiler Error"),
-            CompilerError::CompilationFailed => write!(f, "Compilation Failed"),
+            CompilerError::Failed => write!(f, "Compilation Failed"),
             CompilerError::Interrupted(reason) => write!(f, "Compilation Interrupted: {reason}"),
             CompilerError::Skipped => write!(f, "Compilation Skipped"),
         }
@@ -68,8 +65,7 @@ where
 {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         match self {
-            CompilerError::ICE => write!(f, "Internal Compiler Error"),
-            CompilerError::CompilationFailed => write!(f, "Compilation Failed"),
+            CompilerError::Failed => write!(f, "Compilation Failed"),
             CompilerError::Interrupted(reason) => write!(f, "Compilation Interrupted: {reason:?}"),
             CompilerError::Skipped => write!(f, "Compilation Skipped"),
         }
diff --git a/tests/ui-fulldeps/stable-mir/compilation-result.rs b/tests/ui-fulldeps/stable-mir/compilation-result.rs
index e6dd9fa132d83..cd61d599eb43d 100644
--- a/tests/ui-fulldeps/stable-mir/compilation-result.rs
+++ b/tests/ui-fulldeps/stable-mir/compilation-result.rs
@@ -55,7 +55,7 @@ fn test_skipped(mut args: Vec<String>) {
 fn test_failed(mut args: Vec<String>) {
     args.push("--cfg=broken".to_string());
     let result = run!(args, || unreachable!() as ControlFlow<()>);
-    assert_eq!(result, Err(stable_mir::CompilerError::CompilationFailed));
+    assert_eq!(result, Err(stable_mir::CompilerError::Failed));
 }
 
 /// Test that we are able to pass a closure and set the return according to the captured value.