air_parser/ast/
errors.rs

1use miden_diagnostics::{Diagnostic, Label, SourceSpan, ToDiagnostic};
2
3/// Represents an invalid expression for use in an `Expr` context
4#[derive(Clone, Debug, thiserror::Error)]
5pub enum InvalidExprError {
6    #[error("this value is too large for an exponent")]
7    InvalidExponent(SourceSpan),
8    #[error("expected exponent to be a constant")]
9    NonConstantExponent(SourceSpan),
10    #[error("expected constant range expression")]
11    NonConstantRangeExpr(SourceSpan),
12    #[error("accessing column boundaries is not allowed here")]
13    BoundedSymbolAccess(SourceSpan),
14    #[error("expected scalar expression")]
15    InvalidScalarExpr(SourceSpan),
16    #[error(
17        "invalid let in expression position: body produces no value, or the type of that value is unknown"
18    )]
19    InvalidLetExpr(SourceSpan),
20    #[error("syntax does not represent a valid expression")]
21    NotAnExpr(SourceSpan),
22}
23impl Eq for InvalidExprError {}
24impl PartialEq for InvalidExprError {
25    fn eq(&self, other: &Self) -> bool {
26        core::mem::discriminant(self) == core::mem::discriminant(other)
27    }
28}
29impl ToDiagnostic for InvalidExprError {
30    fn to_diagnostic(self) -> Diagnostic {
31        let message = format!("{}", &self);
32        match self {
33            Self::NonConstantExponent(span) => Diagnostic::error()
34                .with_message("invalid expression")
35                .with_labels(vec![
36                    Label::primary(span.source_id(), span).with_message(message),
37                ])
38                .with_notes(vec![
39                    "Only constant powers are supported with the exponentiation operator currently"
40                        .to_string(),
41                ]),
42            Self::NonConstantRangeExpr(span) => Diagnostic::error()
43                .with_message("invalid expression")
44                .with_labels(vec![
45                    Label::primary(span.source_id(), span).with_message(message),
46                ])
47                .with_notes(vec![
48                    "Range expression must be a constant to do this operation".to_string(),
49                ]),
50            Self::InvalidExponent(span)
51            | Self::BoundedSymbolAccess(span)
52            | Self::InvalidScalarExpr(span)
53            | Self::InvalidLetExpr(span)
54            | Self::NotAnExpr(span) => Diagnostic::error()
55                .with_message("invalid expression")
56                .with_labels(vec![
57                    Label::primary(span.source_id(), span).with_message(message),
58                ]),
59        }
60    }
61}
62
63/// Represents an invalid type for use in a `BindingType` context
64#[derive(Clone, Debug, thiserror::Error)]
65pub enum InvalidTypeError {
66    #[error("expected iterable to be a vector")]
67    NonVectorIterable(SourceSpan),
68}
69impl Eq for InvalidTypeError {}
70impl PartialEq for InvalidTypeError {
71    fn eq(&self, other: &Self) -> bool {
72        core::mem::discriminant(self) == core::mem::discriminant(other)
73    }
74}
75impl ToDiagnostic for InvalidTypeError {
76    fn to_diagnostic(self) -> Diagnostic {
77        let message = format!("{}", &self);
78        match self {
79            Self::NonVectorIterable(span) => Diagnostic::error()
80                .with_message("invalid type")
81                .with_labels(vec![
82                    Label::primary(span.source_id(), span).with_message(message),
83                ])
84                .with_notes(vec!["Only vectors can be used as iterables".to_string()]),
85        }
86    }
87}