Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 248435c

Browse files
author
EnzeXing
committedMay 27, 2025
Address comments
1 parent d9156eb commit 248435c

File tree

1 file changed

+76
-120
lines changed

1 file changed

+76
-120
lines changed
 

‎compiler/src/dotty/tools/dotc/transform/init/Objects.scala

Lines changed: 76 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -84,23 +84,22 @@ class Objects(using Context @constructorOnly):
8484
/** Syntax for the data structure abstraction used in abstract domain:
8585
*
8686
* ve ::= ObjectRef(class) // global object
87-
* | OfClass(class, ownerObject, ctor) // instance of a class
87+
* | OfClass(class, ownerObject, ctor, regions) // instance of a class
8888
* | OfArray(ownerObject, regions) // represents values of native array class in Array.scala
89-
* | Fun(code, env) // value elements that can be contained in ValueSet
89+
* | Fun(code, LocalEnv) // value elements that can be contained in ValueSet
9090
* | SafeValue // values on which method calls and field accesses won't cause warnings. Int, String, etc.
9191
* | UnknownValue // values whose source are unknown at compile time
92-
* | Package // represets a package
9392
* vs ::= ValueSet(ve) // set of abstract values
94-
* Bottom ::= ValueSet(Empty)
95-
* val ::= ve | vs
93+
* Bottom ::= ValueSet(Empty) // unreachable code
94+
* val ::= ve | vs | Package
9695
* Ref ::= ObjectRef | OfClass | OfArray // values that represent a reference to some (global or instance) object
97-
* ThisValue ::= Ref | vs // possible values for 'this'
96+
* ThisValue ::= Ref | Set(Ref) // possible values for 'this'
9897
* LocalEnv(meth, ownerObject) // represents environments for methods or functions
9998
* Scope ::= Ref | LocalEnv
10099
* ScopeSet ::= Set(Scope)
101100
*
102101
* valsMap = sym -> val // maps variables to their values
103-
* outersMap = classSym -> ScopeSEt // maps the possible outer scopes for a corresponding (parent) class
102+
* outersMap = sym -> ScopeSet // maps the possible outer scopes for a corresponding (parent) class
104103
* heap.MutableData = Scope -> (valsMap, outersMap) // heap is mutable
105104
*
106105
* regions ::= List(sourcePosition)
@@ -116,42 +115,34 @@ class Objects(using Context @constructorOnly):
116115
* A reference caches the values for outers and immutable fields.
117116
*/
118117
sealed abstract class Scope(using trace: Trace):
119-
// protected val vals: mutable.Map[Symbol, Value] = valsMap
120-
// protected val vars: mutable.Map[Symbol, Heap.Addr] = varsMap
121-
// protected val outers: mutable.Map[ClassSymbol, Value] = outersMap
122-
123118
def isObjectRef: Boolean = this.isInstanceOf[ObjectRef]
124119

125120
def getTrace: Trace = trace
126121

127122
def isRef = this.isInstanceOf[Ref]
128123

129-
def isEnv = this.isInstanceOf[Env.Data]
124+
def isEnv = this.isInstanceOf[Env.LocalEnv]
125+
126+
def asRef: Ref = this.asInstanceOf[Ref]
130127

131-
def meth: Symbol
128+
def asEnv: Env.LocalEnv = this.asInstanceOf[Env.LocalEnv]
132129

133130
def owner: ClassSymbol
134131

135132
def level: Int
136133

137134
def show(using Context): String
138135

136+
def outer(using Heap.MutableData): ScopeSet
137+
139138
def valValue(sym: Symbol)(using Heap.MutableData): Value = Heap.readVal(this, sym)
140139

141140
def varValue(sym: Symbol)(using Heap.MutableData): Value = Heap.readVal(this, sym)
142141

143-
// def varAddr(sym: Symbol): Heap.Addr = vars(sym)
144-
145-
def outerValue(sym: Symbol)(using Heap.MutableData): ScopeSet = Heap.readOuter(this, sym)
146-
147-
def outer(using Heap.MutableData): ScopeSet = this.outerValue(meth)
148-
149142
def hasVal(sym: Symbol)(using Heap.MutableData): Boolean = Heap.containsVal(this, sym)
150143

