Skip to content

Commit e9b7054

Browse files
committed
Don't bring symbols forward to non-existing phases.
This was observed in TabCompleterTests. The problem in general is that we might see symbols in runs that have fewer phases than the phase at which the symbol was created. Previously, we updated the symbol anyway. But this is problematic since it means the symbol has a validity period that does not correspond to a phase in the current run. We now treat those symbols as stale without a way to recover instead.
1 parent e2eb66a commit e9b7054

File tree

3 files changed

+12
-4
lines changed

3 files changed

+12
-4
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,8 @@ object Contexts {
343343
final def runId = period.runId
344344
final def phaseId = period.phaseId
345345

346+
final def lastPhaseId = base.phases.length - 1
347+
346348
/** Does current phase use an erased types interpretation? */
347349
final def erasedTypes = phase.erasedTypes
348350

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,10 @@ object Denotations {
716716
this match {
717717
case symd: SymDenotation =>
718718
if (stillValid(symd)) return updateValidity()
719-
if (acceptStale(symd)) return symd.currentSymbol.denot.orElse(symd).updateValidity()
719+
if acceptStale(symd) && symd.initial.validFor.firstPhaseId <= ctx.lastPhaseId then
720+
// New run might have fewer phases than old, so symbol might no longer be
721+
// visible at all. TabCompleteTests have examples where this happens.
722+
return symd.currentSymbol.denot.orElse(symd).updateValidity()
720723
case _ =>
721724
}
722725
if (!symbol.exists) return updateValidity()
@@ -790,7 +793,7 @@ object Denotations {
790793
//println(s"might need new denot for $cur, valid for ${cur.validFor} at $currentPeriod")
791794
// not found, cur points to highest existing variant
792795
val nextTransformerId = ctx.base.nextDenotTransformerId(cur.validFor.lastPhaseId)
793-
if (currentPeriod.lastPhaseId <= nextTransformerId)
796+
if currentPeriod.lastPhaseId <= nextTransformerId then
794797
cur.validFor = Period(currentPeriod.runId, cur.validFor.firstPhaseId, nextTransformerId)
795798
else
796799
var startPid = nextTransformerId + 1

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,8 +2351,11 @@ object SymDenotations {
23512351
if (denot.isOneOf(ValidForeverFlags) || denot.isRefinementClass || denot.isImport) true
23522352
else {
23532353
val initial = denot.initial
2354-
val firstPhaseId = initial.validFor.firstPhaseId.max(typerPhase.id)
2355-
if ((initial ne denot) || ctx.phaseId != firstPhaseId)
2354+
val firstPhaseId =
2355+
initial.validFor.firstPhaseId.max(typerPhase.id)
2356+
if firstPhaseId > ctx.lastPhaseId then
2357+
false
2358+
else if (initial ne denot) || ctx.phaseId != firstPhaseId then
23562359
atPhase(firstPhaseId)(stillValidInOwner(initial))
23572360
else
23582361
stillValidInOwner(denot)

0 commit comments

Comments
 (0)