Skip to content

Commit 3d539e6

Browse files
authored
Make Array.apply an intrinsic (#18537)
Make `Array.apply` an intrinsic
2 parents cc40aca + 9e80e94 commit 3d539e6

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

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

+18-14
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ object Objects:
470470

471471
/** Store the heap as a mutable field to avoid threading it through the program. */
472472
class MutableData(private[Heap] var heap: Data):
473-
private[Heap] def update(addr: Addr, value: Value): Unit =
473+
private[Heap] def writeJoin(addr: Addr, value: Value): Unit =
474474
heap.get(addr) match
475475
case None =>
476476
heap = heap.updated(addr, value)
@@ -479,7 +479,7 @@ object Objects:
479479
val value2 = value.join(current)
480480
if value2 != current then
481481
heap = heap.updated(addr, value2)
482-
482+
end MutableData
483483

484484
def empty(): MutableData = new MutableData(Map.empty)
485485

@@ -489,8 +489,8 @@ object Objects:
489489
def read(addr: Addr)(using mutable: MutableData): Value =
490490
mutable.heap(addr)
491491

492-
def write(addr: Addr, value: Value)(using mutable: MutableData): Unit =
493-
mutable.update(addr, value)
492+
def writeJoin(addr: Addr, value: Value)(using mutable: MutableData): Unit =
493+
mutable.writeJoin(addr, value)
494494

495495
def localVarAddr(regions: Regions.Data, sym: Symbol, owner: ClassSymbol): Addr =
496496
LocalVarAddr(regions, sym, owner)
@@ -616,7 +616,7 @@ object Objects:
616616
* @param superType The type of the super in a super call. NoType for non-super calls.
617617
* @param needResolve Whether the target of the call needs resolution?
618618
*/
619-
def call(value: Value, meth: Symbol, args: List[ArgInfo], receiver: Type, superType: Type, needResolve: Boolean = true): Contextual[Value] = log("call " + meth.show + ", args = " + args.map(_.value.show), printer, (_: Value).show) {
619+
def call(value: Value, meth: Symbol, args: List[ArgInfo], receiver: Type, superType: Type, needResolve: Boolean = true): Contextual[Value] = log("call " + meth.show + ", this = " + value.show + ", args = " + args.map(_.value.show), printer, (_: Value).show) {
620620
value match
621621
case Cold =>
622622
report.warning("Using cold alias. Calling trace:\n" + Trace.show, Trace.position)
@@ -639,7 +639,7 @@ object Objects:
639639
if arr.addr.owner != State.currentObject then
640640
errorMutateOtherStaticObject(State.currentObject, arr.addr.owner)
641641
else
642-
Heap.write(arr.addr, args.tail.head.value)
642+
Heap.writeJoin(arr.addr, args.tail.head.value)
643643
Bottom
644644
else
645645
// Array.length is OK
@@ -658,7 +658,11 @@ object Objects:
658658
resolve(ref.klass, meth)
659659

660660
if target.isOneOf(Flags.Method) then
661-
if target.hasSource then
661+
if target.owner == defn.ArrayModuleClass && target.name == nme.apply then
662+
val arr = OfArray(State.currentObject, summon[Regions.Data])
663+
Heap.writeJoin(arr.addr, args.map(_.value).join)
664+
arr
665+
else if target.hasSource then
662666
val cls = target.owner.enclosingClass.asClass
663667
val ddef = target.defTree.asInstanceOf[DefDef]
664668
val meth = ddef.symbol
@@ -842,7 +846,7 @@ object Objects:
842846
if addr.owner != State.currentObject then
843847
errorMutateOtherStaticObject(State.currentObject, addr.owner)
844848
else
845-
Heap.write(addr, rhs)
849+
Heap.writeJoin(addr, rhs)
846850
else
847851
report.warning("Mutating a field before its initialization: " + field.show + ". Calling trace:\n" + Trace.show, Trace.position)
848852
end match
@@ -867,7 +871,7 @@ object Objects:
867871
case outer: (Ref | Cold.type | Bottom.type) =>
868872
if klass == defn.ArrayClass then
869873
val arr = OfArray(State.currentObject, summon[Regions.Data])
870-
Heap.write(arr.addr, Bottom)
874+
Heap.writeJoin(arr.addr, Bottom)
871875
arr
872876
else
873877
// Widen the outer to finitize the domain. Arguments already widened in `evalArgs`.
@@ -903,7 +907,7 @@ object Objects:
903907
if sym.is(Flags.Mutable) then
904908
val addr = Heap.localVarAddr(summon[Regions.Data], sym, State.currentObject)
905909
Env.setLocalVar(sym, addr)
906-
Heap.write(addr, value)
910+
Heap.writeJoin(addr, value)
907911
else
908912
Env.setLocalVal(sym, value)
909913
}
@@ -964,8 +968,8 @@ object Objects:
964968
* @param value The value of the rhs of the assignment.
965969
*/
966970
def writeLocal(thisV: ThisValue, sym: Symbol, value: Value): Contextual[Value] = log("write local " + sym.show + " with " + value.show, printer, (_: Value).show) {
967-
968971
assert(sym.is(Flags.Mutable), "Writing to immutable variable " + sym.show)
972+
969973
Env.resolveEnv(sym.enclosingMethod, thisV, summon[Env.Data]) match
970974
case Some(thisV -> env) =>
971975
given Env.Data = env
@@ -974,7 +978,7 @@ object Objects:
974978
if addr.owner != State.currentObject then
975979
errorMutateOtherStaticObject(State.currentObject, addr.owner)
976980
else
977-
Heap.write(addr, value)
981+
Heap.writeJoin(addr, value)
978982
case _ =>
979983
report.warning("[Internal error] Variable not found " + sym.show + "\nenv = " + env.show + ". Calling trace:\n" + Trace.show, Trace.position)
980984

@@ -1537,7 +1541,7 @@ object Objects:
15371541
if acc.is(Flags.Mutable) then
15381542
val addr = Heap.fieldVarAddr(summon[Regions.Data], acc, State.currentObject)
15391543
thisV.initVar(acc, addr)
1540-
Heap.write(addr, value)
1544+
Heap.writeJoin(addr, value)
15411545
else
15421546
thisV.initVal(acc, value)
15431547
printer.println(acc.show + " initialized with " + value)
@@ -1632,7 +1636,7 @@ object Objects:
16321636
if sym.is(Flags.Mutable) then
16331637
val addr = Heap.fieldVarAddr(summon[Regions.Data], sym, State.currentObject)
16341638
thisV.initVar(sym, addr)
1635-
Heap.write(addr, res)
1639+
Heap.writeJoin(addr, res)
16361640
else
16371641
thisV.initVal(sym, res)
16381642

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
object A:
2+
class Box(var value: Int)
3+
val box: Box = new Box(0)
4+
5+
object B:
6+
val boxes: Array[A.Box] = Array(A.box)
7+
val box: A.Box = boxes(0)
8+
val x: Int = box.value // error

0 commit comments

Comments
 (0)