diff options
author | Paul Phillips <paulp@improving.org> | 2013-05-08 04:47:36 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-05-08 06:04:06 -0700 |
commit | 15df9e970a1d1323148eee714352b55eba429f44 (patch) | |
tree | 60894262689b183b0ba513fcbb8d205d03dbc87f | |
parent | 9a2f6c75cce22565b994c0b8bd2af8acc6e6f178 (diff) | |
download | scala-15df9e970a1d1323148eee714352b55eba429f44.tar.gz scala-15df9e970a1d1323148eee714352b55eba429f44.tar.bz2 scala-15df9e970a1d1323148eee714352b55eba429f44.zip |
Limit unnecessary calls to Type#toString.
Logging revealed a few thousand calls to the often expensive
Type#toString emerging from tailcalls. The error message was
being generated for all methods even though it was only issued
in rare cases (and for the particular tailrec failure which
made the call, extremely rare.)
The remaining boatload of unnecessary Type#toString calls are
much harder to fix due to the design of "AbsTypeError" and the
fact that the compiler approaches mutability like a cat approaches
a loaded gun. See SI-6149.
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/TailCalls.scala | 12 | ||||
-rw-r--r-- | test/files/neg/tailrec-2.check | 2 |
2 files changed, 7 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index 9e867917f9..6f422fcc90 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -89,12 +89,12 @@ abstract class TailCalls extends Transform { */ class TailCallElimination(unit: CompilationUnit) extends Transformer { private def defaultReason = "it contains a recursive call not in tail position" - private val failPositions = perRunCaches.newMap[TailContext, Position]() - private val failReasons = perRunCaches.newMap[TailContext, String]() + private val failPositions = perRunCaches.newMap[TailContext, Position]() withDefault (_.methodPos) + private val failReasons = perRunCaches.newMap[TailContext, String]() withDefaultValue defaultReason private def tailrecFailure(ctx: TailContext) { - val method = ctx.method - val failReason = failReasons.getOrElse(ctx, defaultReason) - val failPos = failPositions.getOrElse(ctx, ctx.methodPos) + val method = ctx.method + val failReason = failReasons(ctx) + val failPos = failPositions(ctx) unit.error(failPos, s"could not optimize @tailrec annotated $method: $failReason") } @@ -237,7 +237,7 @@ abstract class TailCalls extends Transform { if (!ctx.isEligible) fail("it is neither private nor final so can be overridden") else if (!isRecursiveCall) { - if (receiverIsSuper) failHere("it contains a recursive call targeting supertype " + receiver.tpe) + if (receiverIsSuper) failHere("it contains a recursive call targeting a supertype") else failHere(defaultReason) } else if (!matchesTypeArgs) failHere("it is called recursively with different type arguments") diff --git a/test/files/neg/tailrec-2.check b/test/files/neg/tailrec-2.check index d3432a7e76..1daad6922e 100644 --- a/test/files/neg/tailrec-2.check +++ b/test/files/neg/tailrec-2.check @@ -1,4 +1,4 @@ -tailrec-2.scala:8: error: could not optimize @tailrec annotated method f: it contains a recursive call targeting supertype Super[A] +tailrec-2.scala:8: error: could not optimize @tailrec annotated method f: it contains a recursive call targeting a supertype @annotation.tailrec final def f[B >: A](mem: List[B]): List[B] = (null: Super[A]).f(mem) ^ tailrec-2.scala:9: error: @tailrec annotated method contains no recursive calls |