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
Compiler silently fails to @tailrec a nested tail-recursive function #6526
Comments
Imported From: https://issues.scala-lang.org/browse/SI-6526?orig=1 |
Kris Nuttycombe (nuttycom) said: |
Viktor Klang (viktorklang) said (edited on Oct 15, 2012 10:29:52 PM UTC): (Not saying that it shouldn't be fixed, but clearly there's a work-around here, which is not to put @tailrec def in closures until the bug is fixed) |
Kris Nuttycombe (nuttycom) said: |
Viktor Klang (viktorklang) said: |
@djspiewak said: The fact is that this is a silent failure of the worst sort. It is a bug in the compiler that introduces a failure condition in your code that is likely to only exist in production (where you see realistic dataset sizes). Compiler bugs are bad enough. Silent compiler bugs are worse. Silent compiler bugs that are only identifiable by reading the bytecode are worse still. Silent compiler bugs that cause your code to crash only in production are DEATH. My point is this: even though there is a workaround, it's not one that is practical for many people (including us). Even if it were, this bug needs to be fixed. There is almost certainly a lot of code out there, right now, that is broken without anyone knowing. People can't use a workaround if they don't know they have a problem. |
Viktor Klang (viktorklang) said: |
@adriaanm said: |
Kris Nuttycombe (nuttycom) said: |
@dragos said: |
@paulp said: |
The
inner
function in the above code will be compiled into the following bytecode:Needless to say,
invokevirtual
!=goto
. This was a silent failure of the tailrec optimization. No warnings were emitted by the compiler. This bug was found against 2.9.2 and later reproduced against a fresh build of the 2.10.0-RC1 tag.Hilariously, removing the
getOrElse 42
resolves the issue, and the compiler is able to compile the tail recursive call into a jump.Given how pervasive this "@tailrec inner function" idiom is within the standard library, akka, and myriads of code bases (including Precog), this seems like a very serious issue. It basically implies that a lot of code that people think is safe will actually explode for sufficiently large datasets.
The text was updated successfully, but these errors were encountered: