summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeComparers.scala25
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala1
-rw-r--r--test/files/pos/t8146a.scala (renamed from test/pending/pos/t8146a.scala)0
-rw-r--r--test/files/pos/t8146b.scala (renamed from test/pending/pos/t8146b.scala)0
4 files changed, 11 insertions, 15 deletions
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
index b60fecd66e..027da6ed50 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
@@ -17,20 +17,15 @@ trait TypeComparers {
private val _pendingSubTypes = new mutable.HashSet[SubTypePair]
def pendingSubTypes = _pendingSubTypes
- class SubTypePair(val tp1: Type, val tp2: Type) {
- override def hashCode = tp1.hashCode * 41 + tp2.hashCode
- override def equals(other: Any) = (this eq other.asInstanceOf[AnyRef]) || (other match {
- // suspend TypeVars in types compared by =:=,
- // since we don't want to mutate them simply to check whether a subtype test is pending
- // in addition to making subtyping "more correct" for type vars,
- // it should avoid the stackoverflow that's been plaguing us (https://groups.google.com/d/topic/scala-internals/2gHzNjtB4xA/discussion)
- // this method is only called when subtyping hits a recursion threshold (subsametypeRecursions >= LogPendingSubTypesThreshold)
- case stp: SubTypePair =>
- val tvars = List(tp1, stp.tp1, tp2, stp.tp2) flatMap (t => if (t.isGround) Nil else typeVarsInType(t))
- suspendingTypeVars(tvars)(tp1 =:= stp.tp1 && tp2 =:= stp.tp2)
- case _ =>
- false
- })
+ final case class SubTypePair(tp1: Type, tp2: Type) {
+ // SI-8146 we used to implement equality here in terms of pairwise =:=.
+ // But, this was inconsistent with hashCode, which was based on the
+ // Type#hashCode, based on the structure of types, not the meaning.
+ // Now, we use `Type#{equals,hashCode}` as the (consistent) basis for
+ // detecting cycles (aka keeping subtyping decidable.)
+ //
+ // I added a tests to show that we detect the cycle: neg/t8146-no-finitary*
+
override def toString = tp1+" <:<? "+tp2
}
@@ -262,7 +257,7 @@ trait TypeComparers {
if (subsametypeRecursions >= LogPendingSubTypesThreshold) {
val p = new SubTypePair(tp1, tp2)
if (pendingSubTypes(p))
- false
+ false // see neg/t8146-no-finitary*
else
try {
pendingSubTypes += p
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index c87995275f..a2d3206156 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -198,6 +198,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.ErroneousCollector
this.adaptToNewRunMap
// inaccessible: this.commonOwnerMapObj
+ this.SubTypePair
this.SymbolKind
this.NoSymbol
this.CyclicReference
diff --git a/test/pending/pos/t8146a.scala b/test/files/pos/t8146a.scala
index e4eb8d3fd1..e4eb8d3fd1 100644
--- a/test/pending/pos/t8146a.scala
+++ b/test/files/pos/t8146a.scala
diff --git a/test/pending/pos/t8146b.scala b/test/files/pos/t8146b.scala
index dd031f66c8..dd031f66c8 100644
--- a/test/pending/pos/t8146b.scala
+++ b/test/files/pos/t8146b.scala