@@ -197,7 +197,7 @@ class Objects:
197
197
*
198
198
* @param owner The static object whose initialization creates the array.
199
199
*/
200
- case class OfArray (owner : ClassSymbol , regions : Regions .Data )(using @ constructorOnly ctx : Context ) extends ValueElement :
200
+ case class OfArray (owner : ClassSymbol , regions : Regions .Data )(using @ constructorOnly ctx : Context , @ constructorOnly trace : Trace ) extends ValueElement :
201
201
val klass : ClassSymbol = defn.ArrayClass
202
202
val addr : Heap .Addr = Heap .arrayAddr(regions, owner)
203
203
def show (using Context ) = " OfArray(owner = " + owner.show + " )"
@@ -455,9 +455,11 @@ class Objects:
455
455
abstract class Addr :
456
456
/** The static object which owns the mutable slot */
457
457
def owner : ClassSymbol
458
+ def getTrace : Trace = Trace .empty
458
459
459
460
/** The address for mutable fields of objects. */
460
- private case class FieldAddr (regions : Regions .Data , field : Symbol , owner : ClassSymbol ) extends Addr
461
+ private case class FieldAddr (regions : Regions .Data , field : Symbol , owner : ClassSymbol )(trace : Trace ) extends Addr :
462
+ override def getTrace : Trace = trace
461
463
462
464
/** The address for mutable local variables . */
463
465
private case class LocalVarAddr (regions : Regions .Data , sym : Symbol , owner : ClassSymbol ) extends Addr
@@ -497,11 +499,11 @@ class Objects:
497
499
def localVarAddr (regions : Regions .Data , sym : Symbol , owner : ClassSymbol ): Addr =
498
500
LocalVarAddr (regions, sym, owner)
499
501
500
- def fieldVarAddr (regions : Regions .Data , sym : Symbol , owner : ClassSymbol ): Addr =
501
- FieldAddr (regions, sym, owner)
502
+ def fieldVarAddr (regions : Regions .Data , sym : Symbol , owner : ClassSymbol )( using Trace ) : Addr =
503
+ FieldAddr (regions, sym, owner)(summon[ Trace ])
502
504
503
- def arrayAddr (regions : Regions .Data , owner : ClassSymbol )(using Context ): Addr =
504
- FieldAddr (regions, defn.ArrayClass , owner)
505
+ def arrayAddr (regions : Regions .Data , owner : ClassSymbol )(using Trace , Context ): Addr =
506
+ FieldAddr (regions, defn.ArrayClass , owner)(summon[ Trace ])
505
507
506
508
def getHeapData ()(using mutable : MutableData ): Data = mutable.heap
507
509
@@ -654,12 +656,12 @@ class Objects:
654
656
if arr.addr.owner == State .currentObject then
655
657
Heap .read(arr.addr)
656
658
else
657
- errorReadOtherStaticObject(State .currentObject, arr.addr.owner )
659
+ errorReadOtherStaticObject(State .currentObject, arr.addr)
658
660
Bottom
659
661
else if target == defn.Array_update then
660
662
assert(args.size == 2 , " Incorrect number of arguments for Array update, found = " + args.size)
661
663
if arr.addr.owner != State .currentObject then
662
- errorMutateOtherStaticObject(State .currentObject, arr.addr.owner )
664
+ errorMutateOtherStaticObject(State .currentObject, arr.addr)
663
665
else
664
666
Heap .writeJoin(arr.addr, args.tail.head.value)
665
667
Bottom
@@ -810,7 +812,7 @@ class Objects:
810
812
if addr.owner == State .currentObject then
811
813
Heap .read(addr)
812
814
else
813
- errorReadOtherStaticObject(State .currentObject, addr.owner )
815
+ errorReadOtherStaticObject(State .currentObject, addr)
814
816
Bottom
815
817
else if ref.isObjectRef && ref.klass.hasSource then
816
818
report.warning(" Access uninitialized field " + field.show + " . " + Trace .show, Trace .position)
@@ -879,7 +881,7 @@ class Objects:
879
881
if ref.hasVar(field) then
880
882
val addr = ref.varAddr(field)
881
883
if addr.owner != State .currentObject then
882
- errorMutateOtherStaticObject(State .currentObject, addr.owner )
884
+ errorMutateOtherStaticObject(State .currentObject, addr)
883
885
else
884
886
Heap .writeJoin(addr, rhs)
885
887
else
@@ -968,7 +970,7 @@ class Objects:
968
970
if addr.owner == State .currentObject then
969
971
Heap .read(addr)
970
972
else
971
- errorReadOtherStaticObject(State .currentObject, addr.owner )
973
+ errorReadOtherStaticObject(State .currentObject, addr)
972
974
Bottom
973
975
end if
974
976
case _ =>
@@ -1020,7 +1022,7 @@ class Objects:
1020
1022
Env .getVar(sym) match
1021
1023
case Some (addr) =>
1022
1024
if addr.owner != State .currentObject then
1023
- errorMutateOtherStaticObject(State .currentObject, addr.owner )
1025
+ errorMutateOtherStaticObject(State .currentObject, addr)
1024
1026
else
1025
1027
Heap .writeJoin(addr, value)
1026
1028
case _ =>
@@ -1757,20 +1759,31 @@ class Objects:
1757
1759
if cls.isAllOf(Flags .JavaInterface ) then Bottom
1758
1760
else evalType(tref.prefix, thisV, klass, elideObjectAccess = cls.isStatic)
1759
1761
1762
+ def printTraceWhenMultiple (trace : Trace )(using Context ): String =
1763
+ if trace.toVector.size > 1 then
1764
+ Trace .buildStacktrace(trace, " The mutable state is created through: " + System .lineSeparator())
1765
+ else " "
1766
+
1760
1767
val mutateErrorSet : mutable.Set [(ClassSymbol , ClassSymbol )] = mutable.Set .empty
1761
- def errorMutateOtherStaticObject (currentObj : ClassSymbol , otherObj : ClassSymbol )(using Trace , Context ) =
1768
+ def errorMutateOtherStaticObject (currentObj : ClassSymbol , addr : Heap .Addr )(using Trace , Context ) =
1769
+ val otherObj = addr.owner
1770
+ val addr_trace = addr.getTrace
1762
1771
if mutateErrorSet.add((currentObj, otherObj)) then
1763
1772
val msg =
1764
1773
s " Mutating ${otherObj.show} during initialization of ${currentObj.show}. \n " +
1765
- " Mutating other static objects during the initialization of one static object is forbidden. " + Trace .show
1774
+ " Mutating other static objects during the initialization of one static object is forbidden. " + Trace .show +
1775
+ printTraceWhenMultiple(addr_trace)
1766
1776
1767
1777
report.warning(msg, Trace .position)
1768
1778
1769
1779
val readErrorSet : mutable.Set [(ClassSymbol , ClassSymbol )] = mutable.Set .empty
1770
- def errorReadOtherStaticObject (currentObj : ClassSymbol , otherObj : ClassSymbol )(using Trace , Context ) =
1780
+ def errorReadOtherStaticObject (currentObj : ClassSymbol , addr : Heap .Addr )(using Trace , Context ) =
1781
+ val otherObj = addr.owner
1782
+ val addr_trace = addr.getTrace
1771
1783
if readErrorSet.add((currentObj, otherObj)) then
1772
1784
val msg =
1773
1785
" Reading mutable state of " + otherObj.show + " during initialization of " + currentObj.show + " .\n " +
1774
- " Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. " + Trace .show
1786
+ " Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. " + Trace .show +
1787
+ printTraceWhenMultiple(addr_trace)
1775
1788
1776
1789
report.warning(msg, Trace .position)
0 commit comments