-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Initialization of nested objects differs based on whether they are wrapped in a trait #21444
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
@lrytz @som-snytt does this ring a bell? I feel like there are old tickets on this . there’s scala/scala-dev#16 but it's more about the optimizer there's also scala/bug#5304 (comment) , and also the linked tickets from there — maybe that's actually what I'm remembering 🤔 |
FWIW we have code in Mill that wraps things in classes just to work around this issue, which is how I noticed. Not the end of the world, but would be nice if i could eiminate the awkward wrapper class and still have proper initiaization behavior |
IMO this is basically by design at this point. The behavior inside a trait (or class) is the one that makes the most sense, and also the one that could not be changed even if we wanted to. But the behavior for static objects is more efficient, and there's bound to be a number of codebases that basically rely on that better efficiency. I know I have. |
Some kind of wontfix is fine by me. Apart from performance, changing this now would seem like a pretty big breaking change semantically. But if we're not going to fix it, should it at least be documented in the spec somewhere? It's super strange behavior after all, and even after playing around for a bit I'm still not totally sure what I should be expecting (e.g. doing |
Agree @sjrd. Just to confirm, changing Also agree that it should be in the spec, like the difference between a reference to |
Spec says that an We are lulled into complacency because we write top-level Agree with Seth that there is too much history. I recently read an old Odersky comment on the same refrain about nested static classes not forcing. I have no idea where that was. Why are we having this conversation in 2024? Is it documentation, tooling, or implementation? I think |
cc @liufengyun |
While working on We have to teach the analysis to understand the optimization in order to support common Scala code patterns. Otherwise, we would have to report too many warnings about initialization cycles between outer static object and nested static objects.
Maybe the spec can introduce the concept of static objects:
Accessing an inner static object does not go through the outer static object. An expression The semantics of none-static objects is exactly as its desugaring to
Given that the initialization-time between the outer static object and inner static object are not correlated, such a warning should always be emitted, which makes it less useful. |
Out of curiousity, does this behavior lead to unsoundness? I thought part of the reason why Scala's typechecking is sound is because for any type |
It seems to me it will not impact soundness --- the static objects will be ensured to be initialized the first time they are accessed. During the initialization of a static object, the partially initialized state might be observed, as it's the case in a normal class: class A: // same for `object A`:
val n = m + 1
val m: Int = 10
class B: // same for `object B`
class Inner:
println(n)
val inner = new Inner
val n = 10 If two static objects form an initialization cycle, then uninitialized fields of the static objects might be observed (or potential deadlock in the presence of concurrency). These errors are supposed to be caught by Edit: see #5854 |
Compiler version
3.5.0, same behavior in 2.13.14
Minimized code
The following code does not print
Hello outer
But if I wrap the
object outer
in atrait
, it does printHello outer
Expectation
I would expect the initialization behavior of nested objects to be consistent regardless of whether or not they are wrapped in traits
The text was updated successfully, but these errors were encountered: