//! When things go wrong, we need some error handling. //! There are a few different types of errors in rustc_public: //! //! - [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_public_bridge::bridge; 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 { /// 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 bridge::Error for Error { fn new(msg: String) -> Self { Self(msg) } fn from_internal(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 Display for CompilerError 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 Debug for CompilerError 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 std::error::Error for CompilerError where T: Display + Debug {} impl From for Error { fn from(value: io::Error) -> Self { Error(value.to_string()) } }