Skip to content

Commit

Permalink
suspend type vars in SubTypePair's equals
Browse files Browse the repository at this point in the history
SubTypePair's equals method calls =:= on the involved types,
which mutates the TypeVars contained in them
this is undesirable since we're simply checking 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)

SubTypePair's equals method method is only called when subtype checking
hits a recursion threshold (subsametypeRecursions >= LogPendingSubTypesThreshold)
  • Loading branch information
adriaanm committed May 14, 2012
1 parent 32a2068 commit 1b198fa
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions src/compiler/scala/reflect/internal/Types.scala
Expand Up @@ -3068,7 +3068,8 @@ trait Types extends api.Types { self: SymbolTable =>
} }


def registerTypeEquality(tp: Type, typeVarLHS: Boolean): Boolean = { def registerTypeEquality(tp: Type, typeVarLHS: Boolean): Boolean = {
//println("regTypeEq: "+(safeToString, debugString(tp), typeVarLHS)) //@MDEBUG // println("regTypeEq: "+(safeToString, debugString(tp), tp.getClass, if (typeVarLHS) "in LHS" else "in RHS", if (suspended) "ZZ" else if (constr.instValid) "IV" else "")) //@MDEBUG
// println("constr: "+ constr)
def checkIsSameType(tp: Type) = def checkIsSameType(tp: Type) =
if(typeVarLHS) constr.inst =:= tp if(typeVarLHS) constr.inst =:= tp
else tp =:= constr.inst else tp =:= constr.inst
Expand Down Expand Up @@ -3127,7 +3128,7 @@ trait Types extends api.Types { self: SymbolTable =>
} }
def originName = { def originName = {
val name = origin.typeSymbolDirect.decodedName val name = origin.typeSymbolDirect.decodedName
if (name contains "_$") origin.typeSymbolDirect.decodedName else name if (name contains "_$") origin.typeSymbolDirect.decodedName else name // wait, what? - what?
} }
def originLocation = { def originLocation = {
val sym = origin.typeSymbolDirect val sym = origin.typeSymbolDirect
Expand All @@ -3146,7 +3147,7 @@ trait Types extends api.Types { self: SymbolTable =>
protected def typeVarString = originName protected def typeVarString = originName
override def safeToString = ( override def safeToString = (
if ((constr eq null) || (constr.inst eq null)) "TVar<" + originName + "=null>" if ((constr eq null) || (constr.inst eq null)) "TVar<" + originName + "=null>"
else if (constr.inst ne NoType) "" + constr.inst else if (constr.inst ne NoType) "=?" + constr.inst
else (if(untouchable) "!?" else "?") + levelString + originName else (if(untouchable) "!?" else "?") + levelString + originName
) )
override def kind = "TypeVar" override def kind = "TypeVar"
Expand Down Expand Up @@ -4925,7 +4926,23 @@ trait Types extends api.Types { self: SymbolTable =>
override def hashCode = tp1.hashCode * 41 + tp2.hashCode override def hashCode = tp1.hashCode * 41 + tp2.hashCode
override def equals(other: Any) = other match { override def equals(other: Any) = other match {
case stp: SubTypePair => case stp: SubTypePair =>
(tp1 =:= stp.tp1) && (tp2 =:= stp.tp2) // 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)
@inline def suspend(tp: Type) =
if (tp.isGround) null else suspendTypeVarsInType(tp)
@inline def revive(suspension: List[TypeVar]) =
if (suspension ne null) suspension foreach (_.suspended = false)

val suspensions = Array(tp1, stp.tp1, tp2, stp.tp2) map suspend

val sameTypes = (tp1 =:= stp.tp1) && (tp2 =:= stp.tp2)

suspensions foreach revive

sameTypes
case _ => case _ =>
false false
} }
Expand Down

0 comments on commit 1b198fa

Please sign in to comment.