-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Recursively calling a lazy val is broken, prevents bootstrapping tests from passing #1856
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
The spec is super vague: http://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#lazy
|
I think the spec permits the new behavior (and it is actually more useful
than the old one), so I would opt for disabling the test.
…On Sat, Dec 24, 2016 at 4:16 AM, Guillaume Martres ***@***.*** > wrote:
The spec is super-vague: http://www.scala-lang.org/
files/archive/spec/2.11/05-classes-and-objects.html#lazy
Attempting to access a lazy value during its initialization might lead to
looping behavior.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#1856 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAwlVrbOKavOwIJWRxgVmCSYW7R4fTPZks5rLGR7gaJpZM4LVHdu>
.
{"api_version":"1.0","publisher":{"api_key":"
05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":
{"external_key":"github/lampepfl/dotty","title":"
lampepfl/dotty","subtitle":"GitHub repository","main_image_url":"
https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-
11e6-95fc-7290892c7bb5.png","avatar_image_url":"https://
cloud.githubusercontent.com/assets/143418/15842166/
7c72db34-2c0b-11e6-9aed-b52498112777.png","action":{"name":"Open in
GitHub","url":"https://github.com/lampepfl/dotty"}},"
***@***.*** in #1856: The
spec is super-vague: http://www.scala-lang.org/files/archive/spec/2.11/05-
classes-and-objects.html#lazy\r\n\u003e Attempting to access a lazy value
during its initialization might lead to looping
behavior."}],"action":{"name":"View Issue","url":"https://github.
com/lampepfl/dotty/issues/1856#issuecomment-269059401"}}}
--
Prof. Martin Odersky
LAMP/IC, EPFL
|
The test in question is
It does, but consider that this means that the same code will silently have different semantics depending on whether it was compiled with scalac or dotty. At the very least, this should be clearly documented somewhere. I would be more confortable with a difference in semantics if it was obvious (for example, the recursive call could throw an exception instead of returning |
Also, consider what this means for non-nullable types, are we going to require that lazy vals always need to have a nullable type? |
I've hit this again, this time while compiling |
I did make a fix that changes behavior, but it has substantial side effects that I'd prefer to discuss. |
SIP-20 considers circular initializations erroneous code. That would be the "principled" approach. Why not just throw an exception then always? Other semantics are not something you'd call lazy vals. The latest variant of #1892 still allowed observable changes for lazy vals if the first initialization produces a zero for the expected type. In comparison, having three states (initial; initialization started, no calls allowed till initialization completed; initialization completed), like in SIP-20, avoids this issue. |
Checking for circular initialization reliably would require substantial modifications to the scheme, and those would introduce slowdowns. In particular, the current non-@volatile lazy vals scheme doesn't introduce a single memory barrier. As the actual critical blocker bug is now fixed, I'm closing this one. Feel free to open a separate issues for topics discussed here. |
I don't know if any of this is specified but:
With scalac:
With dotty:
This is not just a theoretical problem, I hit this while trying to get the sbt-based bootstrapping tests to work, the lazy val was https://github.com/lampepfl/dotty/blob/119725799675ee00d6d3374771765b88e4de67bc/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala#L30, the cycle involves looking up the root
DottyPredef
import while completing the import (stacktrace: https://gist.github.com/smarter/b2126f895a8458506e58710c93bc9342). I assume that this is not a loop with the Scala2-compiled dotty because we carefully avoid cycles in various ways.The text was updated successfully, but these errors were encountered: