diff options
author | Martin Odersky <odersky@gmail.com> | 2014-09-23 15:42:55 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-10-11 08:24:36 +0200 |
commit | 5289a3719c0767c1874ff1e34b825ccf3b314257 (patch) | |
tree | ef36b0fa142d70af41fd6daa77621e3020374dad /src/dotty/tools/dotc/core/SymDenotations.scala | |
parent | a64e0a2fc8883e5a6358a04d706eb72e896f67c6 (diff) | |
download | dotty-5289a3719c0767c1874ff1e34b825ccf3b314257.tar.gz dotty-5289a3719c0767c1874ff1e34b825ccf3b314257.tar.bz2 dotty-5289a3719c0767c1874ff1e34b825ccf3b314257.zip |
Fix caching logic in baseTypeRef
Typevars can be parts of larger types or underlying types of
other types, which renders these other types uncacheable. The new
logic takes account of that.
Diffstat (limited to 'src/dotty/tools/dotc/core/SymDenotations.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 556112114..711a76ad5 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1317,6 +1317,18 @@ object SymDenotations { case _ => bt } + def inCache(tp: Type) = baseTypeRefCache.containsKey(tp) + + /** Can't cache types containing type variables which are uninstantiated + * or whose instances can change, depending on typerstate. + */ + def isCachable(tp: Type): Boolean = tp match { + case tp: TypeProxy => inCache(tp.underlying) + case tp: AndOrType => inCache(tp.tp1) && inCache(tp.tp2) + case tp: TypeVar => tp.inst.exists && inCache(tp.inst) + case _ => true + } + def computeBaseTypeRefOf(tp: Type): Type = { Stats.record("computeBaseTypeOf") if (symbol.isStatic && tp.derivesFrom(symbol)) @@ -1333,9 +1345,6 @@ object SymDenotations { case _ => baseTypeRefOf(tp.underlying) } - case tp: TypeVar => - if (tp.inst.exists) computeBaseTypeRefOf(tp.inst) - else Uncachable(computeBaseTypeRefOf(tp.underlying)) case tp: TypeProxy => baseTypeRefOf(tp.underlying) case AndType(tp1, tp2) => @@ -1356,15 +1365,9 @@ object SymDenotations { var basetp = baseTypeRefCache get tp if (basetp == null) { baseTypeRefCache.put(tp, NoPrefix) - val computedBT = computeBaseTypeRefOf(tp) - basetp = computedBT match { - case Uncachable(basetp) => - baseTypeRefCache.remove(tp) - computedBT - case basetp => - baseTypeRefCache.put(tp, basetp) - basetp - } + basetp = computeBaseTypeRefOf(tp) + if (isCachable(tp)) baseTypeRefCache.put(tp, basetp) + else baseTypeRefCache.remove(tp) } else if (basetp == NoPrefix) { throw CyclicReference(this) } @@ -1444,8 +1447,7 @@ object SymDenotations { copySymDenotation(info = ClassInfo(pre, classSymbol, ps, decls.cloneScope, selfInfo)) .installAfter(phase) } - } - private case class Uncachable(tp: Type) extends UncachedGroundType + } /** The denotation of a package class. * It overrides ClassDenotation to take account of package objects when looking for members |