@@ -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