diff options
author | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-13 01:20:19 +0300 |
---|---|---|
committer | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-13 01:20:19 +0300 |
commit | 189d06730ae23770fbb970bf37eb0993edb8cd2d (patch) | |
tree | 73048265c57176ba27d2b823e09ebe4c1c7328c1 | |
parent | ec13c45c8ae0f63fa715178308547cfadd8f8c39 (diff) | |
download | myslip-189d06730ae23770fbb970bf37eb0993edb8cd2d.tar.gz myslip-189d06730ae23770fbb970bf37eb0993edb8cd2d.zip |
feat: generic match arms, mostly for functions I guess?
-rw-r--r-- | src/type/check.rs | 14 | ||||
-rw-r--r-- | src/type/conversion.rs | 2 | ||||
-rw-r--r-- | src/type/display.rs | 1 | ||||
-rw-r--r-- | src/type/mod.rs | 2 |
4 files changed, 13 insertions, 6 deletions
diff --git a/src/type/check.rs b/src/type/check.rs index 7a2d231..f842b4c 100644 --- a/src/type/check.rs +++ b/src/type/check.rs @@ -216,7 +216,14 @@ impl SExp { /// }; /// ``` pub fn type_check(&self) -> Result<Type, TypeError> { - self.infer_type(HashMap::new()) + let res = self.infer_type(HashMap::new()); + match res { + Ok(res) => match res.is_concrete() { + Ok(()) => Ok(res), + Err(name) => Err(UnboundGeneric(name)), + }, + e => e, + } } @@ -305,10 +312,7 @@ impl SExp { } match &ty { None => ty = Some(arm.infer_type(newctx)?), - Some(t) => if arm.infer_type(newctx.clone())? != *t { - println!("different types: {}, {}", t, arm.infer_list_type(newctx)?); - return Err(OtherError); - }, + Some(t) => ty = Some(t.least_general_supertype(&arm.infer_type(newctx.clone())?)), } } if !has_wildcard { diff --git a/src/type/conversion.rs b/src/type/conversion.rs index 0a96790..5d29ba0 100644 --- a/src/type/conversion.rs +++ b/src/type/conversion.rs @@ -30,7 +30,7 @@ impl Type { self.least_general_supertype(known_as) == *known_as } - fn least_general_supertype(&self, other: &Type) -> Type { + pub fn least_general_supertype(&self, other: &Type) -> Type { match (self, other) { diff --git a/src/type/display.rs b/src/type/display.rs index 290e24e..56b22b6 100644 --- a/src/type/display.rs +++ b/src/type/display.rs @@ -122,6 +122,7 @@ impl fmt::Display for TypeError { letexp ) }, + DifferentTypeCaseArms(ty1, ty2) => write!(f, "arms of match have different types, '{ty1}' and '{ty2}'"), FunAsAtom => write!(f, "'fn' used as atom doesn't make sense"), CaseAsAtom => write!(f, "'case' used as atom doesn't make sense"), RestAsAtom => write!(f, "'..[name]' used as atom doesn't make sense"), diff --git a/src/type/mod.rs b/src/type/mod.rs index e979595..06b73ac 100644 --- a/src/type/mod.rs +++ b/src/type/mod.rs @@ -79,6 +79,8 @@ pub enum TypeError { NoWildcardInCase(SExp), + DifferentTypeCaseArms(Type, Type), + OtherError } |