summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid MacIver <david.maciver@gmail.com>2008-10-29 00:52:55 +0000
committerDavid MacIver <david.maciver@gmail.com>2008-10-29 00:52:55 +0000
commit0bc8157005ab98782df672dd156f924abd21f69b (patch)
tree0649d62fe739b1f6d7c11056ba4d7b7220d46d68
parent325e2ba1b1a1d2c05bd8f5981dbbfd00b2c7e2d8 (diff)
downloadscala-0bc8157005ab98782df672dd156f924abd21f69b.tar.gz
scala-0bc8157005ab98782df672dd156f924abd21f69b.tar.bz2
scala-0bc8157005ab98782df672dd156f924abd21f69b.zip
I feel like I should be waving a dead chicken w...
I feel like I should be waving a dead chicken with this commit. As was discussed in scala-devel, the pattern matching for Scanners generates very nested if statements. This makes the typechecker work really hard to check these if statements, descending into a deeply nested tree. This can blow the stack. So, what's the solution? Don't touch Scanners at all. Change the definition format for four character constants in SourceFile.scala. Suddenly the problem goes away and we get a lovely big switch statement. The type checker no longer has to do all that work. Clearly this is a bug in the pattern matcher. See #1456. But as I don't know when I'll have a fix for that, this works as a temporary workaround. I don't understand why it works yet, but it does. Hence the sacrificial chicken. All hail Zog, protector of the type checker!
-rw-r--r--src/compiler/scala/tools/nsc/util/SourceFile.scala14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/util/SourceFile.scala b/src/compiler/scala/tools/nsc/util/SourceFile.scala
index 3215aae627..b95471adc0 100644
--- a/src/compiler/scala/tools/nsc/util/SourceFile.scala
+++ b/src/compiler/scala/tools/nsc/util/SourceFile.scala
@@ -9,10 +9,16 @@ package scala.tools.nsc.util
import scala.tools.nsc.io.{AbstractFile, VirtualFile}
object SourceFile {
- val LF: Char = 0x0A
- val FF: Char = 0x0C
- val CR: Char = 0x0D
- val SU: Char = 0x1A
+ // Be very careful touching these.
+ // Apparently trivial changes to the way you write these constants
+ // will cause Scanners.scala to go from a nice efficient switch to
+ // a ghastly nested if statement which will bring the type checker
+ // to its knees. See ticket #1456
+ final val LF = '\u000A'
+ final val FF = '\u000C'
+ final val CR = '\u000D'
+ final val SU = '\u001A'
+
def isLineBreak(c: Int) = c match {
case LF|FF|CR|SU => true
case _ => false