-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 #15494: Handle non-specialized functions in EtaReduce. #15498
Fix #15494: Handle non-specialized functions in EtaReduce. #15498
Conversation
In Scala.js, function specialization is disabled. This means that non-specialized functions can reach `EtaReduce`. Previously, it did not handle the shape of right-hand-side for non-specialized functions returning primitives. We fix the issue by handling those, like we already handled `.asInstanceOf`s.
As it is a regression from 3.1.2, I think we should backport it to 3.2.0. |
What's the procedure for that? Do I retarget this PR to |
We merge to main and then backport. |
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.
Nice explanation of the fix!
In Scala.js, function specialization is disabled. This means that non-specialized functions can reach
EtaReduce
. Previously, it did not handle the shape of right-hand-side for non-specialized functions returning primitives. We fix the issue by handling those, like we already handled.asInstanceOf
s.How I fixed it
First, I took the reproduction from the issue and put it in
sandbox/scalajs/src/hello.scala
. I verified that I could reproduce withNext, I looked at the Scala.js IR produced for this code:
showed nothing wrong, but
showed, sure enough, an extra wrapping when calling
asFunction0
forf2
andf3
, which is not present forf1
:Now I needed to diagnose what phase within the compiler caused the issue. I do that with
flatten
is always a good first candidate when working on Scala.js issues, as it shows the dotc trees right before the back-end.flatten
shows that the wrappings are already there, so the issue must come earlier. There's not supposed to be major differences in transformations in earlier phases for Scala.js versus Scala/JVM, especially when no Scala.js-specific code is involved.So I started investigating the difference in
-Xprint
between Scala/JVM and Scala.js for the same snippet.I reached the conclusion that the group of
etaReduce
received as input something worse on Scala.js than Scala/JVM. And for good reason: the input on Scala/JVM uses specialized function types, which don't exist on Scala.js.I then tried reproducing on Scala/JVM by manually deactivating the
SpecializeFunctions
phase. Sure enough, the issue was triggered.From there, it was a matter of looking at the shape of trees received by
EtaReduce
whenSpecializeFunctions
is disabled, and adding cases inEtaReduce
to handle those shapes.