diff --git a/toy-impl/inference.py b/toy-impl/inference.py index b77f3fa..9eab2e5 100644 --- a/toy-impl/inference.py +++ b/toy-impl/inference.py @@ -32,6 +32,8 @@ def find_subst(ctx: dict[str, Type], else: if a not in b.constraints: return f"{b} cannot take value of {a}" + if b in a.get_vars(): + return "Recursive type is not supported" sub[b.name] = a return sub diff --git a/toy-impl/test_subst.py b/toy-impl/test_subst.py index 7662195..575dc20 100644 --- a/toy-impl/test_subst.py +++ b/toy-impl/test_subst.py @@ -54,5 +54,6 @@ try_case(TupleType([X, X]), TupleType([X, Y]), {}) try_case(TupleType([X, X]), TupleType([Y, Y]), {}) try_case(TupleType([X, Y]), TupleType([X, X]), {}) try_case(TupleType([X, Y]), X, {}) +try_case(TupleType([i32, Y]), X, {}) diff --git a/toy-impl/type_def.py b/toy-impl/type_def.py index a2196de..262d408 100644 --- a/toy-impl/type_def.py +++ b/toy-impl/type_def.py @@ -2,6 +2,9 @@ class Type: def __eq__(self, other): return False + def get_vars(self): + return [] + class BotType: def __eq__(self, other): @@ -38,6 +41,9 @@ class TypeVariable(Type): def __eq__(self, other): return isinstance(other, TypeVariable) and self.name == other.name + def get_vars(self): + return [self] + class ClassType(Type): name: str @@ -83,6 +89,15 @@ class ParametricType(Type): return False return True + def get_vars(self): + result = [] + for p in self.params: + vars = p.get_vars() + for v in vars: + if v not in result: + result.append(v) + return result + class ListType(ParametricType): def __init__(self, param: Type): super().__init__([param])