Skip to content

Commit 0f5c1fd

Browse files
committed
Add stable hash codes to PolyParams.
Helps me a lot in linker.
1 parent 4e86a9d commit 0f5c1fd

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

src/dotty/tools/dotc/core/Types.scala

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import annotation.tailrec
3333
import Flags.FlagSet
3434
import typer.Mode
3535
import language.implicitConversions
36+
import scala.util.hashing.{ MurmurHash3 => hashing }
3637

3738
object Types {
3839

@@ -2249,12 +2250,14 @@ object Types {
22492250
}
22502251
}
22512252

2252-
case class PolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
2253+
abstract case class PolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
22532254
extends CachedGroundType with BindingType with TermType with MethodOrPoly {
22542255

22552256
val paramBounds = paramBoundsExp(this)
22562257
val resType = resultTypeExp(this)
22572258

2259+
assert(resType ne null)
2260+
22582261
override def resultType(implicit ctx: Context) = resType
22592262

22602263
protected def computeSignature(implicit ctx: Context) = resultSignature
@@ -2276,13 +2279,26 @@ object Types {
22762279

22772280
// need to override hashCode and equals to be object identity
22782281
// because paramNames by itself is not discriminatory enough
2279-
override def equals(other: Any) = this eq other.asInstanceOf[AnyRef]
2280-
override def computeHash = identityHash
2282+
override def equals(other: Any) = other match {
2283+
case other: PolyType =>
2284+
other.paramNames == this.paramNames && other.paramBounds == this.paramBounds && other.resType == this.resType
2285+
case _ => false
2286+
}
2287+
override def computeHash = {
2288+
doHash(paramNames, resType, paramBounds)
2289+
}
22812290

22822291
override def toString = s"PolyType($paramNames, $paramBounds, $resType)"
22832292
}
22842293

2294+
class CachedPolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
2295+
extends PolyType(paramNames)(paramBoundsExp, resultTypeExp)
2296+
22852297
object PolyType {
2298+
def apply(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)(implicit ctx: Context): PolyType = {
2299+
unique(new CachedPolyType(paramNames)(paramBoundsExp, resultTypeExp))
2300+
}
2301+
22862302
def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context) =
22872303
if (tparams.isEmpty) resultType
22882304
else {
@@ -2358,7 +2374,7 @@ object Types {
23582374
// no customized hashCode/equals needed because cycle is broken in PolyType
23592375
override def toString = s"PolyParam(${binder.paramNames(paramNum)})"
23602376

2361-
override def computeHash = doHash(paramNum, binder)
2377+
override def computeHash = finishHash(hashing.mix(hashing.mix(hashSeed, paramNum), binder.identityHash), 1)
23622378
override def equals(that: Any) = that match {
23632379
case that: PolyParam =>
23642380
(this.binder eq that.binder) && this.paramNum == that.paramNum

0 commit comments

Comments
 (0)