Skip to content

Commit 5289a37

Browse files
oderskyDarkDimius
authored andcommitted
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.
1 parent a64e0a2 commit 5289a37

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

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

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,18 @@ object SymDenotations {
13171317
case _ => bt
13181318
}
13191319

1320+
def inCache(tp: Type) = baseTypeRefCache.containsKey(tp)
1321+
1322+
/** Can't cache types containing type variables which are uninstantiated
1323+
* or whose instances can change, depending on typerstate.
1324+
*/
1325+
def isCachable(tp: Type): Boolean = tp match {
1326+
case tp: TypeProxy => inCache(tp.underlying)
1327+
case tp: AndOrType => inCache(tp.tp1) && inCache(tp.tp2)
1328+
case tp: TypeVar => tp.inst.exists && inCache(tp.inst)
1329+
case _ => true
1330+
}
1331+
13201332
def computeBaseTypeRefOf(tp: Type): Type = {
13211333
Stats.record("computeBaseTypeOf")
13221334
if (symbol.isStatic && tp.derivesFrom(symbol))
@@ -1333,9 +1345,6 @@ object SymDenotations {
13331345
case _ =>
13341346
baseTypeRefOf(tp.underlying)
13351347
}
1336-
case tp: TypeVar =>
1337-
if (tp.inst.exists) computeBaseTypeRefOf(tp.inst)
1338-
else Uncachable(computeBaseTypeRefOf(tp.underlying))
13391348
case tp: TypeProxy =>
13401349
baseTypeRefOf(tp.underlying)
13411350
case AndType(tp1, tp2) =>
@@ -1356,15 +1365,9 @@ object SymDenotations {
13561365
var basetp = baseTypeRefCache get tp
13571366
if (basetp == null) {
13581367
baseTypeRefCache.put(tp, NoPrefix)
1359-
val computedBT = computeBaseTypeRefOf(tp)
1360-
basetp = computedBT match {
1361-
case Uncachable(basetp) =>
1362-
baseTypeRefCache.remove(tp)
1363-
computedBT
1364-
case basetp =>
1365-
baseTypeRefCache.put(tp, basetp)
1366-
basetp
1367-
}
1368+
basetp = computeBaseTypeRefOf(tp)
1369+
if (isCachable(tp)) baseTypeRefCache.put(tp, basetp)
1370+
else baseTypeRefCache.remove(tp)
13681371
} else if (basetp == NoPrefix) {
13691372
throw CyclicReference(this)
13701373
}
@@ -1444,8 +1447,7 @@ object SymDenotations {
14441447
copySymDenotation(info = ClassInfo(pre, classSymbol, ps, decls.cloneScope, selfInfo))
14451448
.installAfter(phase)
14461449
}
1447-
}
1448-
private case class Uncachable(tp: Type) extends UncachedGroundType
1450+
}
14491451

14501452
/** The denotation of a package class.
14511453
* It overrides ClassDenotation to take account of package objects when looking for members

0 commit comments

Comments
 (0)