Skip to content

Commit

Permalink
Improve TypeMismatch and TypesMismatch errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlamonster committed Nov 8, 2023
1 parent f45a6c7 commit f44c933
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 210 deletions.
15 changes: 12 additions & 3 deletions compiler/src/passes/validate/type_check/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,24 @@ pub enum TypeError {
#[label = "This variable `{sym}` was not declared yet"]
span: (usize, usize),
},
#[error("Types were mismatched. Expected '{expect}', but found '{got}'.")]
TypeMismatchExpect {
#[error("Type was mismatched.")]
MismatchedType {
expect: Type<String>,
got: Type<String>,
#[label = "Expected this to be of type `{expect}`, but got `{got}`"]
span: (usize, usize),
},
#[error("Types were mismatched. Expected function, but found '{got}'.")]
TypeMismatchExpectFn { got: Type<String> },
#[error("Types were mismatched. Expected '{t1}' and '{t2}' to be equal.")]
TypeMismatchEqual { t1: Type<String>, t2: Type<String> },
MismatchedTypes {
t1: Type<String>,
t2: Type<String>,
#[label = "This has type `{t1}`"]
span_t1: (usize, usize),
#[label = "but this has type `{t2}`"]
span_t2: (usize, usize),
},
#[error("There are multiple functions named `{sym}`.")]
DuplicateFunction { sym: String },
#[error("Function `{sym}` has duplicate argument names.")]
Expand Down
37 changes: 25 additions & 12 deletions compiler/src/passes/validate/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ mod validate_type;
mod validate_typedef;

use crate::passes::parse::types::Type;
use crate::passes::parse::{Def, PrgParsed, TypeDef};
use crate::passes::parse::{Def, PrgParsed, Spanned, TypeDef};
use crate::passes::validate::type_check::error::TypeError;
use crate::passes::validate::type_check::error::TypeError::*;
use crate::passes::validate::type_check::uncover_globals::uncover_globals;
use crate::passes::validate::type_check::validate_expr::validate_expr;
use crate::passes::validate::type_check::validate_typedef::validate_typedef;
use crate::passes::validate::{PrgTypeChecked, TExpr};
use crate::s;
use crate::utils::expect::expect;
use crate::utils::push_map::PushMap;
use std::collections::HashMap;
Expand Down Expand Up @@ -85,7 +86,7 @@ impl<'p> PrgParsed<'p> {
Def::Fn {
sym,
params,
bdy,
bdy: bdy.inner,
typ,
},
))
Expand All @@ -109,31 +110,43 @@ impl<'p> PrgParsed<'p> {
}

pub fn expect_type_eq<'p>(
e1: &TExpr<'p, &'p str>,
e2: &TExpr<'p, &'p str>,
e1: &Spanned<TExpr<'p, &'p str>>,
e2: &Spanned<TExpr<'p, &'p str>>,
) -> Result<Type<&'p str>, TypeError> {
let t1 = e1.typ();
let t2 = e2.typ();
let t1 = e1.inner.typ();
let t2 = e2.inner.typ();

expect(
t1 == t2,
TypeMismatchEqual {
MismatchedTypes {
t1: t1.clone().fmap(str::to_string),
t2: t2.clone().fmap(str::to_string),
span_t1: s!(e1.span),
span_t2: s!(e2.span),
},
)?;

Ok(t1.clone())
}

pub fn expect_type<'p>(
expr: &TExpr<'p, &'p str>,
expr: &Spanned<TExpr<'p, &'p str>>,
expected: &Type<&'p str>,
) -> Result<(), TypeError> {
let t = expr.typ();
let typ = expr.inner.typ();
expect(
t == expected,
TypeMismatchExpect {
got: t.clone().fmap(str::to_string),
typ == expected,
MismatchedType {
got: typ.clone().fmap(str::to_string),
expect: expected.clone().fmap(str::to_string),
span: s!(expr.span),
},
)
}

#[macro_export]
macro_rules! s {
($span:expr) => {
($span.0, $span.1 - $span.0)
};
}
Loading

0 comments on commit f44c933

Please sign in to comment.