1use miden_diagnostics::{Diagnostic, Label, SourceSpan, ToDiagnostic};
2
3#[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#[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}