aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2015-11-04 12:06:34 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-11-04 12:16:06 +0100
commit0f5c1fd17c2acc23c3735dd4d8d3748e9eeef444 (patch)
treece4d811bb3a19e315f24d2ab29a3c53eb5014c58 /src/dotty/tools/dotc/core/Types.scala
parent4e86a9dd62560381a6caf960470ea5e4db636fff (diff)
downloaddotty-0f5c1fd17c2acc23c3735dd4d8d3748e9eeef444.tar.gz
dotty-0f5c1fd17c2acc23c3735dd4d8d3748e9eeef444.tar.bz2
dotty-0f5c1fd17c2acc23c3735dd4d8d3748e9eeef444.zip
Add stable hash codes to PolyParams.
Helps me a lot in linker.
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala24
1 files changed, 20 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 3fe5afb33..3b9bcd56d 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -33,6 +33,7 @@ import annotation.tailrec
import Flags.FlagSet
import typer.Mode
import language.implicitConversions
+import scala.util.hashing.{ MurmurHash3 => hashing }
object Types {
@@ -2249,12 +2250,14 @@ object Types {
}
}
- case class PolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
+ abstract case class PolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
extends CachedGroundType with BindingType with TermType with MethodOrPoly {
val paramBounds = paramBoundsExp(this)
val resType = resultTypeExp(this)
+ assert(resType ne null)
+
override def resultType(implicit ctx: Context) = resType
protected def computeSignature(implicit ctx: Context) = resultSignature
@@ -2276,13 +2279,26 @@ object Types {
// need to override hashCode and equals to be object identity
// because paramNames by itself is not discriminatory enough
- override def equals(other: Any) = this eq other.asInstanceOf[AnyRef]
- override def computeHash = identityHash
+ override def equals(other: Any) = other match {
+ case other: PolyType =>
+ other.paramNames == this.paramNames && other.paramBounds == this.paramBounds && other.resType == this.resType
+ case _ => false
+ }
+ override def computeHash = {
+ doHash(paramNames, resType, paramBounds)
+ }
override def toString = s"PolyType($paramNames, $paramBounds, $resType)"
}
+ class CachedPolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
+ extends PolyType(paramNames)(paramBoundsExp, resultTypeExp)
+
object PolyType {
+ def apply(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)(implicit ctx: Context): PolyType = {
+ unique(new CachedPolyType(paramNames)(paramBoundsExp, resultTypeExp))
+ }
+
def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context) =
if (tparams.isEmpty) resultType
else {
@@ -2358,7 +2374,7 @@ object Types {
// no customized hashCode/equals needed because cycle is broken in PolyType
override def toString = s"PolyParam(${binder.paramNames(paramNum)})"
- override def computeHash = doHash(paramNum, binder)
+ override def computeHash = finishHash(hashing.mix(hashing.mix(hashSeed, paramNum), binder.identityHash), 1)
override def equals(that: Any) = that match {
case that: PolyParam =>
(this.binder eq that.binder) && this.paramNum == that.paramNum