@@ -22,14 +22,18 @@ object Potentials {
2222
2323 /** A potential represents an aliasing of a value that is possibly under initialization */
2424 sealed trait Potential {
25- def size : Int
25+ /** Length of the potential. Used for widening */
26+ def size : Int = 1
27+
28+ /** Nested levels of the potential. Used for widening */
29+ def level : Int = 1
30+
2631 def show (using Context ): String
2732 def source : Tree
2833 }
2934
3035 /** The object pointed by `this` */
3136 case class ThisRef ()(val source : Tree ) extends Potential {
32- val size : Int = 1
3337 def show (using Context ): String = " this"
3438
3539 /** Effects of a method call or a lazy val access
@@ -49,7 +53,8 @@ object Potentials {
4953
5054 /** The object pointed by `C.super.this`, mainly used for override resolution */
5155 case class SuperRef (pot : Potential , supercls : ClassSymbol )(val source : Tree ) extends Potential {
52- val size : Int = 1
56+ override def size : Int = pot.size
57+ override def level : Int = pot.level
5358 def show (using Context ): String = pot.show + " .super[" + supercls.name.show + " ]"
5459 }
5560
@@ -60,7 +65,7 @@ object Potentials {
6065 * @param outer The potential for `this` of the enclosing class
6166 */
6267 case class Warm (classSymbol : ClassSymbol , outer : Potential )(val source : Tree ) extends Potential {
63- def size : Int = 1
68+ override def level : Int = 1 + outer.level
6469 def show (using Context ): String = " Warm[" + classSymbol.show + " , outer = " + outer.show + " ]"
6570
6671 /** Effects of a method call or a lazy val access
@@ -111,35 +116,44 @@ object Potentials {
111116 */
112117 case class Outer (pot : Potential , classSymbol : ClassSymbol )(val source : Tree ) extends Potential {
113118 // be lenient with size of outer selection, no worry for non-termination
114- def size : Int = pot.size
119+ override def size : Int = pot.size
120+ override def level : Int = pot.size
115121 def show (using Context ): String = pot.show + " .outer[" + classSymbol.show + " ]"
116122 }
117123
118124 /** The object pointed by `this.f` */
119125 case class FieldReturn (potential : Potential , field : Symbol )(val source : Tree ) extends Potential {
120126 assert(field != NoSymbol )
121127
122- def size : Int = potential.size + 1
128+ override def size : Int = potential.size + 1
129+ override def level : Int = potential.size
123130 def show (using Context ): String = potential.show + " ." + field.name.show
124131 }
125132
126133 /** The object returned by `this.m()` */
127134 case class MethodReturn (potential : Potential , method : Symbol )(val source : Tree ) extends Potential {
128135 assert(method != NoSymbol )
129136
130- def size : Int = potential.size + 1
137+ override def size : Int = potential.size + 1
138+ override def level : Int = potential.size
131139 def show (using Context ): String = potential.show + " ." + method.name.show
132140 }
133141
134142 /** The object whose initialization status is unknown */
135143 case class Cold ()(val source : Tree ) extends Potential {
136- def size : Int = 1
137144 def show (using Context ): String = " Cold"
138145 }
139146
140147 /** A function when called will produce the `effects` and return the `potentials` */
141148 case class Fun (potentials : Potentials , effects : Effects )(val source : Tree ) extends Potential {
142- def size : Int = 1
149+ override def size : Int = 1
150+
151+ override def level : Int = {
152+ val max1 = potentials.map(_.level).max
153+ val max2 = effects.map(_.potential.level).max
154+ if max1 > max2 then max1 else max2
155+ }
156+
143157 def show (using Context ): String =
144158 " Fun[pots = " + potentials.map(_.show).mkString(" ;" ) + " , effs = " + effects.map(_.show).mkString(" ;" ) + " ]"
145159 }
@@ -192,8 +206,11 @@ object Potentials {
192206 case Warm (cls, outer2) =>
193207 // widening to terminate
194208 val thisValue2 = thisValue match {
195- case Warm (cls, outer) => Warm (cls, Cold ()(outer2.source))(thisValue.source)
196- case _ => thisValue
209+ case Warm (cls, outer) if outer.level > 2 =>
210+ Warm (cls, Cold ()(outer2.source))(thisValue.source)
211+
212+ case _ =>
213+ thisValue
197214 }
198215
199216 val outer3 = asSeenFrom(outer2, thisValue2)
0 commit comments