circomspect_program_structure/intermediate_representation/
errors.rs

1use thiserror::Error;
2
3use crate::report_code::ReportCode;
4use crate::report::Report;
5use crate::file_definition::{FileID, FileLocation};
6
7/// Error enum for IR generation errors.
8#[derive(Debug, Error)]
9pub enum IRError {
10    #[error("The variable `{name}` is read before it is declared/written.")]
11    UndefinedVariableError { name: String, file_id: Option<FileID>, file_location: FileLocation },
12    #[error("The variable name `{name}` contains invalid characters.")]
13    InvalidVariableNameError { name: String, file_id: Option<FileID>, file_location: FileLocation },
14}
15
16pub type IRResult<T> = Result<T, IRError>;
17
18impl IRError {
19    pub fn produce_report(error: Self) -> Report {
20        use IRError::*;
21        match error {
22            UndefinedVariableError { name, file_id, file_location } => {
23                let mut report = Report::error(
24                    format!("The variable '{name}' is used before it is defined."),
25                    ReportCode::UninitializedSymbolInExpression,
26                );
27                if let Some(file_id) = file_id {
28                    report.add_primary(
29                        file_location,
30                        file_id,
31                        format!("The variable `{name}` is first seen here."),
32                    );
33                }
34                report
35            }
36            InvalidVariableNameError { name, file_id, file_location } => {
37                let mut report = Report::error(
38                    format!("Invalid variable name `{name}`."),
39                    ReportCode::ParseFail,
40                );
41                if let Some(file_id) = file_id {
42                    report.add_primary(
43                        file_location,
44                        file_id,
45                        "This variable name contains invalid characters.".to_string(),
46                    );
47                }
48                report
49            }
50        }
51    }
52}
53
54impl From<IRError> for Report {
55    fn from(error: IRError) -> Report {
56        IRError::produce_report(error)
57    }
58}