fixed variable freshness bug
This commit is contained in:
parent
c0a44756e3
commit
4577d0cc12
@ -52,7 +52,7 @@ doing unification.
|
||||
|
||||
Consider the following example:
|
||||
|
||||
```py
|
||||
```python
|
||||
X = TypeVar('X')
|
||||
|
||||
def head(a: list[X]) -> X:
|
||||
@ -68,7 +68,7 @@ algorithm tries to fit `(list[int32])` into `(list[X])`, giving a substitution
|
||||
Substitution can also substitute variables into another variable. Consider the
|
||||
following example:
|
||||
|
||||
```
|
||||
```python
|
||||
X = TypeVar('X')
|
||||
Y = TypeVar('Y', int32, int64)
|
||||
|
||||
@ -89,7 +89,7 @@ So the function is well typed.
|
||||
|
||||
Note that variables are fresh in every invocation. Consider the following
|
||||
example:
|
||||
```
|
||||
```python
|
||||
I = TypeVar('I', int32, list[int32])
|
||||
|
||||
def add(a: int32, b: I) -> int32:
|
||||
@ -102,7 +102,7 @@ def add(a: int32, b: I) -> int32:
|
||||
|
||||
add(1, [1, 2, 3])
|
||||
```
|
||||
This one should type check (bug now). `I -> list[int32]` only affects 1 call,
|
||||
This one should type check. `I -> list[int32]` only affects 1 call,
|
||||
and the recursion inside could substitute `I -> int32`.
|
||||
|
||||
## Variable Scoping
|
||||
|
@ -14,3 +14,14 @@ class Vec:
|
||||
return Vec([self.v[i] + other.v[i] for i in range(len(self.v))])
|
||||
|
||||
|
||||
T = TypeVar('T', int32, list[int32])
|
||||
|
||||
def add(a: int32, b: T) -> int32:
|
||||
if type(b) == int32:
|
||||
return a + b
|
||||
else:
|
||||
for x in b:
|
||||
a = add(a, x)
|
||||
return a
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import ast
|
||||
import sys
|
||||
import copy
|
||||
from helper import CustomError
|
||||
from type_def import SelfType, ClassType
|
||||
from parse_stmt import parse_stmts
|
||||
@ -24,9 +25,11 @@ try:
|
||||
|
||||
for c, name, fn in fns:
|
||||
if c is None:
|
||||
params, result, _ = ctx.functions[name]
|
||||
params, result, var = ctx.functions[name]
|
||||
else:
|
||||
params, result, _ = ctx.types[c].methods[name]
|
||||
params, result, var = ctx.types[c].methods[name]
|
||||
# create substitution for type variables
|
||||
subst = {k: copy.deepcopy(ctx.variables[k]) for k in var}
|
||||
# check if fully annotated all params
|
||||
sym_table = {}
|
||||
for n, ty in zip(fn.args.args, params):
|
||||
@ -36,7 +39,7 @@ try:
|
||||
fn)
|
||||
if isinstance(ty, SelfType):
|
||||
ty = ctx.types[c]
|
||||
sym_table[n.arg] = ty
|
||||
sym_table[n.arg] = ty.subst(subst)
|
||||
_, _, returned = parse_stmts(ctx, sym_table, sym_table, result, fn.body)
|
||||
if result is not None and not returned:
|
||||
raise CustomError('Function may have no return value', fn)
|
||||
|
Loading…
Reference in New Issue
Block a user