Skip to content

Commit 0676e5a

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 5aa5c1f commit 0676e5a

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
@@ -359,6 +359,8 @@ object Contexts {
359359
final def runId = period.runId
360360
final def phaseId = period.phaseId
361361

362+
final def lastPhaseId = base.phases.length - 1
363+
362364
/** Does current phase use an erased types interpretation? */
363365
final def erasedTypes = phase.erasedTypes
364366

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
@@ -2347,8 +2347,11 @@ object SymDenotations {
23472347
if (denot.isOneOf(ValidForeverFlags) || denot.isRefinementClass || denot.isImport) true
23482348
else {
23492349
val initial = denot.initial
2350-
val firstPhaseId = initial.validFor.firstPhaseId.max(typerPhase.id)
2351-
if ((initial ne denot) || ctx.phaseId != firstPhaseId)
2350+
val firstPhaseId =
2351+
initial.validFor.firstPhaseId.max(typerPhase.id)
2352+
if firstPhaseId > ctx.lastPhaseId then
2353+
false
2354+
else if (initial ne denot) || ctx.phaseId != firstPhaseId then
23522355
atPhase(firstPhaseId)(stillValidInOwner(initial))
23532356
else
23542357
stillValidInOwner(denot)

0 commit comments

Comments
 (0)