-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix name duplication in code generation for new definition typing #197
Fix name duplication in code generation for new definition typing #197
Conversation
Please `git cherrypick` this to a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for the better solution. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, this looks like a very hacky solution on top of an extremely hacky foundation.
Thankfully, we'll replace this hacky stuff soon once the new symbols are implemented. So let's just merged the hack.
BTW, does it work in situations like the following?
fun foo: Int -> Int
fun foo = x => x + 1
class Bar { fun calc(x) = foo(x) }
class Bar { fun calc(x) = foo }
fun foo: Int
fun foo = 123
I agree. I think the original approach (declare top-level let bindings, and unregister them if there's any error) is imperfect and hacky. So, this is actually a hacky fix to address the imperfectness of previous approach and will be soon removed by the help of I will try your example and add it to tests. |
The test cases you suggested work. |
We might notice a strange behavior of code generation: if we declare a symbol
x
and then define it, the generated JavaScript function name will have a numeric postfixx1
, which indicates that some otherx
was shadowed. But this is the very first time wherex
is defined in this file.Well, this is caused by an imperfect workaround for translating classes in new definition typing. Consider the following code.
Code generation lifts class definitions (e.g.,
Foo
) and translates them into a typing unit class before translating top-level let bindings (e.g.,f
). So, theScope
should contains some sort of stub symbols of top-level let bindings before translating classes. The current implementation does not handle this well, as it just declaresValueSymbol
in the first place.mlscript/shared/src/main/scala/mlscript/JSBackend.scala
Lines 1404 to 1412 in 231d9ec
Then, after the translation of the typing unit class, when translating the top-level let bindings, the symbols will be declared twice and the runtime will be renewed, thus the runtime name comes with a numeric postfix. This sometimes cause runtime errors of undefined references. For example,
This PR fixes this problem by adding a Boolean field
forNewDefsDryRun
toValueSymbol
, which indicates if this symbol is declare in the situation as described above. If new symbols are shadowing this symbol, we will reuse the runtime name rather than allocating new names.