Skip to main content

specl_types/
error.rs

1//! Type checking error types.
2
3use crate::types::Type;
4use specl_syntax::Span;
5use thiserror::Error;
6
7/// A type checking error.
8#[derive(Debug, Error)]
9pub enum TypeError {
10    #[error("type mismatch: expected {expected}, found {found}")]
11    TypeMismatch {
12        expected: Type,
13        found: Type,
14        span: Span,
15    },
16
17    #[error("undefined variable: {name}")]
18    UndefinedVariable { name: String, span: Span },
19
20    #[error("undefined type: {name}")]
21    UndefinedType { name: String, span: Span },
22
23    #[error("undefined action: {name}")]
24    UndefinedAction { name: String, span: Span },
25
26    #[error("duplicate definition: {name}")]
27    DuplicateDefinition { name: String, span: Span },
28
29    #[error("invalid field access: type {ty} has no field {field}")]
30    InvalidField { ty: Type, field: String, span: Span },
31
32    #[error("cannot index into type {ty}")]
33    NotIndexable { ty: Type, span: Span },
34
35    #[error("cannot iterate over type {ty}")]
36    NotIterable { ty: Type, span: Span },
37
38    #[error("cannot call non-function type {ty}")]
39    NotCallable { ty: Type, span: Span },
40
41    #[error("wrong number of arguments: expected {expected}, found {found}")]
42    ArityMismatch {
43        expected: usize,
44        found: usize,
45        span: Span,
46    },
47
48    #[error("prime operator can only be applied to state variables")]
49    InvalidPrime { span: Span },
50
51    #[error("cannot unify types {a} and {b}")]
52    UnificationFailure { a: Type, b: Type, span: Span },
53
54    #[error("occurs check failed: type variable would create infinite type")]
55    OccursCheck { span: Span },
56
57    #[error("expression must be boolean, found {found}")]
58    ExpectedBool { found: Type, span: Span },
59
60    #[error("operands must be numeric, found {found}")]
61    ExpectedNumeric { found: Type, span: Span },
62
63    #[error("operands must be of the same type")]
64    TypesNotEqual { left: Type, right: Type, span: Span },
65}
66
67impl TypeError {
68    /// Get the source span of this error.
69    pub fn span(&self) -> Span {
70        match self {
71            TypeError::TypeMismatch { span, .. }
72            | TypeError::UndefinedVariable { span, .. }
73            | TypeError::UndefinedType { span, .. }
74            | TypeError::UndefinedAction { span, .. }
75            | TypeError::DuplicateDefinition { span, .. }
76            | TypeError::InvalidField { span, .. }
77            | TypeError::NotIndexable { span, .. }
78            | TypeError::NotIterable { span, .. }
79            | TypeError::NotCallable { span, .. }
80            | TypeError::ArityMismatch { span, .. }
81            | TypeError::InvalidPrime { span }
82            | TypeError::UnificationFailure { span, .. }
83            | TypeError::OccursCheck { span }
84            | TypeError::ExpectedBool { span, .. }
85            | TypeError::ExpectedNumeric { span, .. }
86            | TypeError::TypesNotEqual { span, .. } => *span,
87        }
88    }
89}
90
91/// Result type for type checking operations.
92pub type TypeResult<T> = Result<T, TypeError>;