-
Notifications
You must be signed in to change notification settings - Fork 14
Clarify / unify delaying of module / class initializers by the compiler / optimizer #112
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
Comments
I had a discussion about this with @odersky at some point, related to I argue that we should generally relax the spec around object initialization. My take is that the spec should guarantee that an object is never initialized before it is first used, but that it can be initialized either at that moment or any time later in the execution, or never at all. object A {
val x: Int = 5
}
A.x will give 5 (it could give 0). So something must be said about accessing fields, like it is guaranteed that It is actually a very tricky topic. So far in Scala.js we indeed assume that a module load is always non-null (by UB'ing the alternative), but otherwise the back-end and the optimizer guarantee to keep exactly the initialization semantics that scalac gives us. Including things like http://scalapuzzlers.com/#pzzlr-010 |
Let's consider a "worse is better" approach of starting with a whiltelist of common stdlib modules (like |
Here's a take on this issue by @paulp, in which he proposed an annotation to mark pure modules: scala/scala#2416 |
This omits a key condition. object A {
final val x1 = 5
final val x2: Int = 5
} Accessing x1 does not initialize A, accessing x2 does. |
Yes when I say "final val" I usually mean "final val without an explicit type that constant-folds and gives a constant type". |
@sjrd of course that's what I mean when I say that too, like all of us with advanced degrees in compiler implementation detail. I was just looking out for the poor drive-by programmer who might stick his head in here. |
Another example where we discard module loads: https://issues.scala-lang.org/browse/SI-10209. The doc on
I don't really understand that thinking, as inlining discards side effects. |
scala/scala#7133 allows the optimizer to delay class loading, delay initialization of core modules (Predef), treat module loads as non-null. Can be disabled using optimzier flags. |
In some situations the compiler delays module loads, which is not according to the spec.
Examples:
A
,A.apply
is replaced bynew A
SI-5304object O { ???; object I }; O.I
Changing this to follow the spec is not straightforward, see discussion on the above issue, and also linked issues.
The same question arises for static initializers of java classes.
For example, the inliner currently delays class initialization when inlining a static method.
A related question is whether the compiler can assume that a module load is always non-null, which is not the case SI-9655.
The scala-js optimizer for example makes this assumption (scala/scala#2954 (comment)).
The text was updated successfully, but these errors were encountered: