aboutsummaryrefslogtreecommitdiff
path: root/src/type
diff options
context:
space:
mode:
Diffstat (limited to 'src/type')
-rw-r--r--src/type/check.rs8
-rw-r--r--src/type/conversion.rs15
2 files changed, 22 insertions, 1 deletions
diff --git a/src/type/check.rs b/src/type/check.rs
index 5ccd0e7..bb88efb 100644
--- a/src/type/check.rs
+++ b/src/type/check.rs
@@ -510,6 +510,14 @@ impl Type {
Ok(r1)
},
+ (SumType(a1, a2), SumType(b1, b2)) => {
+ let mut r1 = a1.infer_generics_ctx(b1, ctx.clone())?;
+ let r2 = a2.infer_generics_ctx(b2, ctx.clone())?;
+ r1.extend_from_slice(&r2);
+ r1.extend_from_slice(&ctx);
+ Ok(r1)
+ },
+
(List(v1), List(v2)) => {
let mut res = ctx.clone();
for (t1, t2) in v1.into_iter().zip(v2.into_iter()) {
diff --git a/src/type/conversion.rs b/src/type/conversion.rs
index ab858e6..54fc59d 100644
--- a/src/type/conversion.rs
+++ b/src/type/conversion.rs
@@ -11,7 +11,7 @@ impl Type {
/// 0. self == other => self
/// 1. (T T ... T T) -> (T ...)
/// 2. self = concrete and other = variable type => self,
- /// 3. arrow types and lists are mapped
+ /// 3. arrow types and lists and sums are mapped
/// 4. makes [self] self if self == other
pub fn convert(self, other: &Type) -> Result<Type, ()> {
let (ty, ctx) = self.convert_ctx(other)?;
@@ -62,6 +62,14 @@ impl Type {
Ok((arr(t1, t2), ctx))
},
+ (SumType(a1, a2), SumType(b1, b2)) => {
+ let (t1, newctx) = a1.convert_ctx(b1)?;
+ ctx.extend(newctx);
+ let (t2, newctx) = a2.convert_ctx(b2)?;
+ ctx.extend(newctx);
+ Ok((sumtype(t1, t2), ctx))
+ },
+
(List(v), VecOf(ty)) => match v.get(0) {
Some(t) => {
let (convt, newctx) = t.clone().convert_ctx(ty)?;
@@ -163,6 +171,11 @@ mod tests {
.convert(&arr(vt("T"), vt("T"))),
Ok(arr(arr(vecof(Integer), Integer), arr(vecof(Integer), Integer)))
);
+ assert_eq!(
+ sumtype(sumtype(vecof(Integer), Integer), sumtype(vecof(Integer), Integer))
+ .convert(&sumtype(vt("T"), vt("T"))),
+ Ok(sumtype(sumtype(vecof(Integer), Integer), sumtype(vecof(Integer), Integer)))
+ );
assert!(
List(vec![Integer, Boolean])