use crate::ast::{Spanned, SpannedError};
use crate::compile::{IrValue, Meta};
use crate::parse::{ResolveError, ResolveErrorKind};
use crate::query::{QueryError, QueryErrorKind};
use crate::runtime::{AccessError, TypeInfo, TypeOf};
use crate::shared::{ScopeError, ScopeErrorKind};
use thiserror::Error;
error! {
#[derive(Debug)]
pub struct IrError {
kind: IrErrorKind,
}
impl From<ResolveError>;
impl From<QueryError>;
impl From<ScopeError>;
}
impl IrError {
pub(crate) fn expected<S, E>(spanned: S, actual: &IrValue) -> Self
where
S: Spanned,
E: TypeOf,
{
IrError::new(
spanned,
IrErrorKind::Expected {
expected: E::type_info(),
actual: actual.type_info(),
},
)
}
pub(crate) fn access<S>(spanned: S) -> impl FnOnce(AccessError) -> Self
where
S: Spanned,
{
move |error| Self::new(spanned, error)
}
}
impl From<IrError> for SpannedError {
fn from(error: IrError) -> Self {
SpannedError::new(error.span, *error.kind)
}
}
#[derive(Debug, Error)]
#[allow(missing_docs)]
#[non_exhaustive]
pub enum IrErrorKind {
#[error("{message}")]
Custom { message: &'static str },
#[error("scope error: {error}")]
ScopeError {
#[source]
#[from]
error: ScopeErrorKind,
},
#[error("access error: {error}")]
AccessError {
#[source]
#[from]
error: AccessError,
},
#[error("{error}")]
QueryError {
#[source]
#[from]
error: Box<QueryErrorKind>,
},
#[error("{error}")]
ResolveError {
#[source]
#[from]
error: ResolveErrorKind,
},
#[error("expected a constant expression")]
NotConst,
#[error("constant cycle detected")]
ConstCycle,
#[error("{meta} is not supported here")]
UnsupportedMeta {
meta: Meta,
},
#[error("expected a value of type {expected} but got {actual}")]
Expected {
expected: TypeInfo,
actual: TypeInfo,
},
#[error("evaluation budget exceeded")]
BudgetExceeded,
#[error("integer underflow")]
IntegerUnderflow,
#[error("missing index {index}")]
MissingIndex {
index: usize,
},
#[error("missing field `{field}`")]
MissingField {
field: Box<str>,
},
#[error("missing local `{name}`")]
MissingLocal {
name: Box<str>,
},
#[error("no constant or local matching `{name}`")]
MissingConst {
name: Box<str>,
},
#[error("break outside of supported loop")]
BreakOutsideOfLoop,
#[error("function not found")]
FnNotFound,
#[error("argument count mismatch, got {actual} but expected {expected}")]
ArgumentCountMismatch { actual: usize, expected: usize },
#[error("value `{value}` is outside of the supported integer range")]
NotInteger { value: num::BigInt },
}