From 7ada2642d53b745b6efbe50aa37bae13d18ccbce Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Tue, 30 Oct 2018 16:04:16 +0100 Subject: [PATCH 1/2] Fix #5333: Invalid entries in the baseType cache Provisional types should not have their baseType cached, it may change as type variables get refined and instantiated. The seqtype-cycle test had to be adjusted to avoid some missing reference errors, probably due to the completion order changing. --- compiler/src/dotty/tools/dotc/core/SymDenotations.scala | 7 ++++--- tests/pos/seqtype-cycle/Test2.scala | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index c593fa17333d..cdb632fb6da8 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1631,7 +1631,10 @@ object SymDenotations { Stats.record("basetype cache entries") if (!baseTp.exists) Stats.record("basetype cache NoTypes") } - btrCache.put(tp, baseTp) + if (!tp.isProvisional) + btrCache.put(tp, baseTp) + else + btrCache.remove(tp) // Remove any potential sentinel value } def ensureAcyclic(baseTp: Type) = { @@ -1717,8 +1720,6 @@ object SymDenotations { val baseTp = recur(superTp) tp match { case tp: CachedType if baseTp.exists && inCache(superTp) => - // Note: This also works for TypeVars: If they are not instantiated, their supertype - // is a TypeParamRef, which is never cached. So uninstantiated TypeVars are not cached either. record(tp, baseTp) case _ => } diff --git a/tests/pos/seqtype-cycle/Test2.scala b/tests/pos/seqtype-cycle/Test2.scala index cd52cb26864e..30e1e9157a00 100644 --- a/tests/pos/seqtype-cycle/Test2.scala +++ b/tests/pos/seqtype-cycle/Test2.scala @@ -2,6 +2,8 @@ package object scala { // needed for some reasons type Throwable = java.lang.Throwable type IndexOutOfBoundsException = java.lang.IndexOutOfBoundsException + type List[+A] = scala.collection.immutable.List[A] + type Iterable[+A] = scala.collection.Iterable[A] type Seq[A] = scala.collection.Seq[A] val Seq = scala.collection.Seq From ed76b73d6a916f48f1ace45a451e817d6c6434ee Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Wed, 31 Oct 2018 13:49:03 +0100 Subject: [PATCH 2/2] Try caching baseType for term-owned typerefs too --- compiler/src/dotty/tools/dotc/core/SymDenotations.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index cdb632fb6da8..5b96b5b41c2d 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1685,8 +1685,8 @@ object SymDenotations { case _ => val superTp = tp.superType val baseTp = recur(superTp) - if (inCache(superTp) && tp.symbol.maybeOwner.isType) - record(tp, baseTp) // typeref cannot be a GADT, so cache is stable + if (inCache(superTp)) + record(tp, baseTp) else btrCache.remove(tp) baseTp