Skip to main content

rex_typesystem/
error.rs

1use crate::types::{Type, TypeVarId};
2use rex_ast::{Span, Symbol};
3
4#[derive(Debug, thiserror::Error, PartialEq, Eq)]
5pub enum TypeError {
6    #[error("types do not unify: {0} vs {1}")]
7    Unification(String, String),
8    #[error("occurs check failed for {0} in {1}")]
9    Occurs(TypeVarId, String),
10    #[error("unknown class {0}")]
11    UnknownClass(Symbol),
12    #[error("no instance for {0} {1}")]
13    NoInstance(Symbol, String),
14    #[error("unknown type {0}")]
15    UnknownTypeName(Symbol),
16    #[error("cannot redefine reserved builtin type `{0}`")]
17    ReservedTypeName(Symbol),
18    #[error("duplicate value definition `{0}`")]
19    DuplicateValue(Symbol),
20    #[error("duplicate class definition `{0}`")]
21    DuplicateClass(Symbol),
22    #[error("class `{class}` must have at least one type parameter (got {got})")]
23    InvalidClassArity { class: Symbol, got: usize },
24    #[error("duplicate class method `{0}`")]
25    DuplicateClassMethod(Symbol),
26    #[error("unknown method `{method}` in instance of class `{class}`")]
27    UnknownInstanceMethod { class: Symbol, method: Symbol },
28    #[error("missing implementation of `{method}` for instance of class `{class}`")]
29    MissingInstanceMethod { class: Symbol, method: Symbol },
30    #[error(
31        "instance method `{method}` requires constraint {class} {typ}, but it is not in the instance context"
32    )]
33    MissingInstanceConstraint {
34        method: Symbol,
35        class: Symbol,
36        typ: String,
37    },
38    #[error("unbound variable {0}")]
39    UnknownVar(Symbol),
40    #[error("ambiguous overload for {0}")]
41    AmbiguousOverload(Symbol),
42    #[error("ambiguous type variable(s) {vars:?} in constraints: {constraints}")]
43    AmbiguousTypeVars {
44        vars: Vec<TypeVarId>,
45        constraints: String,
46    },
47    #[error(
48        "kind mismatch for class `{class}`: expected {expected} type argument(s) remaining, got {got} for {typ}"
49    )]
50    KindMismatch {
51        class: Symbol,
52        expected: usize,
53        got: usize,
54        typ: String,
55    },
56    #[error("missing type class constraint(s): {constraints}")]
57    MissingConstraints { constraints: String },
58    #[error("unsupported expression {0}")]
59    UnsupportedExpr(&'static str),
60    #[error("unknown field `{field}` on {typ}")]
61    UnknownField { field: Symbol, typ: String },
62    #[error("field `{field}` is not definitely available on {typ}")]
63    FieldNotKnown { field: Symbol, typ: String },
64    #[error("non-exhaustive match for {typ}: missing {missing:?}")]
65    NonExhaustiveMatch { typ: String, missing: Vec<Symbol> },
66    #[error("at {span}: {error}")]
67    Spanned { span: Span, error: Box<TypeError> },
68    #[error("internal error: {0}")]
69    Internal(String),
70}
71
72impl TypeError {
73    pub fn with_span(self, span: &Span) -> TypeError {
74        match self {
75            TypeError::Spanned { .. } => self,
76            other => TypeError::Spanned {
77                span: *span,
78                error: Box::new(other),
79            },
80        }
81    }
82}
83
84#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
85pub struct AdtConflict {
86    pub name: Symbol,
87    pub definitions: Vec<Type>,
88}
89
90#[derive(Clone, Debug, thiserror::Error, PartialEq, Eq)]
91#[error("conflicting ADT definitions: {conflicts:?}")]
92pub struct CollectAdtsError {
93    pub conflicts: Vec<AdtConflict>,
94}