@@ -161,7 +161,7 @@ object Types {
161
161
* Rationale: If an expression has a stable type, the expression must be idempotent, so stable types
162
162
* must be singleton types of stable expressions. */
163
163
final def isStable (using Context ): Boolean = stripTypeVar match {
164
- case tp : TermRef => tp.symbol.isStableMember && tp.prefix.isStable || tp.info.isStable
164
+ case tp : TermRef => tp.cachedIsStable
165
165
case _ : SingletonType | NoPrefix => true
166
166
case tp : RefinedOrRecType => tp.parent.isStable
167
167
case tp : ExprType => tp.resultType.isStable
@@ -175,7 +175,7 @@ object Types {
175
175
// see: tests/explicit-nulls/pos/flow-stable.scala.disabled
176
176
tp.tp1.isStable && (realizability(tp.tp2) eq Realizable ) ||
177
177
tp.tp2.isStable && (realizability(tp.tp1) eq Realizable )
178
- case tp : AppliedType => tp.appliedTypeIsStable
178
+ case tp : AppliedType => tp.cachedIsStable
179
179
case _ => false
180
180
}
181
181
@@ -2665,6 +2665,19 @@ object Types {
2665
2665
override def designator : Designator = myDesignator
2666
2666
override protected def designator_= (d : Designator ): Unit = myDesignator = d
2667
2667
2668
+ var myIsStablePeriod : Period = Nowhere
2669
+ var myIsStable : Boolean = false
2670
+
2671
+ inline def cachedIsStable (using Context ): Boolean =
2672
+ if myIsStablePeriod != ctx.period then
2673
+ val isStable : Boolean = symbol.isStableMember && prefix.isStable || info.isStable
2674
+ if ! isProvisional then
2675
+ myIsStablePeriod = ctx.period
2676
+ myIsStable = isStable
2677
+ isStable
2678
+ else
2679
+ myIsStable
2680
+
2668
2681
// assert(name.toString != "<local Coder>")
2669
2682
override def underlying (using Context ): Type = {
2670
2683
val d = denot
@@ -4163,12 +4176,11 @@ object Types {
4163
4176
private var myGround : Byte = 0
4164
4177
private var myIsStable : Byte = 0
4165
4178
4166
-
4167
4179
def isGround (acc : TypeAccumulator [Boolean ])(using Context ): Boolean =
4168
4180
if myGround == 0 then myGround = if acc.foldOver(true , this ) then 1 else - 1
4169
4181
myGround > 0
4170
4182
4171
- inline def appliedTypeIsStable (using Context ): Boolean =
4183
+ inline def cachedIsStable (using Context ): Boolean =
4172
4184
if myIsStable == 0 then
4173
4185
val isStable : Byte = tycon match
4174
4186
case tycon : TypeRef if defn.isCompiletimeAppliedType(tycon.symbol) && args.forall(_.isStable) => 1
0 commit comments