Skip to content

Commit a158137

Browse files
committed
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 16e3b14 commit a158137

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

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

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,18 @@ object SymDenotations {
13101310
case _ => bt
13111311
}
13121312

1313+
def inCache(tp: Type) = baseTypeRefCache.containsKey(tp)
1314+
1315+
/** Can't cache types containing type variables which are uninstantiated
1316+
* or whose instances can change, depending on typerstate.
1317+
*/
1318+
def isCachable(tp: Type): Boolean = tp match {
1319+
case tp: TypeProxy => inCache(tp.underlying)
1320+
case tp: AndOrType => inCache(tp.tp1) && inCache(tp.tp2)
1321+
case tp: TypeVar => tp.inst.exists && inCache(tp.inst)
1322+
case _ => true
1323+
}
1324+
13131325
def computeBaseTypeRefOf(tp: Type): Type = {
13141326
Stats.record("computeBaseTypeOf")
13151327
if (symbol.isStatic && tp.derivesFrom(symbol))
@@ -1326,9 +1338,6 @@ object SymDenotations {
13261338
case _ =>
13271339
baseTypeRefOf(tp.underlying)
13281340
}
1329-
case tp: TypeVar =>
1330-
if (tp.inst.exists) computeBaseTypeRefOf(tp.inst)
1331-
else Uncachable(computeBaseTypeRefOf(tp.underlying))
13321341
case tp: TypeProxy =>
13331342
baseTypeRefOf(tp.underlying)
13341343
case AndType(tp1, tp2) =>
@@ -1349,14 +1358,9 @@ object SymDenotations {
13491358
var basetp = baseTypeRefCache get tp
13501359
if (basetp == null) {
13511360
baseTypeRefCache.put(tp, NoPrefix)
1352-
basetp = computeBaseTypeRefOf(tp) match {
1353-
case Uncachable(basetp) =>
1354-
baseTypeRefCache.remove(tp)
1355-
basetp
1356-
case basetp =>
1357-
baseTypeRefCache.put(tp, basetp)
1358-
basetp
1359-
}
1361+
basetp = computeBaseTypeRefOf(tp)
1362+
if (isCachable(tp)) baseTypeRefCache.put(tp, basetp)
1363+
else baseTypeRefCache.remove(tp)
13601364
} else if (basetp == NoPrefix) {
13611365
throw CyclicReference(this)
13621366
}
@@ -1438,8 +1442,6 @@ object SymDenotations {
14381442
}
14391443
}
14401444

1441-
private case class Uncachable(tp: Type) extends UncachedGroundType
1442-
14431445
/** The denotation of a package class.
14441446
* It overrides ClassDenotation to take account of package objects when looking for members
14451447
*/

0 commit comments

Comments
 (0)