@@ -55,6 +55,10 @@ object Semantic {
55
55
*/
56
56
sealed abstract class Value {
57
57
def show : String = this .toString()
58
+
59
+ def isHot = this == Hot
60
+ def isCold = this == Cold
61
+ def isWarm = this .isInstanceOf [Warm ]
58
62
}
59
63
60
64
/** A transitively initialized object */
@@ -99,9 +103,7 @@ object Semantic {
99
103
}
100
104
101
105
/** A reference to the object under initialization pointed by `this` */
102
- case class ThisRef (klass : ClassSymbol )(using @ constructorOnly h : Heap ) extends Ref {
103
- val outer = Hot
104
-
106
+ case class ThisRef (klass : ClassSymbol , outer : Value , ctor : Symbol , args : List [Value ])(using @ constructorOnly h : Heap ) extends Ref {
105
107
ensureObjectExists()
106
108
}
107
109
@@ -447,7 +449,7 @@ object Semantic {
447
449
def widenArgs : List [Value ] = values.map(_.widenArg).toList
448
450
449
451
extension (value : Value )
450
- def select (field : Symbol , source : Tree , needResolve : Boolean = true ): Contextual [Result ] = log(" select " + field.show, printer, (_ : Result ).show) {
452
+ def select (field : Symbol , source : Tree , needResolve : Boolean = true ): Contextual [Result ] = log(" select " + field.show + " , this = " + value , printer, (_ : Result ).show) {
451
453
if promoted.isCurrentObjectPromoted then Result (Hot , Nil )
452
454
else value match {
453
455
case Hot =>
@@ -613,6 +615,8 @@ object Semantic {
613
615
val warm = Warm (klass, outer, ctor, args2)
614
616
val argInfos2 = args.zip(args2).map { (argInfo, v) => argInfo.copy(value = v) }
615
617
val res = warm.callConstructor(ctor, argInfos2, source)
618
+ val task = ThisRef (klass, outer, ctor, args2)
619
+ this .addTask(task)
616
620
Result (warm, res.errors)
617
621
618
622
case Cold =>
@@ -630,6 +634,8 @@ object Semantic {
630
634
val argInfos2 = args.zip(argsWidened).map { (argInfo, v) => argInfo.copy(value = v) }
631
635
val warm = Warm (klass, outer, ctor, argsWidened)
632
636
val res = warm.callConstructor(ctor, argInfos2, source)
637
+ val task = ThisRef (klass, outer, ctor, argsWidened)
638
+ this .addTask(task)
633
639
Result (warm, res.errors)
634
640
635
641
case Fun (body, thisV, klass, env) =>
@@ -827,19 +833,22 @@ object Semantic {
827
833
cls == defn.ObjectClass
828
834
829
835
// ----- Work list ---------------------------------------------------
830
- type Task = ThisRef
836
+ case class Task ( value : ThisRef )( val trace : Trace )
831
837
832
838
class WorkList private [Semantic ]() {
833
839
private var pendingTasks : List [Task ] = Nil
840
+ private var checkedTasks : Set [Task ] = Set .empty
834
841
835
842
def addTask (task : Task ): Unit =
836
- pendingTasks = task :: pendingTasks
843
+ if ! checkedTasks.contains(task) then pendingTasks = task :: pendingTasks
837
844
838
845
/** Process the worklist until done */
839
846
@ tailrec
840
847
final def work ()(using State , Context ): Unit =
841
848
pendingTasks match
842
849
case task :: rest =>
850
+ checkedTasks = checkedTasks + task
851
+
843
852
val heapBefore = heap.snapshot()
844
853
val res = doTask(task)
845
854
res.errors.foreach(_.issue)
@@ -861,7 +870,7 @@ object Semantic {
861
870
* This method should only be called from the work list scheduler.
862
871
*/
863
872
private def doTask (task : Task )(using State , Context ): Result = log(" checking " + task) {
864
- val thisRef = task
873
+ val thisRef = task.value
865
874
val tpl = thisRef.klass.defTree.asInstanceOf [TypeDef ].rhs.asInstanceOf [Template ]
866
875
867
876
val paramValues = tpl.constr.termParamss.flatten.map(param => param.symbol -> Hot ).toMap
@@ -878,7 +887,7 @@ object Semantic {
878
887
// ----- API --------------------------------
879
888
880
889
/** Add a checking task to the work list */
881
- def addTask (task : ThisRef )(using WorkList ) = workList.addTask(task )
890
+ def addTask (thisRef : ThisRef )(using WorkList , Trace ) = workList.addTask(Task (thisRef)(trace) )
882
891
883
892
/** Perform check on the work list until it becomes empty
884
893
*
0 commit comments