Skip to main content

lex_types/
error.rs

1//! Structured type errors per spec ยง6.7.
2
3use 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}
55
56impl TypeError {
57    pub fn node(&self) -> &str {
58        match self {
59            TypeError::TypeMismatch { at_node, .. }
60            | TypeError::UnknownIdentifier { at_node, .. }
61            | TypeError::ArityMismatch { at_node, .. }
62            | TypeError::NonExhaustiveMatch { at_node, .. }
63            | TypeError::UnknownField { at_node, .. }
64            | TypeError::DuplicateField { at_node, .. }
65            | TypeError::UnknownVariant { at_node, .. }
66            | TypeError::EffectNotDeclared { at_node, .. }
67            | TypeError::InfiniteType { at_node, .. }
68            | TypeError::AmbiguousType { at_node, .. }
69            | TypeError::RecursiveTypeWithoutConstructor { at_node, .. } => at_node,
70        }
71    }
72}
73
74impl std::fmt::Display for TypeError {
75    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
76        match self {
77            TypeError::TypeMismatch { at_node, expected, got, context } => {
78                write!(f, "type mismatch at {at_node}: expected {expected}, got {got}")?;
79                if !context.is_empty() { write!(f, " ({})", context.join(" / "))?; }
80                Ok(())
81            }
82            TypeError::UnknownIdentifier { at_node, name } => write!(f, "unknown identifier `{name}` at {at_node}"),
83            TypeError::ArityMismatch { at_node, expected, got } => write!(f, "arity mismatch at {at_node}: expected {expected}, got {got}"),
84            TypeError::NonExhaustiveMatch { at_node, missing } => write!(f, "non-exhaustive match at {at_node}: missing {missing:?}"),
85            TypeError::UnknownField { at_node, record_type, field } => write!(f, "unknown field `{field}` on {record_type} at {at_node}"),
86            TypeError::DuplicateField { at_node, field } => write!(f, "duplicate field `{field}` at {at_node}"),
87            TypeError::UnknownVariant { at_node, constructor } => write!(f, "unknown constructor `{constructor}` at {at_node}"),
88            TypeError::EffectNotDeclared { at_node, effect } => write!(f, "effect `{effect}` not declared at {at_node}"),
89            TypeError::InfiniteType { at_node } => write!(f, "infinite type (occurs check) at {at_node}"),
90            TypeError::AmbiguousType { at_node } => write!(f, "ambiguous type at {at_node}"),
91            TypeError::RecursiveTypeWithoutConstructor { at_node, name } => write!(f, "recursive type {name} has no constructor at {at_node}"),
92        }
93    }
94}
95
96impl std::error::Error for TypeError {}