@@ -1079,17 +1079,13 @@ object Types {
1079
1079
* @param checkClassInfo if true we check that ClassInfos are within bounds of abstract types
1080
1080
*/
1081
1081
final def overrides (that : Type , relaxedCheck : Boolean , matchLoosely : => Boolean , checkClassInfo : Boolean = true )(using Context ): Boolean = {
1082
- def widenNullary (tp : Type ) = tp match {
1083
- case tp @ MethodType (Nil ) => tp.resultType
1084
- case _ => tp
1085
- }
1086
1082
val overrideCtx = if relaxedCheck then ctx.relaxedOverrideContext else ctx
1087
1083
inContext(overrideCtx) {
1088
1084
! checkClassInfo && this .isInstanceOf [ClassInfo ]
1089
1085
|| (this .widenExpr frozen_<:< that.widenExpr)
1090
1086
|| matchLoosely && {
1091
- val this1 = widenNullary( this )
1092
- val that1 = widenNullary( that)
1087
+ val this1 = this .widenNullaryMethod
1088
+ val that1 = that.widenNullaryMethod
1093
1089
((this1 `ne` this ) || (that1 `ne` that)) && this1.overrides(that1, relaxedCheck, false , checkClassInfo)
1094
1090
}
1095
1091
}
@@ -1326,6 +1322,11 @@ object Types {
1326
1322
this
1327
1323
}
1328
1324
1325
+ /** If this is a nullary method type, its result type */
1326
+ def widenNullaryMethod (using Context ): Type = this match
1327
+ case tp @ MethodType (Nil ) => tp.resType
1328
+ case _ => this
1329
+
1329
1330
/** The singleton types that must or may be in this type. @see Atoms.
1330
1331
* Overridden and cached in OrType.
1331
1332
*/
@@ -2561,7 +2562,7 @@ object Types {
2561
2562
* A test case is neg/opaque-self-encoding.scala.
2562
2563
*/
2563
2564
final def withDenot (denot : Denotation )(using Context ): ThisType =
2564
- if ( denot.exists) {
2565
+ if denot.exists then
2565
2566
val adapted = withSym(denot.symbol)
2566
2567
val result =
2567
2568
if (adapted.eq(this )
@@ -2570,9 +2571,25 @@ object Types {
2570
2571
|| adapted.info.eq(denot.info))
2571
2572
adapted
2572
2573
else this
2573
- result.setDenot(denot)
2574
+ val lastDenot = result.lastDenotation
2575
+ denot match
2576
+ case denot : SymDenotation
2577
+ if denot.validFor.firstPhaseId < ctx.phase.id
2578
+ && lastDenot != null
2579
+ && lastDenot.validFor.lastPhaseId > denot.validFor.firstPhaseId
2580
+ && ! lastDenot.isInstanceOf [SymDenotation ] =>
2581
+ // In this case the new SymDenotation might be valid for all phases, which means
2582
+ // we would not recompute the denotation when travelling to an earlier phase, maybe
2583
+ // in the next run. We fix that problem by creating a UniqueRefDenotation instead.
2584
+ core.println(i " overwrite ${result.toString} / ${result.lastDenotation}, ${result.lastDenotation.getClass} with $denot at ${ctx.phaseId}" )
2585
+ result.setDenot(
2586
+ UniqueRefDenotation (
2587
+ denot.symbol, denot.info,
2588
+ Period (ctx.runId, ctx.phaseId, denot.validFor.lastPhaseId),
2589
+ this .prefix))
2590
+ case _ =>
2591
+ result.setDenot(denot)
2574
2592
result.asInstanceOf [ThisType ]
2575
- }
2576
2593
else // don't assign NoDenotation, we might need to recover later. Test case is pos/avoid.scala.
2577
2594
this
2578
2595
0 commit comments