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    NewAtomicFactError(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    NewAtomicFactRuntimeError => NewAtomicFactError,
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_atomic_fact_as_store_conflict(e: RuntimeError) -> RuntimeError {
97        match e {
98            RuntimeError::NewAtomicFactError(s) => {
99                NewAtomicFactRuntimeError(RuntimeErrorStruct::new(
100                    s.statement.clone(),
101                    s.msg.clone(),
102                    s.line_file.clone(),
103                    Some(NewAtomicFactRuntimeError(s).into()),
104                    vec![],
105                ))
106                .into()
107            }
108            _ => e,
109        }
110    }
111
112    pub fn line_file(&self) -> LineFile {
113        match self {
114            RuntimeError::ArithmeticError(e) => e.line_file.clone(),
115            RuntimeError::NewAtomicFactError(e) => e.line_file.clone(),
116            RuntimeError::StoreFactError(e) => e.line_file.clone(),
117            RuntimeError::ParseError(e) => e.line_file.clone(),
118            RuntimeError::ExecStmtError(e) => e.line_file.clone(),
119            RuntimeError::WellDefinedError(e) => e.line_file.clone(),
120            RuntimeError::VerifyError(e) => e.line_file.clone(),
121            RuntimeError::UnknownError(e) => e.line_file.clone(),
122            RuntimeError::InferError(e) => e.line_file.clone(),
123            RuntimeError::NameAlreadyUsedError(e) => e.line_file.clone(),
124            RuntimeError::DefineParamsError(e) => e.line_file.clone(),
125            RuntimeError::InstantiateError(e) => e.line_file.clone(),
126        }
127    }
128
129    pub fn display_label(&self) -> &'static str {
130        match self {
131            RuntimeError::ArithmeticError(_) => "ArithmeticError",
132            RuntimeError::NewAtomicFactError(_) => "NewAtomicFactError",
133            RuntimeError::StoreFactError(_) => "StoreFactError",
134            RuntimeError::ParseError(_) => "ParseError",
135            RuntimeError::ExecStmtError(_) => "ExecStmtError",
136            RuntimeError::WellDefinedError(_) => "WellDefinedError",
137            RuntimeError::VerifyError(_) => "VerifyError",
138            RuntimeError::UnknownError(_) => "UnknownError",
139            RuntimeError::InferError(_) => "InferError",
140            RuntimeError::NameAlreadyUsedError(_) => "NameAlreadyUsedError",
141            RuntimeError::DefineParamsError(_) => "DefineParamsError",
142            RuntimeError::InstantiateError(_) => "InstantiateError",
143        }
144    }
145}
146
147// Display outputs a short placeholder; JSON: `display_runtime_error_json` in `crate::pipeline`.
148impl fmt::Display for RuntimeError {
149    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150        write!(f, "{}", "error")
151    }
152}
153
154impl fmt::Display for RuntimeErrorStruct {
155    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156        write!(f, "{}", self.msg)
157    }
158}
159
160impl std::error::Error for RuntimeErrorStruct {}
161
162impl RuntimeErrorStruct {
163    pub fn new_with_just_msg(msg: String) -> Self {
164        Self::new(None, msg, default_line_file(), None, vec![])
165    }
166
167    pub fn new_with_msg_and_line_file(msg: String, line_file: LineFile) -> Self {
168        Self::new(None, msg, line_file, None, vec![])
169    }
170
171    pub fn new_with_msg_and_cause(msg: String, cause: RuntimeError) -> Self {
172        Self::new(None, msg, default_line_file(), Some(cause), vec![])
173    }
174}