Permalink
Browse files

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.
  • Loading branch information...
1 parent 9a2f6c7 commit 15df9e970a1d1323148eee714352b55eba429f44 @paulp paulp committed May 8, 2013
Showing with 7 additions and 7 deletions.
  1. +6 −6 src/compiler/scala/tools/nsc/transform/TailCalls.scala
  2. +1 −1 test/files/neg/tailrec-2.check
@@ -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")
@@ -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

0 comments on commit 15df9e9

Please sign in to comment.