Skip to content

Conversation

sjrd
Copy link
Member

@sjrd sjrd commented Sep 7, 2025

And related changes.


Scala.js 1.20.x contains the last IR changes required for good performance in WebAssembly. It would be really good to have this for the next LTS (and hence for 3.8.0), as it only applies to libraries recompiled with this new IR.

@sjrd sjrd added this to the 3.8.0 milestone Sep 7, 2025
@sjrd sjrd requested a review from natsukagami September 7, 2025 10:48
@sjrd sjrd added the needs-minor-release This PR cannot be merged until the next minor release label Sep 7, 2025
Copy link
Contributor

@natsukagami natsukagami left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some questions, otherwise LGTM!

This is a forward port of the compiler changes in the Scala.js commit
scala-js/scala-js@5bfa254

It is now possible to use `@JSOperator` on a method named `**` in
a JS type. In that case, it will translate to the JavaScript `**`
operator. This is only valid when emitting ES 2016 or later, as it
is not valid ES 2015 code.

Without an explicit `@JSOperator` annotation, such a method still
defaults to being a method call, to preserve backward
compatibility.
In this commit, we ignore the new test for `linkTimeIf`.
This commit is a forward port of the compiler changes in
scala-js/scala-js@5e842d8
When B <: A and C <: A, `linkTimeIf[A](cond) { B }{ C }` would
generate an `.asInstanceOf[A]` that casts the resulting value to a
supertype. However, this cast is redundant, as the linker will
prune one branch at link time, and the remaining expression is
already known to be a compatible type.

This commit eliminates the surrounding `.asInstanceOf` around the
`linkTimeIf[T]` when both `thenp` and `elsep` are known to be
subtypes of `T`. The optimizer already routinely performs this
optimization. However, that comes too late for the module instance
field alias analysis performed by `IncOptimizer`. In that case,
while the desugarer removes the `LinkTimeIf`, the extra
`AsInstanceOf` prevents aliasing the field. Removing the cast ahead
of time in the compiler allows field aliases to be recognized in
the presence of `LinkTimeIf`s.

This commit is a forward port of the Scala.js commit
scala-js/scala-js@9bb267c
We now recognize the shapes of varargs, deconstruct them, and emit
instead calls to Scala.js-specific runtime methods. Those methods
choose at link-time the best implementation for the target platform.

The changes in `genActualArgs` revealed that we cannot trust
`Symbol.isPrivate`. It uses `lastDenot.flagsUNSAFE` under the hood,
which returns absurd results if `lastDenot` happened to be accessed
within an `atPhase(...)` call. Therefore, we change those calls to
`sym.is(Private)` instead. `Symbol.is` always uses an up-to-date
denotation.

Another consequence of the optimization is that the string
representation of varargs seqs is altered in Scala.js. This is
consistent with the Scala 2 behavior. We generalize the check file
lookup of Vulpix to allow platform-dependent check files. We use
that mechanism to introduce Scala.js-specific versions of the
affected tests.

This commit is essentially a forward port of the Scala.js commit
scala-js/scala-js@24750cf
except that, in dotc, previously we did not do the optimization at
all.
@sjrd sjrd enabled auto-merge September 10, 2025 12:09
@sjrd sjrd merged commit 64f8cfa into scala:main Sep 10, 2025
44 checks passed
@sjrd sjrd deleted the scalajs-1.20.0 branch September 10, 2025 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-minor-release This PR cannot be merged until the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants