Skip to content

Commit fb3b6ca

Browse files
committed
Make sure the class parameters and outers of warm objects are populated
1 parent ad503fc commit fb3b6ca

File tree

1 file changed

+29
-12
lines changed

1 file changed

+29
-12
lines changed

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

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,12 @@ object Semantic {
7272
def outer: Value
7373
def objekt(using Heap): Objekt = heap(this)
7474

75-
def ensureObjectExists()(using Heap) =
76-
if heap.contains(this) then heap(this)
75+
def ensureObjectExists()(using Heap): this.type =
76+
if heap.contains(this) then this
7777
else {
7878
val obj = Objekt(this.klass, fields = Map.empty, outers = Map(this.klass -> this.outer))
7979
heap.update(this, obj)
80-
obj
80+
this
8181
}
8282

8383

@@ -113,6 +113,22 @@ object Semantic {
113113
*/
114114
case class Warm(klass: ClassSymbol, outer: Value, ctor: Symbol, args: List[Value])(using @constructorOnly h: Heap) extends Ref {
115115
ensureObjectExists()
116+
117+
/** Ensure that outers and class parameters are initialized.
118+
*
119+
* Fields in class body are not initialized.
120+
*/
121+
def ensureInit(): Contextual[this.type] =
122+
// Somehow Dotty uses the one in the class parameters
123+
given Heap = state.heap
124+
if objekt.outers.size <= 1 then
125+
val tpl = klass.defTree.asInstanceOf[TypeDef].rhs.asInstanceOf[Template]
126+
val termParamss = ctor.defTree.asInstanceOf[DefDef].termParamss
127+
val paramValues = termParamss.flatten.zip(args).map((param, v) => param.symbol -> v).toMap
128+
given Env = Env(paramValues)
129+
init(tpl, this, klass)
130+
end if
131+
this
116132
}
117133

118134
/** A function value */
@@ -292,12 +308,13 @@ object Semantic {
292308
if current.contains(value, expr) then current(value)(expr)
293309
else stable(value)(expr)
294310

295-
def assume(value: Value, expr: Tree, cacheResult: Boolean)(fun: => Result)(using Heap): Result =
311+
def assume(value: Value, expr: Tree, cacheResult: Boolean)(fun: => Result): Contextual[Result] =
296312
val assumeValue: Value =
297313
if last.contains(value, expr) then
298314
// Due to heap reverting, the object corresponding to a reference may not exist in the heap.
299315
last.get(value, expr) match
300-
case ref: Ref => ref.ensureObjectExists(); ref
316+
case ref: ThisRef => ref.ensureObjectExists()
317+
case ref: Warm => ref.ensureObjectExists().ensureInit()
301318
case v => v
302319
else
303320
last.put(value, expr, Hot)
@@ -395,6 +412,8 @@ object Semantic {
395412
given (using s: State): Cache = s.cache
396413
given (using s: State): WorkList = s.workList
397414

415+
inline def state(using s: State) = s
416+
398417
/** The state that threads through the interpreter */
399418
type Contextual[T] = (Env, Context, Trace, Promoted, State) ?=> T
400419

@@ -631,12 +650,11 @@ object Semantic {
631650
Result(Hot, Errors.empty)
632651
else
633652
val outer = Hot
634-
val warm = Warm(klass, outer, ctor, args2)
653+
val warm = Warm(klass, outer, ctor, args2).ensureInit()
635654
val argInfos2 = args.zip(args2).map { (argInfo, v) => argInfo.copy(value = v) }
636-
val res = warm.callConstructor(ctor, argInfos2, source)
637655
val task = ThisRef(klass, outer, ctor, args2)
638656
this.addTask(task)
639-
Result(warm, res.errors)
657+
Result(warm, Errors.empty)
640658

641659
case Cold =>
642660
val error = CallCold(ctor, source, trace1.toVector)
@@ -651,11 +669,10 @@ object Semantic {
651669

652670
val argsWidened = args.map(_.value).widenArgs
653671
val argInfos2 = args.zip(argsWidened).map { (argInfo, v) => argInfo.copy(value = v) }
654-
val warm = Warm(klass, outer, ctor, argsWidened)
655-
val res = warm.callConstructor(ctor, argInfos2, source)
672+
val warm = Warm(klass, outer, ctor, argsWidened).ensureInit()
656673
val task = ThisRef(klass, outer, ctor, argsWidened)
657674
this.addTask(task)
658-
Result(warm, res.errors)
675+
Result(warm, Errors.empty)
659676

660677
case Fun(body, thisV, klass, env) =>
661678
report.error("unexpected tree in instantiating a function, fun = " + body.show, source)
@@ -1280,7 +1297,7 @@ object Semantic {
12801297
thisV.updateOuter(cls, res.value)
12811298

12821299
// follow constructor
1283-
if cls.hasSource && !thisV.isWarm then
1300+
if cls.hasSource then
12841301
tasks.append { () =>
12851302
printer.println("init super class " + cls.show)
12861303
val res2 = thisV.callConstructor(ctor, args, source)

0 commit comments

Comments
 (0)