For loop type inference fix #128
No reviewers
Labels
No Milestone
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: M-Labs/nac3#128
Loading…
Reference in New Issue
No description provided.
Delete Branch "for_loop_type_fix"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I encounter the bug when testing my fix for
len
.Now it seems that with
range
, the nested for loop type check will be broken:will give:
And if we mention
i
to be int:it will still give:
As fas as I understand it, it is due to the sequence we do the type inference: we first go to the
for
body and then check whether our iterator and target are of compatible types. So in this case of nested for loop,r
will be a typevar in the first for loop body, and previously we wrongly assume that ifr
is not of typerange
, then it is of type list, so we get the error.I am not entirely sure if this way would be appropriate. I thought about some other ways but does not seem to work, If we constraints
r
to be something likevar1(range = [`range`, list[var2]])
, there is no way we can later get the type ofi
ifr
turns out to be of typerange
in the outer for loop. So I think we need to change the order we do type inference on for loop to first constranint the type of iter and target (similar to assignment), and then type check the body... (BTW I think this might also become a related potential problem if we later add support to allow typevars to be inside typevar constraints? like how do we unifyvar0[var1, var2]
withint
?)I also added some concrete check when I think should be missing previously, which I think might cause some typevars to leak to the codegen phase and cause panic.
I think for some more time and the major problem seems to be the unification between the type var
var1(range = [list[var2], range])
(list of something or range), and the typelist[some concrete type T]
orrange
list[some concrete type T]
is the case, how canvar2
get update withsome concrete type T
?range
is the case, how to getvar2
to beint32
?Maybe I did not think about it in a right way... how the order of doing things matters here as the unification process is supposed to be undirected anyway? The current commits workaround it when the type of the iter of the outmost loop is known, but might fail when that type is still a type var... I am not sure whether I missed anything but it seems that it would not be a type var?
Actually, the fundamental problem is due to how we treat iterators. We have an inference rule which states that
for _ in expr
implies thatexpr: list[T]
. The range type is something I later hacked into the type system without much consideration and would break in some cases (by break I mean report a type error when it is correct, but not inferring an incorrect type).A proper fix would be to change the type system to allow for iterator type, which can be range type, list type or other user defined iterators. But I think if this patch can make the above example compile, it should be fine for the majority of the cases.
Ah I get it, yes and I think for this issue (#137) we would need to add iterator type to the existing type system anyway. For now this patch should be working.