summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-01-19 22:25:20 +0300
committerEugene Burmako <xeno.by@gmail.com>2014-01-20 09:48:13 +0300
commit35300b46311c93c692744701275dbb4807f851e2 (patch)
tree492e5202d3f52afd60c9ee419c3e1a1a98098fed /src
parent936d60a2621088ba463a44c2f2d6450986022169 (diff)
downloadscala-35300b46311c93c692744701275dbb4807f851e2.tar.gz
scala-35300b46311c93c692744701275dbb4807f851e2.tar.bz2
scala-35300b46311c93c692744701275dbb4807f851e2.zip
introduces failsafe against endless type printing
The parent commit works around a particular problem that led to a compiler freeze in SI-8158, whereas this commit introduces a general solution - a cache that tracks all types that we've recursed into during printing. I can't immediately come up with an example of a type that would be caught by this safety net, but unknown unknowns are the worst of them all, so why not guard against them while we can.
Diffstat (limited to 'src')
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala13
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala1
-rw-r--r--src/reflect/scala/reflect/runtime/SynchronizedTypes.scala3
3 files changed, 16 insertions, 1 deletions
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala b/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala
index ebc4394d25..b08aabef85 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala
@@ -3,6 +3,8 @@ package reflect
package internal
package tpe
+import scala.collection.mutable.HashSet
+
private[internal] trait TypeToStrings {
self: SymbolTable =>
@@ -14,8 +16,15 @@ private[internal] trait TypeToStrings {
def tostringRecursions = _tostringRecursions
def tostringRecursions_=(value: Int) = _tostringRecursions = value
+ private var _tostringSubjects = HashSet[Type]()
+ def tostringSubjects = _tostringSubjects
+
protected def typeToString(tpe: Type): String =
- if (tostringRecursions >= maxTostringRecursions) {
+ if (tostringSubjects contains tpe) {
+ // handles self-referential anonymous classes and who knows what else
+ "..."
+ }
+ else if (tostringRecursions >= maxTostringRecursions) {
devWarning("Exceeded recursion depth attempting to print " + util.shortClassOfInstance(tpe))
if (settings.debug)
(new Throwable).printStackTrace
@@ -25,8 +34,10 @@ private[internal] trait TypeToStrings {
else
try {
tostringRecursions += 1
+ tostringSubjects += tpe
tpe.safeToString
} finally {
+ tostringSubjects -= tpe
tostringRecursions -= 1
}
}
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index 6b3985d434..ac6dd0783d 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -42,6 +42,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
// inaccessible: this._glbResults
// inaccessible: this._indent
// inaccessible: this._tostringRecursions
+ // inaccessible: this._tostringSubjects
// inaccessible: this.atomicIds
// inaccessible: this.atomicExistentialIds
// inaccessible: this._recursionTable
diff --git a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala
index de78e527a7..12ada07a56 100644
--- a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala
+++ b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala
@@ -85,6 +85,9 @@ private[reflect] trait SynchronizedTypes extends internal.Types { self: SymbolTa
override def tostringRecursions = _tostringRecursions.get
override def tostringRecursions_=(value: Int) = _tostringRecursions.set(value)
+ private lazy val _tostringSubjects = mkThreadLocalStorage(new mutable.HashSet[Type])
+ override def tostringSubjects = _tostringSubjects.get
+
/* The idea of caches is as follows.
* When in reflexive mode, a cache is either null, or one sentinal
* value representing undefined or the final defined