diff options
author | Guillaume Martres <smarter@ubuntu.com> | 2016-10-26 17:06:10 +0200 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2016-10-26 17:14:59 +0200 |
commit | 03b6a47f72da3229e80c7e67495cc73611aae0c9 (patch) | |
tree | 604b7370f2f81062f357a4116021031e00138503 | |
parent | 557d448c626dd3fc93943523e6e28cf04288d848 (diff) | |
download | dotty-03b6a47f72da3229e80c7e67495cc73611aae0c9.tar.gz dotty-03b6a47f72da3229e80c7e67495cc73611aae0c9.tar.bz2 dotty-03b6a47f72da3229e80c7e67495cc73611aae0c9.zip |
Avoid calling unsupported computeHash in some situations
Some types do not implement `computeHash`, instead they override
`myHash` directly. This works fine as long as `myHash` is not equal to
`HashUnknown` but this was not guaranteed before this commit, if
`myHash` is equal to `HashUnknown` then `computeHash` is called by
`CachedGroundType#hash` or `CachedProxyType#hash` causing an exception:
https://gist.github.com/smarter/6b642db0495e995d8f3c26d614cf54d6
This commit fixes this by making sure we never compute a hash equal to
`HashUnknown`, instead `HashUnknownAlt` should be used.
-rw-r--r-- | src/dotty/tools/dotc/core/Hashable.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 4 |
2 files changed, 9 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/core/Hashable.scala b/src/dotty/tools/dotc/core/Hashable.scala index 12a408fbd..e4510c53e 100644 --- a/src/dotty/tools/dotc/core/Hashable.scala +++ b/src/dotty/tools/dotc/core/Hashable.scala @@ -31,9 +31,9 @@ trait Hashable { protected def hashSeed: Int = getClass.hashCode protected final def finishHash(hashCode: Int, arity: Int): Int = - avoidNotCached(hashing.finalizeHash(hashCode, arity)) + avoidSpecialHashes(hashing.finalizeHash(hashCode, arity)) - final def identityHash = avoidNotCached(System.identityHashCode(this)) + final def identityHash = avoidSpecialHashes(System.identityHashCode(this)) protected def finishHash(seed: Int, arity: Int, tp: Type): Int = { val elemHash = tp.hash @@ -94,7 +94,10 @@ trait Hashable { protected final def addDelta(elemHash: Int, delta: Int) = if (elemHash == NotCached) NotCached - else avoidNotCached(elemHash + delta) + else avoidSpecialHashes(elemHash + delta) - private def avoidNotCached(h: Int) = if (h == NotCached) NotCachedAlt else h + private def avoidSpecialHashes(h: Int) = + if (h == NotCached) NotCachedAlt + else if (h == HashUnknown) HashUnknownAlt + else h } diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 38913a7d0..f4d712db3 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1278,7 +1278,7 @@ object Types { final def hash = { if (myHash == HashUnknown) { myHash = computeHash - if (myHash == HashUnknown) myHash = HashUnknownAlt + assert(myHash != HashUnknown) } myHash } @@ -1293,7 +1293,7 @@ object Types { final def hash = { if (myHash == HashUnknown) { myHash = computeHash - if (myHash == HashUnknown) myHash = HashUnknownAlt + assert(myHash != HashUnknown) } myHash } |