diff --git a/compiler/src/dotty/tools/dotc/core/DenotTransformers.scala b/compiler/src/dotty/tools/dotc/core/DenotTransformers.scala index 4b08c9442102..6690cae3a142 100644 --- a/compiler/src/dotty/tools/dotc/core/DenotTransformers.scala +++ b/compiler/src/dotty/tools/dotc/core/DenotTransformers.scala @@ -37,7 +37,7 @@ object DenotTransformers { def transform(ref: SingleDenotation)(using Context): SingleDenotation = { val sym = ref.symbol - if (sym.exists && !mayChange(sym)) ref + if (sym.exists && !infoMayChange(sym)) ref else { val info1 = transformInfo(ref.info, ref.symbol) if (info1 eq ref.info) ref @@ -50,11 +50,11 @@ object DenotTransformers { } } - /** Denotations with a symbol where `mayChange` is false are guaranteed to be + /** Denotations with a symbol where `infoMayChange` is false are guaranteed to be * unaffected by this transform, so `transformInfo` need not be run. This * can save time, and more importantly, can help avoid forcing symbol completers. */ - protected def mayChange(sym: Symbol)(using Context): Boolean = true + protected def infoMayChange(sym: Symbol)(using Context): Boolean = true } /** A transformer that only transforms SymDenotations. diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 37c337de08c0..fcfe30561c6d 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -2641,7 +2641,11 @@ object SymDenotations { private var locked = false private var provisional = false - final def isValid(using Context): Boolean = valid && isValidAt(ctx.phase) + final def isValid(using Context): Boolean = + valid && createdAt.runId == ctx.runId + // Note: We rely on the fact that whenever base types of classes change, + // the affected classes will get new denotations with new basedata caches. + // So basedata caches can become invalid only if the run changes. def invalidate(): Unit = if (valid && !locked) { diff --git a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala index bdc57529d2ce..aeed5ac76d39 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala @@ -72,7 +72,7 @@ class ElimByName extends TransformByNameApply with InfoTransformer { case _ => tp } - override def mayChange(sym: Symbol)(using Context): Boolean = sym.isTerm && exprBecomesFunction(sym) + override def infoMayChange(sym: Symbol)(using Context): Boolean = sym.isTerm && exprBecomesFunction(sym) } object ElimByName { diff --git a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala index 9fc0b7b53c0e..d94b42d6764e 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala @@ -73,7 +73,7 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase => case ref1 => ref1 - override def mayChange(sym: Symbol)(using Context): Boolean = sym.is(Method) + override def infoMayChange(sym: Symbol)(using Context): Boolean = sym.is(Method) private def overridesJava(sym: Symbol)(using Context) = sym.allOverriddenSymbols.exists(_.is(JavaDefined)) diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index 202747b5739e..5516346dc09f 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -90,16 +90,17 @@ class Erasure extends Phase with DenotTransformer { newFlags = newFlags &~ Flags.Inline newAnnotations = newAnnotations.filterConserve(!_.isInstanceOf[BodyAnnotation]) // TODO: define derivedSymDenotation? - if (oldSymbol eq newSymbol) - && (oldOwner eq newOwner) - && (oldName eq newName) - && (oldInfo eq newInfo) - && (oldFlags == newFlags) - && (oldAnnotations eq newAnnotations) + if ref.is(Flags.PackageClass) + || !ref.isClass // non-package classes are always copied since their base types change + && (oldSymbol eq newSymbol) + && (oldOwner eq newOwner) + && (oldName eq newName) + && (oldInfo eq newInfo) + && (oldFlags == newFlags) + && (oldAnnotations eq newAnnotations) then ref else - assert(!ref.is(Flags.PackageClass), s"trans $ref @ ${ctx.phase} oldOwner = $oldOwner, newOwner = $newOwner, oldInfo = $oldInfo, newInfo = $newInfo ${oldOwner eq newOwner} ${oldInfo eq newInfo}") ref.copySymDenotation( symbol = newSymbol, owner = newOwner, diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 3d351eb03a67..3be0ac6fbbdf 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -57,7 +57,7 @@ class ExplicitOuter extends MiniPhase with InfoTransformer { thisPhase => tp } - override def mayChange(sym: Symbol)(using Context): Boolean = sym.isClass && !sym.is(JavaDefined) + override def infoMayChange(sym: Symbol)(using Context): Boolean = sym.isClass && !sym.is(JavaDefined) /** First, add outer accessors if a class does not have them yet and it references an outer this. * If the class has outer accessors, implement them. diff --git a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala index 085fea1a2d0b..643f62933629 100644 --- a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala +++ b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala @@ -46,7 +46,7 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase => tp } - override protected def mayChange(sym: Symbol)(using Context): Boolean = sym.isClass + override protected def infoMayChange(sym: Symbol)(using Context): Boolean = sym.isClass override def checkPostCondition(tree: Tree)(using Context): Unit = tree match {