@@ -98,8 +98,8 @@ class Objects(using Context @constructorOnly):
9898 * LocalEnv(meth, ownerObject) // represents environments for methods or functions
9999 * EnvSet ::= Set(LocalEnv)
100100 * 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
103103 * Heap ::= Ref -> InstanceBody // heap is mutable
104104 * EnvBody ::= (valsMap: Map[Symbol, Value],
105105 * thisV: Value,
@@ -164,16 +164,14 @@ class Objects(using Context @constructorOnly):
164164 Heap .writeJoinOuter(this , sym, outers)
165165 }
166166
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)
169169
170170 def outerValue (sym : Symbol )(using Heap .MutableData ): Value = Heap .readOuter(this , sym)
171171
172172 def outer (using Heap .MutableData ): Value = this .outerValue(klass)
173173
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 )
177175 end Ref
178176
179177 /** A reference to a static object */
@@ -186,7 +184,7 @@ class Objects(using Context @constructorOnly):
186184 def apply (klass : ClassSymbol )(using Context , Heap .MutableData , Trace ): ObjectRef =
187185 val obj = new ObjectRef (klass)
188186 obj.initOuter(klass, Bottom )
189- obj.initOuterEnv(klass, Env .NoEnv )
187+ obj.initOuterEnv(Env .NoEnv )
190188 obj
191189
192190 /**
@@ -208,7 +206,7 @@ class Objects(using Context @constructorOnly):
208206 val owner = State .currentObject
209207 val instance = new OfClass (klass, owner, ctor, summon[Regions .Data ])
210208 instance.initOuter(klass, outer)
211- instance.initOuterEnv(klass, outerEnv)
209+ instance.initOuterEnv(outerEnv)
212210 instance
213211
214212 /**
@@ -239,7 +237,7 @@ class Objects(using Context @constructorOnly):
239237 val arr = new OfArray (owner, regions)
240238 arr.initVal(arr.elementSymbol, Bottom )
241239 arr.initOuter(arr.klass, Bottom )
242- arr.initOuterEnv(arr.klass, Env .NoEnv )
240+ arr.initOuterEnv(Env .NoEnv )
243241 arr
244242
245243 /**
@@ -499,13 +497,16 @@ class Objects(using Context @constructorOnly):
499497 val outerEnvs = envSet.joinOuterEnvs
500498 if outerEnvs != NoEnv then // Search for the outerEnvs of the current envSet
501499 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`
503504 val thisV = envSet.joinThisV
504505 val outerEnvsOfThis = thisV match {
505506 case ref : Ref => ref.outerEnv
506507 case refSet : RefSet => refSet.joinOuterEnvs
507508 }
508- resolveEnvRecur(target, outerEnvs , bySymbol)
509+ resolveEnvRecur(target, outerEnvsOfThis , bySymbol)
509510 }
510511
511512
@@ -589,13 +590,13 @@ class Objects(using Context @constructorOnly):
589590 private case class InstanceBody (
590591 valsMap : Map [Symbol , Value ],
591592 outersMap : Map [Symbol , Value ],
592- outerEnvsMap : Map [ Symbol , Env .EnvSet ]
593+ outerEnvs : Env .EnvSet
593594 )
594595
595596 private def emptyInstanceBody (): InstanceBody = InstanceBody (
596597 valsMap = Map .empty,
597598 outersMap = Map .empty,
598- outerEnvsMap = Map .empty
599+ outerEnvs = Env . NoEnv
599600 )
600601
601602 /** Immutable heap data used in the cache.
@@ -619,7 +620,7 @@ class Objects(using Context @constructorOnly):
619620 heap = heap.updated(ref, new InstanceBody (
620621 valsMap = newValsMap,
621622 outersMap = current.outersMap,
622- outerEnvsMap = current.outerEnvsMap
623+ outerEnvs = current.outerEnvs
623624 ))
624625
625626 private [Heap ] def writeJoinOuter (ref : Ref , parentSymbol : Symbol , outers : Value ): Unit =
@@ -633,21 +634,21 @@ class Objects(using Context @constructorOnly):
633634 heap = heap.updated(ref, new InstanceBody (
634635 valsMap = current.valsMap,
635636 outersMap = newOutersMap,
636- outerEnvsMap = current.outerEnvsMap
637+ outerEnvs = current.outerEnvs
637638 ))
638639
639- private [Heap ] def writeJoinOuterEnv (ref : Ref , parentSymbol : Symbol , outerEnvs : Env .EnvSet ): Unit =
640+ private [Heap ] def writeJoinOuterEnv (ref : Ref , outerEnvs : Env .EnvSet ): Unit =
640641 heap.get(ref) match
641642 case None =>
642643 heap = heap.updated(ref, Heap .emptyInstanceBody())
643- writeJoinOuterEnv(ref, parentSymbol, outerEnvs)
644+ writeJoinOuterEnv(ref, outerEnvs)
644645
645646 case Some (current) =>
646- val newOuterEnvsMap = current.outerEnvsMap .join(parentSymbol, outerEnvs)
647+ val newOuterEnvs = current.outerEnvs .join(outerEnvs)
647648 heap = heap.updated(ref, new InstanceBody (
648649 valsMap = current.valsMap,
649650 outersMap = current.outersMap,
650- outerEnvsMap = newOuterEnvsMap
651+ outerEnvs = newOuterEnvs
651652 ))
652653 end MutableData
653654
@@ -668,17 +669,17 @@ class Objects(using Context @constructorOnly):
668669 def readOuter (ref : Ref , parent : Symbol )(using mutable : MutableData ): Value =
669670 mutable.heap(ref).outersMap(parent)
670671
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
673674
674675 def writeJoinVal (ref : Ref , valSymbol : Symbol , value : Value )(using mutable : MutableData ): Unit =
675676 mutable.writeJoinVal(ref, valSymbol, value)
676677
677678 def writeJoinOuter (ref : Ref , outer : Symbol , outers : Value )(using mutable : MutableData ): Unit =
678679 mutable.writeJoinOuter(ref, outer, outers)
679680
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)
682683
683684 def getHeapData ()(using mutable : MutableData ): Data = mutable.heap
684685
@@ -1085,7 +1086,7 @@ class Objects(using Context @constructorOnly):
10851086 // See tests/init/pos/Type.scala
10861087 Bottom
10871088
1088- case Fun (code, thisV , klass, scope) =>
1089+ case Fun (code, thisVOfClosure , klass, scope) =>
10891090 // meth == NoSymbol for poly functions
10901091 if meth.name == nme.tupled then
10911092 value // a call like `fun.tupled`
@@ -1094,11 +1095,11 @@ class Objects(using Context @constructorOnly):
10941095 case ddef : DefDef =>
10951096 if meth.name == nme.apply then
10961097 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)))
10991100 }
11001101 given Scope = funEnv
1101- extendTrace(code) { eval(ddef.rhs, thisV , klass, cacheResult = true ) }
1102+ extendTrace(code) { eval(ddef.rhs, thisVOfClosure , klass, cacheResult = true ) }
11021103 else
11031104 // The methods defined in `Any` and `AnyRef` are trivial and don't affect initialization.
11041105 if meth.owner == defn.AnyClass || meth.owner == defn.ObjectClass then
@@ -2121,7 +2122,7 @@ class Objects(using Context @constructorOnly):
21212122 *
21222123 * @param target The class symbol for `C` for which `C.this` is to be resolved.
21232124 * @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
21252126 * @param elideObjectAccess Whether object access should be omitted.
21262127 *
21272128 * Object access elision happens when the object access is used as a prefix
0 commit comments