diff options
author | David MacIver <david.maciver@gmail.com> | 2008-10-29 00:52:55 +0000 |
---|---|---|
committer | David MacIver <david.maciver@gmail.com> | 2008-10-29 00:52:55 +0000 |
commit | 0bc8157005ab98782df672dd156f924abd21f69b (patch) | |
tree | 0649d62fe739b1f6d7c11056ba4d7b7220d46d68 | |
parent | 325e2ba1b1a1d2c05bd8f5981dbbfd00b2c7e2d8 (diff) | |
download | scala-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.scala | 14 |
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 |