Skip to content

Commit 6339276

Browse files
committed
Fix installAfter corner case
There was a corner case in installAfter where - A denotation valid in a single phase got replaced by another one - Immediately after, the symbol's denotation would be forced in a previous phase This somehow landed on a wrong denotation. The problem got apparent when more symbols underwent a Recheck.updateInfoBetween. The flags field installed by a previous update somehow was not recognized anymore. Specifically, the following was observed in order: 1. For a parameter getter (xs in LazyList, file pos-custeom-args/captures/lazylists1.scala) the Private flag was suppressed via transformInfo at phase cc. 2. The denotation of the getter v which was valid in the single phase cc+1 was updated at at cc by updateInfoInBetween in Recheck so that the Private flag was re-asserted in cc+1. 3. Immediately afterwards, the getter's flags was demanded at phase cc. 4. The Private flag was present, even though it should not be. The problem was fixed by demanding the denotation of the getter as part of isntallAfter.
1 parent 8205ae9 commit 6339276

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -884,24 +884,28 @@ object Denotations {
884884
/** Install this denotation to be the result of the given denotation transformer.
885885
* This is the implementation of the same-named method in SymDenotations.
886886
* It's placed here because it needs access to private fields of SingleDenotation.
887-
* @pre Can only be called in `phase.next`.
888887
*/
889888
protected def installAfter(phase: DenotTransformer)(using Context): Unit = {
890889
val targetId = phase.next.id
891890
if (ctx.phaseId != targetId) atPhase(phase.next)(installAfter(phase))
892891
else {
893892
val current = symbol.current
894893
// println(s"installing $this after $phase/${phase.id}, valid = ${current.validFor}")
895-
// printPeriods(current)
894+
// println(current.definedPeriodsString)
896895
this.validFor = Period(ctx.runId, targetId, current.validFor.lastPhaseId)
897896
if (current.validFor.firstPhaseId >= targetId)
898897
current.replaceWith(this)
898+
symbol.denot
899+
// Let symbol point to updated denotation
900+
// Without this we can get problems when we immediately recompute the denotation
901+
// at another phase since the invariant that symbol used to point to a valid
902+
// denotation is lost.
899903
else {
900904
current.validFor = Period(ctx.runId, current.validFor.firstPhaseId, targetId - 1)
901905
insertAfter(current)
902906
}
907+
// println(current.definedPeriodsString)
903908
}
904-
// printPeriods(this)
905909
}
906910

907911
/** Apply a transformation `f` to all denotations in this group that start at or after

0 commit comments

Comments
 (0)