From 3e1bf7f9946efe70d452c71494ac77ed39110804 Mon Sep 17 00:00:00 2001 From: Joel Kronqvist Date: Wed, 6 Aug 2025 17:05:55 +0300 Subject: Added print, raised level on which UnboundGeneric error is returned --- src/type/check.rs | 24 +++++++++++------------- src/type/display.rs | 8 ++++---- src/type/mod.rs | 2 +- 3 files changed, 16 insertions(+), 18 deletions(-) (limited to 'src/type') diff --git a/src/type/check.rs b/src/type/check.rs index e536ce7..91ca422 100644 --- a/src/type/check.rs +++ b/src/type/check.rs @@ -163,7 +163,11 @@ impl SExp { /// }; /// ``` pub fn type_check(&self) -> Result { - self.infer_type(HashMap::new()) + let ty = self.infer_type(HashMap::new())?; + match ty.is_concrete() { + Ok(()) => Ok(ty), + Err(s) => Err(UnboundGeneric(ty, s)), + } } @@ -194,6 +198,7 @@ impl SExp { List(vec![VecType, vecof(vt("T"))]) )), Atom(Let) => Ok(LetType), + Atom(Print) => Ok(arr(vt("_"), arr(vt("T"), vt("T")))), SCons(op, l) => { @@ -298,10 +303,11 @@ impl Type { restype = restype.subst(&name, &ty); } - match restype.is_concrete() { - Ok(()) => Ok(arr(argtype.clone(), restype)), - Err(unbound) => Err(UnboundGeneric(unbound)), - } + //match restype.is_concrete() { + // Ok(()) => Ok(arr(argtype.clone(), restype)), + // Err(unbound) => Err(UnboundGeneric(unbound)), + //} + Ok(arr(argtype.clone(), restype)) }, _ => Err(OtherError) } @@ -378,14 +384,6 @@ impl Type { mod tests { use super::{*, TypeError}; - #[test] - fn test_failing_infer_generics() { - assert_eq!( - arr(Integer, VarType("X".to_string())).infer_generics(&Integer), - Err(TypeError::UnboundGeneric(String::from("X"))) - ); - } - #[test] fn test_infer_generics() { diff --git a/src/type/display.rs b/src/type/display.rs index 4a9b54a..f859dc3 100644 --- a/src/type/display.rs +++ b/src/type/display.rs @@ -67,8 +67,8 @@ impl fmt::Display for TypeError { /// "invalid argument list: '(1 2 3)'\nexpected: '(Int Int)'\nfound: '(Int Int Int)'".to_string() /// ); /// assert_eq!( - /// UnboundGeneric(String::from("?")).to_string(), - /// "unbound generic type: '?'".to_string() + /// UnboundGeneric(arr(Integer, vt("?")), String::from("?")).to_string(), + /// "unbound generic type in '(Int -> ?)': '?'".to_string() /// ); /// assert_eq!( /// ArgumentsDontMatchGeneric { @@ -80,8 +80,8 @@ impl fmt::Display for TypeError { /// ``` fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - UndefinedVariable(name) => write!(f, "undefined variable: '{}'", name), - UnboundGeneric(name) => write!(f, "unbound generic type: '{}'", name), + UndefinedVariable(name) => write!(f, "undefined variable: '{}'", name), + UnboundGeneric(ty, name) => write!(f, "unbound generic type in '{}': '{}'", ty, name), InvalidOperator { operator, expected, found } => { write!( f, diff --git a/src/type/mod.rs b/src/type/mod.rs index afb5a0b..6f5c6dc 100644 --- a/src/type/mod.rs +++ b/src/type/mod.rs @@ -40,7 +40,7 @@ pub enum TypeError { UndefinedVariable(String), - UnboundGeneric(String), + UnboundGeneric(Type, String), InvalidOperator { operator: SExp, -- cgit v1.2.3