@@ -98,8 +98,8 @@ class Objects(using Context @constructorOnly):
98
98
* LocalEnv(meth, ownerObject) // represents environments for methods or functions
99
99
* EnvSet ::= Set(LocalEnv)
100
100
* InstanceBody ::= (valsMap: Map[Symbol, Value],
101
- outersMap: Map[Symbol , Value],
102
- outerEnvsMap: Map[Symbol, EnvSet]) // represents combined information of all instances represented by a ref
101
+ outersMap: Map[ClassSymbol , Value],
102
+ outerEnv: EnvSet) // represents combined information of all instances represented by a ref
103
103
* Heap ::= Ref -> InstanceBody // heap is mutable
104
104
* EnvBody ::= (valsMap: Map[Symbol, Value],
105
105
* thisV: Value,
@@ -164,16 +164,14 @@ class Objects(using Context @constructorOnly):
164
164
Heap .writeJoinOuter(this , sym, outers)
165
165
}
166
166
167
- def initOuterEnv (sym : Symbol , outerEnvs : Env .EnvSet )(using Context , Heap .MutableData ) =
168
- Heap .writeJoinOuterEnv(this , sym, outerEnvs)
167
+ def initOuterEnv (outerEnvs : Env .EnvSet )(using Context , Heap .MutableData ) =
168
+ Heap .writeJoinOuterEnv(this , outerEnvs)
169
169
170
170
def outerValue (sym : Symbol )(using Heap .MutableData ): Value = Heap .readOuter(this , sym)
171
171
172
172
def outer (using Heap .MutableData ): Value = this .outerValue(klass)
173
173
174
- def outerEnvValue (sym : Symbol )(using Heap .MutableData ): Env .EnvSet = Heap .readOuterEnv(this , sym)
175
-
176
- def outerEnv (using Heap .MutableData ): Env .EnvSet = this .outerEnvValue(klass)
174
+ def outerEnv (using Heap .MutableData ): Env .EnvSet = Heap .readOuterEnv(this )
177
175
end Ref
178
176
179
177
/** A reference to a static object */
@@ -186,7 +184,7 @@ class Objects(using Context @constructorOnly):
186
184
def apply (klass : ClassSymbol )(using Context , Heap .MutableData , Trace ): ObjectRef =
187
185
val obj = new ObjectRef (klass)
188
186
obj.initOuter(klass, Bottom )
189
- obj.initOuterEnv(klass, Env .NoEnv )
187
+ obj.initOuterEnv(Env .NoEnv )
190
188
obj
191
189
192
190
/**
@@ -208,7 +206,7 @@ class Objects(using Context @constructorOnly):
208
206
val owner = State .currentObject
209
207
val instance = new OfClass (klass, owner, ctor, summon[Regions .Data ])
210
208
instance.initOuter(klass, outer)
211
- instance.initOuterEnv(klass, outerEnv)
209
+ instance.initOuterEnv(outerEnv)
212
210
instance
213
211
214
212
/**
@@ -239,7 +237,7 @@ class Objects(using Context @constructorOnly):
239
237
val arr = new OfArray (owner, regions)
240
238
arr.initVal(arr.elementSymbol, Bottom )
241
239
arr.initOuter(arr.klass, Bottom )
242
- arr.initOuterEnv(arr.klass, Env .NoEnv )
240
+ arr.initOuterEnv(Env .NoEnv )
243
241
arr
244
242
245
243
/**
@@ -499,13 +497,16 @@ class Objects(using Context @constructorOnly):
499
497
val outerEnvs = envSet.joinOuterEnvs
500
498
if outerEnvs != NoEnv then // Search for the outerEnvs of the current envSet
501
499
resolveEnvRecur(target, outerEnvs, bySymbol)
502
- else // Search through the outerEnvs of the instances represented by `this`
500
+ else
501
+ // Search through the outerEnvs of the instances represented by `this`
502
+ // in case that `target` is in outer methods separated by local class definitions
503
+ // See `tests/init-global/warn/local-class.scala`
503
504
val thisV = envSet.joinThisV
504
505
val outerEnvsOfThis = thisV match {
505
506
case ref : Ref => ref.outerEnv
506
507
case refSet : RefSet => refSet.joinOuterEnvs
507
508
}
508
- resolveEnvRecur(target, outerEnvs , bySymbol)
509
+ resolveEnvRecur(target, outerEnvsOfThis , bySymbol)
509
510
}
510
511
511
512
@@ -589,13 +590,13 @@ class Objects(using Context @constructorOnly):
589
590
private case class InstanceBody (
590
591
valsMap : Map [Symbol , Value ],
591
592
outersMap : Map [Symbol , Value ],
592
- outerEnvsMap : Map [ Symbol , Env .EnvSet ]
593
+ outerEnvs : Env .EnvSet
593
594
)
594
595
595
596
private def emptyInstanceBody (): InstanceBody = InstanceBody (
596
597
valsMap = Map .empty,
597
598
outersMap = Map .empty,
598
- outerEnvsMap = Map .empty
599
+ outerEnvs = Env . NoEnv
599
600
)
600
601
601
602
/** Immutable heap data used in the cache.
@@ -619,7 +620,7 @@ class Objects(using Context @constructorOnly):
619
620
heap = heap.updated(ref, new InstanceBody (
620
621
valsMap = newValsMap,
621
622
outersMap = current.outersMap,
622
- outerEnvsMap = current.outerEnvsMap
623
+ outerEnvs = current.outerEnvs
623
624
))
624
625
625
626
private [Heap ] def writeJoinOuter (ref : Ref , parentSymbol : Symbol , outers : Value ): Unit =
@@ -633,21 +634,21 @@ class Objects(using Context @constructorOnly):
633
634
heap = heap.updated(ref, new InstanceBody (
634
635
valsMap = current.valsMap,
635
636
outersMap = newOutersMap,
636
- outerEnvsMap = current.outerEnvsMap
637
+ outerEnvs = current.outerEnvs
637
638
))
638
639
639
- private [Heap ] def writeJoinOuterEnv (ref : Ref , parentSymbol : Symbol , outerEnvs : Env .EnvSet ): Unit =
640
+ private [Heap ] def writeJoinOuterEnv (ref : Ref , outerEnvs : Env .EnvSet ): Unit =
640
641
heap.get(ref) match
641
642
case None =>
642
643
heap = heap.updated(ref, Heap .emptyInstanceBody())
643
- writeJoinOuterEnv(ref, parentSymbol, outerEnvs)
644
+ writeJoinOuterEnv(ref, outerEnvs)
644
645
645
646
case Some (current) =>
646
- val newOuterEnvsMap = current.outerEnvsMap .join(parentSymbol, outerEnvs)
647
+ val newOuterEnvs = current.outerEnvs .join(outerEnvs)
647
648
heap = heap.updated(ref, new InstanceBody (
648
649
valsMap = current.valsMap,
649
650
outersMap = current.outersMap,
650
- outerEnvsMap = newOuterEnvsMap
651
+ outerEnvs = newOuterEnvs
651
652
))
652
653
end MutableData
653
654
@@ -668,17 +669,17 @@ class Objects(using Context @constructorOnly):
668
669
def readOuter (ref : Ref , parent : Symbol )(using mutable : MutableData ): Value =
669
670
mutable.heap(ref).outersMap(parent)
670
671
671
- def readOuterEnv (ref : Ref , parent : Symbol )(using mutable : MutableData ): Env .EnvSet =
672
- mutable.heap(ref).outerEnvsMap(parent)
672
+ def readOuterEnv (ref : Ref )(using mutable : MutableData ): Env .EnvSet =
673
+ mutable.heap(ref).outerEnvs
673
674
674
675
def writeJoinVal (ref : Ref , valSymbol : Symbol , value : Value )(using mutable : MutableData ): Unit =
675
676
mutable.writeJoinVal(ref, valSymbol, value)
676
677
677
678
def writeJoinOuter (ref : Ref , outer : Symbol , outers : Value )(using mutable : MutableData ): Unit =
678
679
mutable.writeJoinOuter(ref, outer, outers)
679
680
680
- def writeJoinOuterEnv (ref : Ref , outer : Symbol , outerEnvs : Env .EnvSet )(using mutable : MutableData ): Unit =
681
- mutable.writeJoinOuterEnv(ref, outer, outerEnvs)
681
+ def writeJoinOuterEnv (ref : Ref , outerEnvs : Env .EnvSet )(using mutable : MutableData ): Unit =
682
+ mutable.writeJoinOuterEnv(ref, outerEnvs)
682
683
683
684
def getHeapData ()(using mutable : MutableData ): Data = mutable.heap
684
685
@@ -1085,7 +1086,7 @@ class Objects(using Context @constructorOnly):
1085
1086
// See tests/init/pos/Type.scala
1086
1087
Bottom
1087
1088
1088
- case Fun (code, thisV , klass, scope) =>
1089
+ case Fun (code, thisVOfClosure , klass, scope) =>
1089
1090
// meth == NoSymbol for poly functions
1090
1091
if meth.name == nme.tupled then
1091
1092
value // a call like `fun.tupled`
@@ -1094,11 +1095,11 @@ class Objects(using Context @constructorOnly):
1094
1095
case ddef : DefDef =>
1095
1096
if meth.name == nme.apply then
1096
1097
val funEnv = scope match {
1097
- case ref : Ref => Env .ofDefDef(ddef, args.map(_.value), thisV , Env .NoEnv )
1098
- case env : Env .LocalEnv => Env .ofDefDef(ddef, args.map(_.value), thisV , Env .EnvSet (Set (env)))
1098
+ case ref : Ref => Env .ofDefDef(ddef, args.map(_.value), thisVOfClosure , Env .NoEnv )
1099
+ case env : Env .LocalEnv => Env .ofDefDef(ddef, args.map(_.value), thisVOfClosure , Env .EnvSet (Set (env)))
1099
1100
}
1100
1101
given Scope = funEnv
1101
- extendTrace(code) { eval(ddef.rhs, thisV , klass, cacheResult = true ) }
1102
+ extendTrace(code) { eval(ddef.rhs, thisVOfClosure , klass, cacheResult = true ) }
1102
1103
else
1103
1104
// The methods defined in `Any` and `AnyRef` are trivial and don't affect initialization.
1104
1105
if meth.owner == defn.AnyClass || meth.owner == defn.ObjectClass then
@@ -2121,7 +2122,7 @@ class Objects(using Context @constructorOnly):
2121
2122
*
2122
2123
* @param target The class symbol for `C` for which `C.this` is to be resolved.
2123
2124
* @param thisV The value for `D.this`.
2124
- * @param klass The enclosing class of where `C.this` appears
2125
+ * @param klass The enclosing class `D` where `C.this` appears
2125
2126
* @param elideObjectAccess Whether object access should be omitted.
2126
2127
*
2127
2128
* Object access elision happens when the object access is used as a prefix
0 commit comments