@@ -2097,6 +2097,7 @@ object Types {
20972097 private var lastDenotation : Denotation | Null = null
20982098 private var lastSymbol : Symbol | Null = null
20992099 private var checkedPeriod : Period = Nowhere
2100+ private var firstValidPhaseId : Int = 0
21002101 private var myStableHash : Byte = 0
21012102 private var mySignature : Signature = _
21022103 private var mySignatureRunId : Int = NoRunId
@@ -2212,6 +2213,8 @@ object Types {
22122213 val now = ctx.period
22132214 // Even if checkedPeriod == now we still need to recheck lastDenotation.validFor
22142215 // as it may have been mutated by SymDenotation#installAfter
2216+ if firstValidPhaseId > now.phaseId then
2217+ revalidateDenot()
22152218 if (checkedPeriod != Nowhere && lastDenotation.nn.validFor.contains(now)) {
22162219 checkedPeriod = now
22172220 lastDenotation.nn
@@ -2340,6 +2343,18 @@ object Types {
23402343 def recomputeDenot ()(using Context ): Unit =
23412344 setDenot(memberDenot(name, allowPrivate = ! symbol.exists || symbol.is(Private )))
23422345
2346+ /** Try to recompute denotation and reset `firstValidPhaseId`.
2347+ * @pre Current phase id < firstValidPhaseId
2348+ */
2349+ def revalidateDenot ()(using Context ): Unit =
2350+ if (prefix ne NoPrefix ) then
2351+ core.println(i " revalidate $prefix . $name, $firstValidPhaseId > ${ctx.phaseId}" )
2352+ val newDenot = memberDenot(name, allowPrivate =
2353+ lastSymbol == null || ! lastSymbol.nn.exists || lastSymbol.nn.is(Private ))
2354+ if newDenot.exists then
2355+ setDenot(newDenot)
2356+ firstValidPhaseId = ctx.phaseId
2357+
23432358 private def setDenot (denot : Denotation )(using Context ): Unit = {
23442359 if (Config .checkNoDoubleBindings)
23452360 if (ctx.settings.YnoDoubleBindings .value)
@@ -2570,6 +2585,15 @@ object Types {
25702585 || adapted.info.eq(denot.info))
25712586 adapted
25722587 else this
2588+ val lastDenot = result.lastDenotation
2589+ if denot.isInstanceOf [SymDenotation ] && lastDenot != null && ! lastDenot.isInstanceOf [SymDenotation ] then
2590+ // In this case the new SymDenotation might be valid for all phases, which means
2591+ // we would not recompute the denotation when travelling to an earlier phase, maybe
2592+ // in the next run. We fix that problem by recording in this case in the NamedType
2593+ // the phase from which the denotation is valid. Taking the denotation at an earlier
2594+ // phase will then lead to a `revalidateDenot`.
2595+ core.println(i " overwrite ${result.toString} / ${result.lastDenotation} with $denot" )
2596+ result.firstValidPhaseId = ctx.phaseId
25732597 result.setDenot(denot)
25742598 result.asInstanceOf [ThisType ]
25752599 }
0 commit comments