@@ -2097,6 +2097,7 @@ object Types {
2097
2097
private var lastDenotation : Denotation | Null = null
2098
2098
private var lastSymbol : Symbol | Null = null
2099
2099
private var checkedPeriod : Period = Nowhere
2100
+ private var firstValidPhaseId : Int = 0
2100
2101
private var myStableHash : Byte = 0
2101
2102
private var mySignature : Signature = _
2102
2103
private var mySignatureRunId : Int = NoRunId
@@ -2212,6 +2213,8 @@ object Types {
2212
2213
val now = ctx.period
2213
2214
// Even if checkedPeriod == now we still need to recheck lastDenotation.validFor
2214
2215
// as it may have been mutated by SymDenotation#installAfter
2216
+ if firstValidPhaseId > now.phaseId then
2217
+ revalidateDenot()
2215
2218
if (checkedPeriod != Nowhere && lastDenotation.nn.validFor.contains(now)) {
2216
2219
checkedPeriod = now
2217
2220
lastDenotation.nn
@@ -2340,6 +2343,18 @@ object Types {
2340
2343
def recomputeDenot ()(using Context ): Unit =
2341
2344
setDenot(memberDenot(name, allowPrivate = ! symbol.exists || symbol.is(Private )))
2342
2345
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
+
2343
2358
private def setDenot (denot : Denotation )(using Context ): Unit = {
2344
2359
if (Config .checkNoDoubleBindings)
2345
2360
if (ctx.settings.YnoDoubleBindings .value)
@@ -2570,6 +2585,15 @@ object Types {
2570
2585
|| adapted.info.eq(denot.info))
2571
2586
adapted
2572
2587
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
2573
2597
result.setDenot(denot)
2574
2598
result.asInstanceOf [ThisType ]
2575
2599
}
0 commit comments