about summary refs log tree commit diff
path: root/compiler/stable_mir/src/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/stable_mir/src/error.rs')
-rw-r--r--compiler/stable_mir/src/error.rs91
1 files changed, 91 insertions, 0 deletions
diff --git a/compiler/stable_mir/src/error.rs b/compiler/stable_mir/src/error.rs
new file mode 100644
index 00000000000..702134b0c4c
--- /dev/null
+++ b/compiler/stable_mir/src/error.rs
@@ -0,0 +1,91 @@
+//! When things go wrong, we need some error handling.
+//! There are a few different types of errors in StableMIR:
+//!
+//! - [CompilerError]: This represents errors that can be raised when invoking the compiler.
+//! - [Error]: Generic error that represents the reason why a request that could not be fulfilled.
+
+use std::fmt::{Debug, Display, Formatter};
+use std::{fmt, io};
+
+use rustc_smir::bridge::SmirError;
+
+macro_rules! error {
+     ($fmt: literal $(,)?) => { Error(format!($fmt)) };
+     ($fmt: literal, $($arg:tt)*) => { Error(format!($fmt, $($arg)*)) };
+}
+
+pub(crate) use 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> {
+    /// 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
+    /// --version.
+    Skipped,
+}
+
+/// A generic error to represent an API request that cannot be fulfilled.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Error(pub(crate) String);
+
+impl SmirError for Error {
+    fn new(msg: String) -> Self {
+        Self(msg)
+    }
+
+    fn from_internal<T: Debug>(err: T) -> Self {
+        Self(format!("{err:?}"))
+    }
+}
+
+impl From<&str> for Error {
+    fn from(value: &str) -> Self {
+        Self(value.into())
+    }
+}
+
+impl Display for Error {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        Display::fmt(&self.0, f)
+    }
+}
+
+impl<T> Display for CompilerError<T>
+where
+    T: Display,
+{
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        match self {
+            CompilerError::Failed => write!(f, "Compilation Failed"),
+            CompilerError::Interrupted(reason) => write!(f, "Compilation Interrupted: {reason}"),
+            CompilerError::Skipped => write!(f, "Compilation Skipped"),
+        }
+    }
+}
+
+impl<T> Debug for CompilerError<T>
+where
+    T: Debug,
+{
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        match self {
+            CompilerError::Failed => write!(f, "Compilation Failed"),
+            CompilerError::Interrupted(reason) => write!(f, "Compilation Interrupted: {reason:?}"),
+            CompilerError::Skipped => write!(f, "Compilation Skipped"),
+        }
+    }
+}
+
+impl std::error::Error for Error {}
+
+impl<T> std::error::Error for CompilerError<T> where T: Display + Debug {}
+
+impl From<io::Error> for Error {
+    fn from(value: io::Error) -> Self {
+        Error(value.to_string())
+    }
+}