Open jamescheney opened 2 years ago
Also:
mutual {
fun bar() { 42 }
fun baz() { "xyzzy" }
fun foo(baz){
{baz()}
}
}
foo(bar)
runs and returns "xyzzy" : Int
, which suggests that typechecking is doing the right thing but this is happening after typechecking... Indeed looking at the type of foo, it is correctly generalized to (() ~a~> b::Any) ~a~> b::Any
which suggests that scope is being handled correctly at least until type inference.
I will put this issue under "name shenanigans" umbrella of issues that I have been working on for some time. As with the other name issues, the proper solution here is to have a properly hygienic names. This is a non-trivial change, although, it is something I have nearly implemented in another patch https://github.com/dhil/links/tree/name-resolution. I will try to prioritise some time for landing that patch this summer.
Consider the following (contrived) program:
This should call foo, then bar,then return 42. And it does.
Now consider the following, alpha-renamed program.
This should call foo, then bar, then return 42. And it does not.
From looking at the generated IR, for some reason the bindings of mutually recursive functions in mutual blocks are being used instead of local parameter names when there is a conflict.
In some examples in #1136 this appears to be making something work inside a mutual block by accident that otherwise doesn't.