151144
def hasVar(sym: Symbol)(using Heap.MutableData): Boolean = Heap.containsVal(this, sym)
152145

153-
def hasOuter(cls: ClassSymbol)(using Heap.MutableData): Boolean = Heap.containsOuter(this, cls)
154-
155146
def initVal(field: Symbol, value: Value)(using Context, Heap.MutableData) = log("Initialize " + field.show + " = " + value + " for " + this, printer) {
156147
assert(!field.is(Flags.Mutable), "Field is mutable: " + field.show)
157148
Heap.writeJoinVal(this, field, value)
@@ -168,22 +159,25 @@ class Objects(using Context @constructorOnly):
168159

169160
sealed abstract class Ref(using Trace) extends Scope with ValueElement:
170161
def klass: ClassSymbol
171-
final override def outer(using Heap.MutableData): ScopeSet = this.outerValue(klass)
172162

173-
/** A reference to a static object */
174-
case class ObjectRef(
175-
klass: ClassSymbol
176-
)(using context: Context, @constructorOnly heap: Heap.MutableData, trace: Trace) extends Ref:
177-
initOuter(klass, Env.NoEnv)
163+
def outerValue(sym: Symbol)(using Heap.MutableData): ScopeSet = Heap.readOuter(this, sym)
178164

179-
def meth = klass.primaryConstructor
165+
def outer(using Heap.MutableData): ScopeSet = this.outerValue(klass)
180166

167+
/** A reference to a static object */
168+
case class ObjectRef private (klass: ClassSymbol)(using Trace) extends Ref:
181169
def owner = klass
182170

183171
def level = 1
184172

185173
def show(using Context) = "ObjectRef(" + klass.show + ")"
186174

175+
object ObjectRef:
176+
def apply(klass: ClassSymbol)(using Context, Heap.MutableData, Trace): ObjectRef =
177+
val obj = new ObjectRef(klass)
178+
obj.initOuter(klass, Env.NoEnv)
179+
obj
180+
187181
/**
188182
* Represents values that are instances of the specified class.
189183
*
@@ -192,10 +186,8 @@ class Objects(using Context @constructorOnly):
192186
case class OfClass private (
193187
klass: ClassSymbol, owner: ClassSymbol, ctor: Symbol, level: Int, regions: Regions.Data)(using Trace)
194188
extends Ref:
195-
def meth = klass.primaryConstructor
196-
197189
def show(using Context) =
198-
"OfClass(" + klass.show + ", meth = " + meth.show + ", owner = " + owner + ")"
190+
"OfClass(" + klass.show + ", ctor = " + ctor.show + ", owner = " + owner + ")"
199191

200192
object OfClass:
201193
def apply(
@@ -219,18 +211,25 @@ class Objects(using Context @constructorOnly):
219211
*
220212
* @param owner The static object whose initialization creates the array.
221213
*/
222-
case class OfArray(owner: ClassSymbol, regions: Regions.Data)(using Context, Trace, Heap.MutableData) extends Ref:
223-
def meth = defn.ArrayConstructor
224-
def klass: ClassSymbol = defn.ArrayClass
214+
case class OfArray private (owner: ClassSymbol, regions: Regions.Data)(using Trace) extends Ref:
215+
val elementSymbol = defn.ArrayConstructor
225216

226-
val contentSymbol = defn.ArrayConstructor
227-
initVal(meth, Bottom)
217+
def klass: ClassSymbol = defn.ArrayClass
228218

229219
def level = 1
230-
def outerScope = Env.NoEnv
220+
231221
def show(using Context) = "OfArray(owner = " + owner.show + ")"
232-
def content(using Heap.MutableData) = valValue(meth)
233-
def updateContent(value: Value)(using Heap.MutableData) = Heap.writeJoinVal(this, meth, value)
222+
223+
def readElement(using Heap.MutableData) = valValue(elementSymbol)
224+
225+
def writeElement(value: Value)(using Heap.MutableData) = Heap.writeJoinVal(this, elementSymbol, value)
226+
227+
object OfArray:
228+
def apply(owner: ClassSymbol, regions: Regions.Data)(using Context, Trace, Heap.MutableData): OfArray =
229+
val arr = new OfArray(owner, regions)
230+
arr.initVal(arr.elementSymbol, Bottom)
231+
arr.initOuter(arr.klass, Env.NoEnv)
232+
arr
234233

235234
/**
236235
* Represents a lambda expression
@@ -277,8 +276,6 @@ class Objects(using Context @constructorOnly):
277276
new SafeValue(typeSymbol.get)
278277

279278
/** Represents values unknown to the checker, such as values loaded without source
280-
* UnknownValue is not ValueElement since RefSet containing UnknownValue
281-
* is equivalent to UnknownValue
282279
*/
283280
case object UnknownValue extends ValueElement:
284281
def show(using Context): String = "UnknownValue"
@@ -291,11 +288,18 @@ class Objects(using Context @constructorOnly):
291288
case class ValueSet(values: Set[ValueElement]) extends Value:
292289
def show(using Context) = values.map(_.show).mkString("[", ",", "]")
293290

291+
def isRefSet = values.forall(_.isInstanceOf[Ref])
292+
293+
def toScopeSet: ScopeSet = ScopeSet(values.asInstanceOf[Set[Scope]])
294+
294295
case class ScopeSet(scopes: Set[Scope]):
295296
assert(scopes.forall(_.isRef) || scopes.forall(_.isEnv), "All scopes should have the same type!")
296297
def level: Int = if scopes.isEmpty then 0 else scopes.head.level
298+
297299
def show(using Context) = scopes.map(_.show).mkString("[", ",", "]")
298300

301+
def toValueSet: ValueSet = ValueSet(scopes.asInstanceOf[Set[ValueElement]])
302+
299303
case class Package(packageModuleClass: ClassSymbol) extends Value:
300304
def show(using Context): String = "Package(" + packageModuleClass.show + ")"
301305

@@ -390,20 +394,19 @@ class Objects(using Context @constructorOnly):
390394

391395
/** Environment for parameters */
392396
object Env:
393-
sealed abstract class Data(using Trace) extends Scope:
394-
def level: Int
395-
396397
/** Local environments can be deeply nested, therefore we need `outer`.
397398
*
398399
* For local variables in rhs of class field definitions, the `meth` is the primary constructor.
399400
*/
400-
private case class LocalEnv(meth: Symbol, owner: ClassSymbol, level: Int)(using Trace) extends Data:
401+
case class LocalEnv(meth: Symbol, owner: ClassSymbol, level: Int)(using Trace) extends Scope:
401402
if (level > 3)
402403
report.warning("[Internal error] Deeply nested environment, level = " + level + ", " + meth.show + " in " + meth.enclosingClass.show, meth.defTree)
403404

404405
def show(using Context) =
405406
"meth: " + meth.show + "\n" +
406407
"owner: " + owner.show
408+
409+
def outer(using Heap.MutableData): ScopeSet = Heap.readOuter(this, meth)
407410
end LocalEnv
408411

409412
val NoEnv = ScopeSet(Set.empty)
@@ -413,7 +416,7 @@ class Objects(using Context @constructorOnly):
413416
* The owner for the local environment for field initializers is the primary constructor of the
414417
* enclosing class.
415418
*/
416-
def emptyEnv(meth: Symbol)(using Context, State.Data, Heap.MutableData, Trace): Data =
419+
def emptyEnv(meth: Symbol)(using Context, State.Data, Heap.MutableData, Trace): LocalEnv =
417420
_of(Map.empty, meth, NoEnv)
418421

419422
def valValue(x: Symbol)(using scope: Scope, ctx: Context, trace: Trace, heap: Heap.MutableData): Value =
@@ -423,20 +426,8 @@ class Objects(using Context @constructorOnly):
423426
report.warning("[Internal error] Value not found " + x.show + "\nscope = " + scope.show + ". " + Trace.show, Trace.position)
424427
Bottom
425428

426-
def getVal(x: Symbol)(using scope: Scope, ctx: Context, heap: Heap.MutableData): Option[Value] =
427-
if scope.hasVal(x) then
428-
Some(scope.valValue(x))
429-
else
430-
None
431-
432-
def getVar(x: Symbol)(using scope: Scope, ctx: Context, heap: Heap.MutableData): Option[Value] =
433-
if scope.hasVar(x) then
434-
Some(scope.varValue(x))
435-
else
436-
None
437-
438429
private[Env] def _of(argMap: Map[Symbol, Value], meth: Symbol, outerSet: ScopeSet)
439-
(using State.Data, Heap.MutableData, Trace): Data =
430+
(using State.Data, Heap.MutableData, Trace): LocalEnv =
440431
val env = LocalEnv(meth, State.currentObject, outerSet.level + 1)
441432
argMap.foreach(env.initVal(_, _))
442433
env.initOuter(meth, outerSet)
@@ -454,7 +445,7 @@ class Objects(using Context @constructorOnly):
454445
if bySymbol then
455446
scopeSet.scopes.filter(_.hasVal(target))
456447
else
457-
scopeSet.scopes.filter(_.meth == target)
448+
scopeSet.scopes.filter(s => s.isEnv && s.asEnv.meth == target)
458449

459450
assert(filter.isEmpty || filter.size == scopeSet.scopes.size, "Either all scopes or no scopes contain " + target)
460451
if (!filter.isEmpty) then
@@ -475,13 +466,13 @@ class Objects(using Context @constructorOnly):
475466

476467

477468
def ofDefDef(ddef: DefDef, args: List[Value], outer: ScopeSet)
478-
(using State.Data, Heap.MutableData, Trace): Data =
469+
(using State.Data, Heap.MutableData, Trace): LocalEnv =
479470
val params = ddef.termParamss.flatten.map(_.symbol)
480471
assert(args.size == params.size, "arguments = " + args.size + ", params = " + params.size)
481472
// assert(ddef.symbol.owner.isClass ^ (outer != NoEnv), "ddef.owner = " + ddef.symbol.owner.show + ", outer = " + outer + ", " + ddef.source)
482473
_of(params.zip(args).toMap, ddef.symbol, outer)
483474

484-
def ofByName(byNameParam: Symbol, outer: Scope)(using State.Data, Heap.MutableData, Trace): Data =
475+
def ofByName(byNameParam: Symbol, outer: Scope)(using State.Data, Heap.MutableData, Trace): LocalEnv =
485476
assert(byNameParam.is(Flags.Param) && byNameParam.info.isInstanceOf[ExprType]);
486477
_of(Map.empty, byNameParam, ScopeSet(Set(outer)))
487478

@@ -491,15 +482,15 @@ class Objects(using Context @constructorOnly):
491482
case localEnv: LocalEnv =>
492483
localEnv.initVal(x, value)
493484
case ref: Ref =>
494-
ref.initVal(x, value) // possible for match statement in class body. Report warning?
485+
ref.initVal(x, value) // TODO: This is possible for match statement in class body. Report warning?
495486

496487
def setLocalVar(x: Symbol, value: Value)(using scope: Scope, ctx: Context, heap: Heap.MutableData): Unit =
497488
assert(x.is(Flags.Mutable, butNot = Flags.Param), "Only local mutable variable allowed")
498489
scope match
499490
case localEnv: LocalEnv =>
500491
localEnv.initVar(x, value)
501492
case ref: Ref =>
502-
ref.initVar(x, value) // possible for match statement in class body. Report warning?
493+
ref.initVar(x, value) // TODO: This is possible for match statement in class body. Report warning?
503494

504495
/**
505496
* Resolve the environment by searching for a given symbol.
@@ -541,20 +532,18 @@ class Objects(using Context @constructorOnly):
541532
resolveEnvRecur(enclosing, thisV, ScopeSet(Set(scope)), bySymbol = false)
542533
}
543534

544-
def withEnv[T](env: Data)(fn: Data ?=> T): T = fn(using env)
535+
def withEnv[T](env: LocalEnv)(fn: LocalEnv ?=> T): T = fn(using env)
545536
end Env
546537

547538
/** Abstract heap for mutable fields
548539
*/
549540
object Heap:
550541
private case class ScopeBody(
551-
paramsMap: Map[Symbol, Value],
552542
valsMap: Map[Symbol, Value],
553543
outersMap: Map[Symbol, ScopeSet]
554544
)
555545

556546
private def emptyScopeBody(): ScopeBody = ScopeBody(
557-
paramsMap = Map.empty,
558547
valsMap = Map.empty,
559548
outersMap = Map.empty
560549
)
@@ -569,20 +558,6 @@ class Objects(using Context @constructorOnly):
569558

570559
/** Store the heap as a mutable field to avoid threading it through the program. */
571560
class MutableData(private[Heap] var heap: Data):
572-
private[Heap] def writeJoinParam(scope: Scope, param: Symbol, value: Value): Unit =
573-
heap.get(scope) match
574-
case None =>
575-
heap = heap.updated(scope, Heap.emptyScopeBody())
576-
writeJoinParam(scope, param, value)
577-
578-
case Some(current) =>
579-
val newParamsMap = current.paramsMap.join(param, value)
580-
heap = heap.updated(scope, new ScopeBody(
581-
paramsMap = newParamsMap,
582-
valsMap = current.valsMap,
583-
outersMap = current.outersMap
584-
))
585-
586561
private[Heap] def writeJoinVal(scope: Scope, valSymbol: Symbol, value: Value): Unit =
587562
heap.get(scope) match
588563
case None =>
@@ -592,7 +567,6 @@ class Objects(using Context @constructorOnly):
592567
case Some(current) =>
593568
val newValsMap = current.valsMap.join(valSymbol, value)
594569
heap = heap.updated(scope, new ScopeBody(
595-
paramsMap = current.paramsMap,
596570
valsMap = newValsMap,
597571
outersMap = current.outersMap
598572
))
@@ -606,7 +580,6 @@ class Objects(using Context @constructorOnly):
606580
case Some(current) =>
607581
val newOutersMap = current.outersMap.join(outerSymbol, outerScope)
608582
heap = heap.updated(scope, new ScopeBody(
609-
paramsMap = current.paramsMap,
610583
valsMap = current.valsMap,
611584
outersMap = newOutersMap
612585
))
@@ -617,12 +590,6 @@ class Objects(using Context @constructorOnly):
617590
def contains(scope: Scope)(using mutable: MutableData): Boolean =
618591
mutable.heap.contains(scope)
619592

620-
def containsParam(scope: Scope, param: Symbol)(using mutable: MutableData): Boolean =
621-
if mutable.heap.contains(scope) then
622-
mutable.heap(scope).paramsMap.contains(param)
623-
else
624-
false
625-
626593
def containsVal(scope: Scope, value: Symbol)(using mutable: MutableData): Boolean =
627594
if mutable.heap.contains(scope) then
628595
mutable.heap(scope).valsMap.contains(value)
@@ -635,18 +602,12 @@ class Objects(using Context @constructorOnly):
635602
else
636603
false
637604

638-
def readParam(scope: Scope, param: Symbol)(using mutable: MutableData): Value =
639-
mutable.heap(scope).paramsMap(param)
640-
641605
def readVal(scope: Scope, value: Symbol)(using mutable: MutableData): Value =
642606
mutable.heap(scope).valsMap(value)
643607

644608
def readOuter(scope: Scope, outer: Symbol)(using mutable: MutableData): ScopeSet =
645609
mutable.heap(scope).outersMap(outer)
646610

647-
def writeJoinParam(scope: Scope, param: Symbol, value: Value)(using mutable: MutableData): Unit =
648-
mutable.writeJoinParam(scope, param, value)
649-
650611
def writeJoinVal(scope: Scope, valSymbol: Symbol, value: Value)(using mutable: MutableData): Unit =
651612
mutable.writeJoinVal(scope, valSymbol, value)
652613

@@ -663,7 +624,7 @@ class Objects(using Context @constructorOnly):
663624
case class Res(value: Value, heap: Heap.Data)
664625

665626
class Data extends Cache[Config, Res]:
666-
def get(thisV: Value, expr: Tree)(using Heap.MutableData, Env.Data): Option[Value] =
627+
def get(thisV: Value, expr: Tree)(using Heap.MutableData, Scope): Option[Value] =
667628
val config = Config(thisV, summon[Scope], Heap.getHeapData())
668629
super.get(config, expr).map(_.value)
669630

@@ -880,7 +841,7 @@ class Objects(using Context @constructorOnly):
880841

881842
if target == defn.Array_apply || target == defn.Array_clone then
882843
if arr.owner == State.currentObject then
883-
arr.content
844+
arr.readElement
884845
else
885846
errorReadOtherStaticObject(State.currentObject, arr)
886847
Bottom
@@ -889,7 +850,7 @@ class Objects(using Context @constructorOnly):
889850
if arr.owner != State.currentObject then
890851
errorMutateOtherStaticObject(State.currentObject, arr)
891852
else
892-
arr.updateContent(args.tail.head.value)
853+
arr.writeElement(args.tail.head.value)
893854
Bottom
894855
else
895856
// Array.length is OK
@@ -910,7 +871,7 @@ class Objects(using Context @constructorOnly):
910871
if target.isOneOf(Flags.Method) then
911872
if target.owner == defn.ArrayModuleClass && target.name == nme.apply then
912873
val arr = OfArray(State.currentObject, summon[Regions.Data])
913-
arr.updateContent(args.map(_.value).join)
874+
arr.writeElement(args.map(_.value).join)
914875
arr
915876
else if target.equals(defn.Predef_classOf) then
916877
// Predef.classOf is a stub method in tasty and is replaced in backend
@@ -1151,7 +1112,7 @@ class Objects(using Context @constructorOnly):
11511112
* @param ctor The symbol of the target constructor.
11521113
* @param args The arguments passsed to the constructor.
11531114
*/
1154-
def instantiate(outer: Value, klass: ClassSymbol, ctor: Symbol, args: List[ArgInfo], typeArgs: List[Type]): Contextual[Value] = log("instantiating " + klass.show + ", outer = " + outer + ", args = " + args.map(_.value.show), printer, (_: Value).show) {
1115+
def instantiate(outer: Value, klass: ClassSymbol, ctor: Symbol, args: List[ArgInfo]): Contextual[Value] = log("instantiating " + klass.show + ", outer = " + outer + ", args = " + args.map(_.value.show), printer, (_: Value).show) {
11551116
outer.filterClass(klass.owner) match
11561117
case _ : Fun | _: OfArray | SafeValue(_) =>
11571118
report.warning("[Internal error] unexpected outer in instantiating a class, outer = " + outer.show + ", class = " + klass.show + ", " + Trace.show, Trace.position)
@@ -1175,24 +1136,24 @@ class Objects(using Context @constructorOnly):
11751136
outer match
11761137
case Package(_) => // For top-level classes
11771138
Env.NoEnv
1178-
case thisV : ThisValue =>
1139+
case outer : ThisValue =>
11791140
if klass.owner.is(Flags.Package) then
11801141
report.warning("[Internal error] top-level class should have `Package` as outer, class = " + klass.show + ", outer = " + outer.show + ", " + Trace.show, Trace.position)
11811142
Env.NoEnv
11821143
else
11831144
val enclosingMethod = klass.owner.enclosingMethod
1184-
val outerCls = thisV.asInstanceOf[Ref].klass
1145+
val outerCls = outer.asInstanceOf[Ref].klass
11851146
// When `klass` is directly nested in `outerCls`, `outerCls`.enclosingMethod returns its primary constructor
11861147
if enclosingMethod == outerCls.primaryConstructor then
1187-
ScopeSet(Set(thisV.asInstanceOf[Ref]))
1148+
ScopeSet(Set(outer.asInstanceOf[Ref]))
11881149
else
1189-
Env.resolveEnvByMethod(klass.owner.enclosingMethod, thisV, summon[Scope]).getOrElse(UnknownValue -> Env.NoEnv)._2
1150+
Env.resolveEnvByMethod(klass.owner.enclosingMethod, outer, summon[Scope]).getOrElse(UnknownValue -> Env.NoEnv)._2
11901151

11911152
val instance = OfClass(klass, envWidened, ctor)
11921153
callConstructor(instance, ctor, args)
11931154

11941155
case ValueSet(values) =>
1195-
values.map(ref => instantiate(ref, klass, ctor, args, typeArgs)).join
1156+
values.map(ref => instantiate(ref, klass, ctor, args)).join
11961157
}
11971158

11981159
/** Handle local variable definition, `val x = e` or `var x = e`.
@@ -1296,10 +1257,10 @@ class Objects(using Context @constructorOnly):
12961257
}
12971258

12981259

1299-
def checkClasses(classes: List[ClassSymbol])(using Context) =
1260+
def checkClasses(classes: List[ClassSymbol])(using Context): Unit =
13001261
given State.Data = new State.Data
13011262
given Trace = Trace.empty
1302-
given Heap.MutableData = Heap.empty
1263+
given Heap.MutableData = Heap.empty // TODO: do garbage collection on the heap
13031264

13041265
for
13051266
classSym <- classes if classSym.isStaticObject
@@ -1360,12 +1321,9 @@ class Objects(using Context @constructorOnly):
13601321
val args = evalArgs(argss.flatten, thisV, klass)
13611322

13621323
val cls = tref.classSymbol.asClass
1363-
val typeArgs = tpt.tpe match
1364-
case AppliedType(_, args) => args
1365-
case _ => Nil
13661324
withTrace(trace2) {
13671325
val outer = outerValue(tref, thisV, klass)
1368-
instantiate(outer, cls, ctor, args, typeArgs)
1326+
instantiate(outer, cls, ctor, args)
13691327
}
13701328

13711329
case TypeCast(elem, tpe) =>
@@ -1516,7 +1474,7 @@ class Objects(using Context @constructorOnly):
15161474
val module = defn.getWrapVarargsArrayModule.moduleClass.asClass
15171475
val args = evalArgs(elems.map(Arg.apply), thisV, klass)
15181476
val arr = OfArray(State.currentObject, summon[Regions.Data])
1519-
arr.updateContent(args.map(_.value).join)
1477+
arr.writeElement(args.map(_.value).join)
15201478
call(ObjectRef(module), meth, List(ArgInfo(arr, summon[Trace], EmptyTree)), module.typeRef, NoType)
15211479

15221480
case Inlined(call, bindings, expansion) =>
@@ -1871,8 +1829,8 @@ class Objects(using Context @constructorOnly):
18711829
val res = outerValue(tref, thisV, klass)
18721830
res match {
18731831
case ref: Ref => thisV.initOuter(cls, ScopeSet(Set(ref)))
1874-
case ValueSet(values) if values.forall(_.isInstanceOf[Ref]) =>
1875-
thisV.initOuter(cls, ScopeSet(values.map(_.asInstanceOf[Ref])))
1832+
case vs: ValueSet if vs.isRefSet =>
1833+
thisV.initOuter(cls, vs.toScopeSet)
18761834
case _: Package =>
18771835
thisV.initOuter(cls, Env.NoEnv)
18781836
case _ =>
@@ -1993,7 +1951,7 @@ class Objects(using Context @constructorOnly):
19931951
val klass = head.asInstanceOf[Ref].klass
19941952
assert(scopeSet.scopes.forall(_.asInstanceOf[Ref].klass == klass), "Multiple possible outer class?")
19951953
if klass == target then
1996-
ValueSet(scopeSet.scopes.map(_.asInstanceOf[Ref]))
1954+
scopeSet.toValueSet
19971955
else
19981956
recur(scopeSet.scopes.map(_.outer).join)
19991957
else
@@ -2013,8 +1971,8 @@ class Objects(using Context @constructorOnly):
20131971
case Bottom => Bottom
20141972
case ref: Ref =>
20151973
recur(ScopeSet(Set(ref)))
2016-
case ValueSet(values) if values.forall(_.isInstanceOf[Ref]) =>
2017-
recur(ScopeSet(values.map(_.asInstanceOf[Ref])))
1974+
case vs: ValueSet if vs.isRefSet =>
1975+
recur(vs.toScopeSet)
20181976
case _ =>
20191977
report.warning("[Internal error] unexpected thisV = " + thisV + ", target = " + target.show + ", klass = " + klass.show + Trace.show, Trace.position)
20201978
Bottom
@@ -2033,9 +1991,7 @@ class Objects(using Context @constructorOnly):
20331991
resolveThis(enclosing, thisV, klass, elideObjectAccess = cls.isStatic)
20341992
else
20351993
if cls.isAllOf(Flags.JavaInterface) then Bottom
2036-
else
2037-
val res = evalType(tref.prefix, thisV, klass, elideObjectAccess = cls.isStatic)
2038-
res
1994+
else evalType(tref.prefix, thisV, klass, elideObjectAccess = cls.isStatic)
20391995

20401996
def printTraceWhenMultiple(trace: Trace)(using Context): String =
20411997
if trace.toVector.size > 1 then

0 commit comments

Comments
 (0)
Please sign in to comment.