Skip to main content

litex/error/
error.rs

1use crate::prelude::*;
2use std::fmt;
3
4#[derive(Debug)]
5pub enum RuntimeError {
6    ArithmeticError(RuntimeErrorStruct),
7    NewFactError(RuntimeErrorStruct),
8    StoreFactError(RuntimeErrorStruct),
9    ParseError(RuntimeErrorStruct),
10    ExecStmtError(RuntimeErrorStruct),
11    WellDefinedError(RuntimeErrorStruct),
12    VerifyError(RuntimeErrorStruct),
13    UnknownError(RuntimeErrorStruct),
14    InferError(RuntimeErrorStruct),
15    NameAlreadyUsedError(RuntimeErrorStruct),
16    DefineParamsError(RuntimeErrorStruct),
17    InstantiateError(RuntimeErrorStruct),
18}
19
20#[derive(Debug)]
21pub struct RuntimeErrorStruct {
22    pub statement: Option<Stmt>,
23    pub msg: String,
24    pub line_file: LineFile,
25    pub previous_error: Option<Box<RuntimeError>>,
26    pub inside_results: Vec<StmtResult>,
27}
28
29macro_rules! runtime_error_wrapper {
30    ($($wrapper:ident => $variant:ident),* $(,)?) => {
31        $(
32            #[derive(Debug)]
33            pub struct $wrapper(pub RuntimeErrorStruct);
34
35            impl From<$wrapper> for RuntimeError {
36                fn from(w: $wrapper) -> Self {
37                    RuntimeError::$variant(w.0)
38                }
39            }
40        )*
41    };
42}
43
44runtime_error_wrapper! {
45    ArithmeticRuntimeError => ArithmeticError,
46    NewFactRuntimeError => NewFactError,
47    StoreFactRuntimeError => StoreFactError,
48    ParseRuntimeError => ParseError,
49    WellDefinedRuntimeError => WellDefinedError,
50    VerifyRuntimeError => VerifyError,
51    UnknownRuntimeError => UnknownError,
52    InferRuntimeError => InferError,
53    NameAlreadyUsedRuntimeError => NameAlreadyUsedError,
54    DefineParamsRuntimeError => DefineParamsError,
55    InstantiateRuntimeError => InstantiateError,
56}
57
58impl RuntimeErrorStruct {
59    pub fn new(
60        statement: Option<Stmt>,
61        msg: String,
62        line_file: LineFile,
63        previous_error: Option<RuntimeError>,
64        inside_results: Vec<StmtResult>,
65    ) -> Self {
66        RuntimeErrorStruct {
67            statement,
68            msg,
69            line_file,
70            previous_error: previous_error.map(Box::new),
71            inside_results,
72        }
73    }
74}
75
76pub fn short_exec_error(
77    stmt: Stmt,
78    message: impl Into<String>,
79    cause: Option<RuntimeError>,
80    inside_results: Vec<StmtResult>,
81) -> RuntimeError {
82    let message = message.into();
83    let line_file = stmt.line_file();
84    RuntimeError::ExecStmtError(RuntimeErrorStruct::new(
85        Some(stmt.clone()),
86        message,
87        line_file.clone(),
88        cause,
89        inside_results,
90    ))
91}
92
93impl std::error::Error for RuntimeError {}
94
95impl RuntimeError {
96    pub fn wrap_new_fact_as_store_conflict(e: RuntimeError) -> RuntimeError {
97        match e {
98            RuntimeError::NewFactError(s) => NewFactRuntimeError(RuntimeErrorStruct::new(
99                s.statement.clone(),
100                s.msg.clone(),
101                s.line_file.clone(),
102                Some(NewFactRuntimeError(s).into()),
103                vec![],
104            ))
105            .into(),
106            _ => e,
107        }
108    }
109
110    pub fn line_file(&self) -> LineFile {
111        match self {
112            RuntimeError::ArithmeticError(e) => e.line_file.clone(),
113            RuntimeError::NewFactError(e) => e.line_file.clone(),
114            RuntimeError::StoreFactError(e) => e.line_file.clone(),
115            RuntimeError::ParseError(e) => e.line_file.clone(),
116            RuntimeError::ExecStmtError(e) => e.line_file.clone(),
117            RuntimeError::WellDefinedError(e) => e.line_file.clone(),
118            RuntimeError::VerifyError(e) => e.line_file.clone(),
119            RuntimeError::UnknownError(e) => e.line_file.clone(),
120            RuntimeError::InferError(e) => e.line_file.clone(),
121            RuntimeError::NameAlreadyUsedError(e) => e.line_file.clone(),
122            RuntimeError::DefineParamsError(e) => e.line_file.clone(),
123            RuntimeError::InstantiateError(e) => e.line_file.clone(),
124        }
125    }
126
127    pub fn display_label(&self) -> &'static str {
128        match self {
129            RuntimeError::ArithmeticError(_) => "ArithmeticError",
130            RuntimeError::NewFactError(_) => "NewFactError",
131            RuntimeError::StoreFactError(_) => "StoreFactError",
132            RuntimeError::ParseError(_) => "ParseError",
133            RuntimeError::ExecStmtError(_) => "ExecStmtError",
134            RuntimeError::WellDefinedError(_) => "WellDefinedError",
135            RuntimeError::VerifyError(_) => "VerifyError",
136            RuntimeError::UnknownError(_) => "UnknownError",
137            RuntimeError::InferError(_) => "InferError",
138            RuntimeError::NameAlreadyUsedError(_) => "NameAlreadyUsedError",
139            RuntimeError::DefineParamsError(_) => "DefineParamsError",
140            RuntimeError::InstantiateError(_) => "InstantiateError",
141        }
142    }
143}
144
145// Display outputs a short placeholder; JSON: `display_runtime_error_json` in `crate::pipeline`.
146impl fmt::Display for RuntimeError {
147    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148        write!(f, "{}", "error")
149    }
150}
151
152impl fmt::Display for RuntimeErrorStruct {
153    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154        write!(f, "{}", self.msg)
155    }
156}
157
158impl std::error::Error for RuntimeErrorStruct {}
159
160impl RuntimeErrorStruct {
161    pub fn new_with_just_msg(msg: String) -> Self {
162        Self::new(None, msg, default_line_file(), None, vec![])
163    }
164
165    pub fn new_with_msg_and_line_file(msg: String, line_file: LineFile) -> Self {
166        Self::new(None, msg, line_file, None, vec![])
167    }
168
169    pub fn new_with_msg_and_cause(msg: String, cause: RuntimeError) -> Self {
170        Self::new(None, msg, default_line_file(), Some(cause), vec![])
171    }
172}