use std::sync::Arc;
use haloumi_core::slot::output::OutputId as FieldId;
use llzk::prelude::Type;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum Error {
#[error("Struct is missing output #{0}")]
MissingOutput(FieldId),
#[error("Constrain function is missing!")]
MissingConstrainFunc,
#[error("Constrain function region is missing a block")]
MissingBlock,
#[error("Constrain function is missing a terminator")]
MissingTerminator,
#[error("LLZK error: {0}")]
Llzk(#[from] llzk::error::Error),
#[error("MLIR error: {0}")]
Mlir(#[from] melior::Error),
#[error("Lowering error: {0}")]
Lowering(#[from] haloumi_lowering::error::Error),
#[error("IR gen error: {0}")]
IRGen(#[from] haloumi_ir_gen::error::Error),
#[error("Output module failed verification{note}: {err}")]
VerificationFailed {
err: llzk::error::Error,
note: &'static str,
},
}
impl From<Error> for haloumi_lowering::error::Error {
fn from(value: Error) -> Self {
Self::Backend(Arc::new(value))
}
}
#[derive(Debug, Error)]
#[error("Was expecting type {expected} but got type {actual}")]
pub(crate) struct UnexpectedTypeError {
expected: String,
actual: String,
}
impl UnexpectedTypeError {
pub fn new(expected: Type<'_>, actual: Type<'_>) -> Self {
Self {
expected: format!("{expected}"),
actual: format!("{actual}"),
}
}
pub fn with_context(self, msg: impl ToString) -> ContextualizedError<Self> {
ContextualizedError {
msg: msg.to_string(),
error: self,
}
}
}
impl From<UnexpectedTypeError> for haloumi_lowering::error::Error {
fn from(value: UnexpectedTypeError) -> Self {
Self::Backend(Arc::new(value))
}
}
#[derive(Debug, Error)]
#[error("{msg}: {error}")]
pub(crate) struct ContextualizedError<E: std::error::Error> {
msg: String,
#[source]
error: E,
}
impl<E: std::error::Error + 'static> From<ContextualizedError<E>>
for haloumi_lowering::error::Error
{
fn from(value: ContextualizedError<E>) -> Self {
Self::Backend(Arc::new(value))
}
}