Skip to content

Commit 04aa72b

Browse files
committed
Add back arguments to ThisRef
1 parent 5b00b1f commit 04aa72b

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

compiler/src/dotty/tools/dotc/transform/init/Checker.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ class Checker extends Phase {
5555
mdef match
5656
case tdef: TypeDef if tdef.isClassDef =>
5757
val cls = tdef.symbol.asClass
58-
val thisRef = ThisRef(cls)
58+
val ctor = cls.primaryConstructor
59+
val args = ctor.defTree.asInstanceOf[DefDef].termParamss.flatten.map(_ => Hot)
60+
val outer = Hot
61+
val thisRef = ThisRef(cls, outer, ctor, args)
5962
given Trace = Trace.empty
6063
if shouldCheckClass(cls) then Semantic.addTask(thisRef)
6164
case _ =>

compiler/src/dotty/tools/dotc/transform/init/Semantic.scala

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ object Semantic {
5555
*/
5656
sealed abstract class Value {
5757
def show: String = this.toString()
58+
59+
def isHot = this == Hot
60+
def isCold = this == Cold
61+
def isWarm = this.isInstanceOf[Warm]
5862
}
5963

6064
/** A transitively initialized object */
@@ -99,9 +103,7 @@ object Semantic {
99103
}
100104

101105
/** 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 {
105107
ensureObjectExists()
106108
}
107109

@@ -447,7 +449,7 @@ object Semantic {
447449
def widenArgs: List[Value] = values.map(_.widenArg).toList
448450

449451
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) {
451453
if promoted.isCurrentObjectPromoted then Result(Hot, Nil)
452454
else value match {
453455
case Hot =>
@@ -613,6 +615,8 @@ object Semantic {
613615
val warm = Warm(klass, outer, ctor, args2)
614616
val argInfos2 = args.zip(args2).map { (argInfo, v) => argInfo.copy(value = v) }
615617
val res = warm.callConstructor(ctor, argInfos2, source)
618+
val task = ThisRef(klass, outer, ctor, args2)
619+
this.addTask(task)
616620
Result(warm, res.errors)
617621

618622
case Cold =>
@@ -630,6 +634,8 @@ object Semantic {
630634
val argInfos2 = args.zip(argsWidened).map { (argInfo, v) => argInfo.copy(value = v) }
631635
val warm = Warm(klass, outer, ctor, argsWidened)
632636
val res = warm.callConstructor(ctor, argInfos2, source)
637+
val task = ThisRef(klass, outer, ctor, argsWidened)
638+
this.addTask(task)
633639
Result(warm, res.errors)
634640

635641
case Fun(body, thisV, klass, env) =>
@@ -827,19 +833,22 @@ object Semantic {
827833
cls == defn.ObjectClass
828834

829835
// ----- Work list ---------------------------------------------------
830-
type Task = ThisRef
836+
case class Task(value: ThisRef)(val trace: Trace)
831837

832838
class WorkList private[Semantic]() {
833839
private var pendingTasks: List[Task] = Nil
840+
private var checkedTasks: Set[Task] = Set.empty
834841

835842
def addTask(task: Task): Unit =
836-
pendingTasks = task :: pendingTasks
843+
if !checkedTasks.contains(task) then pendingTasks = task :: pendingTasks
837844

838845
/** Process the worklist until done */
839846
@tailrec
840847
final def work()(using State, Context): Unit =
841848
pendingTasks match
842849
case task :: rest =>
850+
checkedTasks = checkedTasks + task
851+
843852
val heapBefore = heap.snapshot()
844853
val res = doTask(task)
845854
res.errors.foreach(_.issue)
@@ -861,7 +870,7 @@ object Semantic {
861870
* This method should only be called from the work list scheduler.
862871
*/
863872
private def doTask(task: Task)(using State, Context): Result = log("checking " + task) {
864-
val thisRef = task
873+
val thisRef = task.value
865874
val tpl = thisRef.klass.defTree.asInstanceOf[TypeDef].rhs.asInstanceOf[Template]
866875

867876
val paramValues = tpl.constr.termParamss.flatten.map(param => param.symbol -> Hot).toMap
@@ -878,7 +887,7 @@ object Semantic {
878887
// ----- API --------------------------------
879888

880889
/** 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))
882891

883892
/** Perform check on the work list until it becomes empty
884893
*

0 commit comments

Comments
 (0)