pliron_mlir_builtin/
error.rs1use std::error::Error as StdError;
2use thiserror::Error;
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6#[non_exhaustive]
7pub enum RecoveryCategory {
8 InvalidInput,
10 Unsupported,
12}
13
14#[derive(Debug, Error)]
16#[non_exhaustive]
17pub enum Diagnostic {
18 #[error("affine dimension {position} is outside {dimensions} dimensions")]
20 DimensionOutOfBounds {
21 position: usize,
23 dimensions: usize,
25 },
26 #[error("affine symbol {position} is outside {symbols} symbols")]
28 SymbolOutOfBounds {
29 position: usize,
31 symbols: usize,
33 },
34 #[error("affine product is not affine")]
36 NonAffineProduct,
37 #[error("affine divisor for {op:?} is not symbolic")]
39 NonSymbolicDivisor {
40 op: crate::attributes::AffineBinaryOp,
42 },
43 #[error("affine expression exceeds the nesting limit")]
45 NestingLimit,
46 #[error(
48 "affine argument count mismatch: expected {expected}, got {actual} (symbols: {symbols})"
49 )]
50 ArgumentCount {
51 symbols: bool,
53 expected: usize,
55 actual: usize,
57 },
58 #[error("division by zero in affine expression")]
60 DivisionByZero,
61 #[error("arithmetic overflow in affine expression")]
63 ArithmeticOverflow,
64 #[error("malformed affine expression")]
66 MalformedExpression,
67 #[error("invalid {ty}: {reason}")]
69 InvalidType {
70 ty: &'static str,
72 reason: &'static str,
74 },
75 #[error("invalid {attribute}: {reason}")]
77 InvalidAttribute {
78 attribute: &'static str,
80 reason: &'static str,
82 },
83 #[error("integer value cannot be represented as {target}")]
85 IntegerOutOfRange {
86 target: &'static str,
88 },
89 #[error("cannot serialize {entity} as MLIR: {reason}")]
91 UnsupportedSerialization {
92 entity: String,
94 reason: &'static str,
96 },
97}
98
99impl Diagnostic {
100 pub fn recovery_category(&self) -> RecoveryCategory {
102 match self {
103 Self::UnsupportedSerialization { .. } => RecoveryCategory::Unsupported,
104 _ => RecoveryCategory::InvalidInput,
105 }
106 }
107
108 pub fn into_error(self) -> pliron::result::Error {
110 self.into()
111 }
112
113 pub fn from_error(error: &pliron::result::Error) -> Option<&Self> {
115 let mut source: &(dyn StdError + 'static) = error;
116 loop {
117 if let Some(diagnostic) = source.downcast_ref::<Self>() {
118 return Some(diagnostic);
119 }
120 source = if let Some(envelope) = source.downcast_ref::<pliron::result::Error>() {
121 envelope.err.as_ref()
122 } else {
123 source.source()?
124 };
125 }
126 }
127}
128impl From<crate::integer::IntegerParseError> for pliron::result::Error {
129 fn from(error: crate::integer::IntegerParseError) -> Self {
130 pliron::arg_error_noloc!(error)
131 }
132}
133
134impl From<Diagnostic> for pliron::result::Error {
135 fn from(error: Diagnostic) -> Self {
136 match error.recovery_category() {
137 RecoveryCategory::InvalidInput => pliron::arg_error_noloc!(error),
138 RecoveryCategory::Unsupported => pliron::input_error_noloc!(error),
139 }
140 }
141}