1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//! Error types for expression evaluation and type-checking.
/// Errors that can occur during expression evaluation or type-checking.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum ExprError {
/// Evaluation exceeded the configured step limit.
#[error("step limit exceeded after {0} steps")]
StepLimitExceeded(u64),
/// Evaluation exceeded the configured recursion depth.
#[error("recursion depth exceeded: {0}")]
DepthExceeded(u32),
/// A variable was referenced but not bound in the environment.
#[error("unbound variable: {0}")]
UnboundVariable(String),
/// An operation received a value of the wrong type.
#[error("type error: expected {expected}, got {got}")]
TypeError {
/// The expected type name.
expected: String,
/// The actual type name.
got: String,
},
/// A builtin was applied to the wrong number of arguments.
#[error("arity mismatch for {op}: expected {expected}, got {got}")]
ArityMismatch {
/// The builtin operation name.
op: String,
/// Expected number of arguments.
expected: usize,
/// Actual number of arguments.
got: usize,
},
/// List index was out of bounds.
#[error("index out of bounds: {index} for list of length {len}")]
IndexOutOfBounds {
/// The index that was attempted.
index: i64,
/// The actual list length.
len: usize,
},
/// A field was not found in a record.
#[error("field not found: {0}")]
FieldNotFound(String),
/// No pattern arm matched the scrutinee.
#[error("non-exhaustive match")]
NonExhaustiveMatch,
/// Division by zero.
#[error("division by zero")]
DivisionByZero,
/// A list operation exceeded the configured maximum list length.
#[error("list length limit exceeded: {0}")]
ListLengthExceeded(usize),
/// Failed to parse a string as a number.
#[error("parse error: cannot convert {value:?} to {target_type}")]
ParseError {
/// The string value that failed to parse.
value: String,
/// The target type name.
target_type: String,
},
/// Attempted to call a non-function value.
#[error("not a function")]
NotAFunction,
/// Integer arithmetic overflowed.
#[error("integer overflow")]
Overflow,
/// Float value is not representable as an integer (NaN, infinity, or out of range).
#[error("float not representable as integer: {0}")]
FloatNotRepresentable(String),
/// A builtin operation reached a category handler that does not implement it.
///
/// The top-level dispatch in [`apply_builtin`](crate::builtin::apply_builtin)
/// routes each [`BuiltinOp`](crate::expr::BuiltinOp) to the category handler
/// that implements it. This error signals a misrouted operation: a
/// per-category handler received an op outside its category.
#[error("internal dispatch error: operation {op} routed to the wrong category handler")]
InternalDispatch {
/// The misrouted builtin operation.
op: String,
},
}