1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6#[serde(tag = "kind", rename_all = "snake_case")]
7pub enum TypeError {
8 TypeMismatch {
9 at_node: String,
10 expected: String,
11 got: String,
12 context: Vec<String>,
13 },
14 UnknownIdentifier {
15 at_node: String,
16 name: String,
17 },
18 ArityMismatch {
19 at_node: String,
20 expected: usize,
21 got: usize,
22 },
23 NonExhaustiveMatch {
24 at_node: String,
25 missing: Vec<String>,
26 },
27 UnknownField {
28 at_node: String,
29 record_type: String,
30 field: String,
31 },
32 DuplicateField {
33 at_node: String,
34 field: String,
35 },
36 UnknownVariant {
37 at_node: String,
38 constructor: String,
39 },
40 EffectNotDeclared {
41 at_node: String,
42 effect: String,
43 },
44 InfiniteType {
45 at_node: String,
46 },
47 AmbiguousType {
48 at_node: String,
49 },
50 RecursiveTypeWithoutConstructor {
51 at_node: String,
52 name: String,
53 },
54 RefinementViolation {
60 at_node: String,
61 fn_name: String,
62 param_index: usize,
63 binding: String,
64 reason: String,
65 },
66}
67
68impl TypeError {
69 pub fn node(&self) -> &str {
70 match self {
71 TypeError::TypeMismatch { at_node, .. }
72 | TypeError::UnknownIdentifier { at_node, .. }
73 | TypeError::ArityMismatch { at_node, .. }
74 | TypeError::NonExhaustiveMatch { at_node, .. }
75 | TypeError::UnknownField { at_node, .. }
76 | TypeError::DuplicateField { at_node, .. }
77 | TypeError::UnknownVariant { at_node, .. }
78 | TypeError::EffectNotDeclared { at_node, .. }
79 | TypeError::InfiniteType { at_node, .. }
80 | TypeError::AmbiguousType { at_node, .. }
81 | TypeError::RecursiveTypeWithoutConstructor { at_node, .. }
82 | TypeError::RefinementViolation { at_node, .. } => at_node,
83 }
84 }
85}
86
87impl std::fmt::Display for TypeError {
88 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
89 match self {
90 TypeError::TypeMismatch { at_node, expected, got, context } => {
91 write!(f, "type mismatch at {at_node}: expected {expected}, got {got}")?;
92 if !context.is_empty() { write!(f, " ({})", context.join(" / "))?; }
93 Ok(())
94 }
95 TypeError::UnknownIdentifier { at_node, name } => write!(f, "unknown identifier `{name}` at {at_node}"),
96 TypeError::ArityMismatch { at_node, expected, got } => write!(f, "arity mismatch at {at_node}: expected {expected}, got {got}"),
97 TypeError::NonExhaustiveMatch { at_node, missing } => write!(f, "non-exhaustive match at {at_node}: missing {missing:?}"),
98 TypeError::UnknownField { at_node, record_type, field } => write!(f, "unknown field `{field}` on {record_type} at {at_node}"),
99 TypeError::DuplicateField { at_node, field } => write!(f, "duplicate field `{field}` at {at_node}"),
100 TypeError::UnknownVariant { at_node, constructor } => write!(f, "unknown constructor `{constructor}` at {at_node}"),
101 TypeError::EffectNotDeclared { at_node, effect } => write!(f, "effect `{effect}` not declared at {at_node}"),
102 TypeError::InfiniteType { at_node } => write!(f, "infinite type (occurs check) at {at_node}"),
103 TypeError::AmbiguousType { at_node } => write!(f, "ambiguous type at {at_node}"),
104 TypeError::RecursiveTypeWithoutConstructor { at_node, name } => write!(f, "recursive type {name} has no constructor at {at_node}"),
105 TypeError::RefinementViolation { at_node, fn_name, param_index, binding, reason } =>
106 write!(f, "refinement violated at {at_node}: argument {} of `{fn_name}` (binding `{binding}`): {reason}",
107 param_index + 1),
108 }
109 }
110}
111
112impl std::error::Error for TypeError {}