You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix#17549: Unify how Memoize and Constructors decide what fields need storing. (#17560)
The Memoize and Constructors have to work together and agree on which
`final val`s actually need storing in a field. Previously, they used
slightly different criteria: one on the result type, and one on the rhs
(with an additional Scala.js-specific eligibility condition). That
discrepancy resulted in the crash/wrong codegen in the issue.
We now unify both: we avoid a field if and only if all of the following
apply:
* it is a `final val`,
* its result *type* is a `ConstantType`, and
* it is eligible according to Scala.js semantics.
In particular, there is no condition on the right-hand-side. We avoid a
field even if the right-hand-side has side effects. The side effects are
moved to the constructor regardless.
---
This introduces both progressions and regressions in the amount of
fields we generate. We can avoid fields even for side-effecting rhs'es,
as long as the result type is constant. On the other hand, we now create
a field for `final val`s with non-constant result type, even if the rhs
is a literal.
While the latter is a regression for Scala 3, it aligns with the
behavior of Scala 2. It also has the nice benefit that whether or not a
val has a field is now independent of its *implementation*, and only
dependent on its *API*. Overall, I think this is a trade-off worth
taking.
We could reintroduce that optimization in the future (but in classes
only; not in traits), if we really want to, although that would require
dedicated code.
0 commit comments