Skip to content

Commit 368bc2e

Browse files
committed
Be more aggressive invalidating baseTypeRef caches
We might get a wrong baseTypeRef cache when basetypes get populated while parent type infos of a class are not yet installed. So at the end of initializing a class type in namer, we should invalidate the caches of all its base types. Without the fix, BitSet in the collection strawman fails to compile.
1 parent cd492c7 commit 368bc2e

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

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

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,12 +1381,15 @@ object SymDenotations {
13811381
/** Invalidate baseTypeRefCache, baseClasses and superClassBits on new run */
13821382
private def checkBasesUpToDate()(implicit ctx: Context) =
13831383
if (baseTypeRefValid != ctx.runId) {
1384-
baseTypeRefCache = new java.util.HashMap[CachedType, Type]
1384+
invalidateBaseTypeRefCache()
13851385
myBaseClasses = null
13861386
mySuperClassBits = null
13871387
baseTypeRefValid = ctx.runId
13881388
}
13891389

1390+
def invalidateBaseTypeRefCache() =
1391+
baseTypeRefCache = new java.util.HashMap[CachedType, Type]
1392+
13901393
private def computeBases(implicit ctx: Context): (List[ClassSymbol], BitSet) = {
13911394
if (myBaseClasses eq Nil) throw CyclicReference(this)
13921395
myBaseClasses = Nil
@@ -1712,18 +1715,23 @@ object SymDenotations {
17121715
/*>|>*/ ctx.debugTraceIndented(s"$tp.baseTypeRef($this)") /*<|<*/ {
17131716
tp match {
17141717
case tp: CachedType =>
1715-
checkBasesUpToDate()
1716-
var basetp = baseTypeRefCache get tp
1717-
if (basetp == null) {
1718-
baseTypeRefCache.put(tp, NoPrefix)
1719-
basetp = computeBaseTypeRefOf(tp)
1720-
if (isCachable(tp)) baseTypeRefCache.put(tp, basetp)
1721-
else baseTypeRefCache.remove(tp)
1722-
} else if (basetp == NoPrefix) {
1723-
baseTypeRefCache.put(tp, null)
1724-
throw CyclicReference(this)
1718+
try {
1719+
checkBasesUpToDate()
1720+
var basetp = baseTypeRefCache get tp
1721+
if (basetp == null) {
1722+
baseTypeRefCache.put(tp, NoPrefix)
1723+
basetp = computeBaseTypeRefOf(tp)
1724+
if (isCachable(tp)) baseTypeRefCache.put(tp, basetp)
1725+
else baseTypeRefCache.remove(tp)
1726+
} else if (basetp == NoPrefix)
1727+
throw CyclicReference(this)
1728+
basetp
1729+
}
1730+
catch {
1731+
case ex: Throwable =>
1732+
baseTypeRefCache.put(tp, null)
1733+
throw ex
17251734
}
1726-
basetp
17271735
case _ =>
17281736
computeBaseTypeRefOf(tp)
17291737
}

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,7 @@ class Namer { typer: Typer =>
915915
Checking.checkWellFormed(cls)
916916
if (isDerivedValueClass(cls)) cls.setFlag(Final)
917917
cls.info = avoidPrivateLeaks(cls, cls.pos)
918+
cls.baseClasses.foreach(_.invalidateBaseTypeRefCache)
918919
}
919920
}
920921

0 commit comments

Comments
 (0)