Skip to content

Commit 673a38d

Browse files
committed
vcArrays: fix for arrays of value classes with array as underlying type
1 parent 0c0f566 commit 673a38d

File tree

4 files changed

+74
-6
lines changed

4 files changed

+74
-6
lines changed

src/dotty/tools/dotc/transform/VCArrays.scala

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,18 @@ class VCArrays extends MiniPhaseTransform with InfoTransformer {
2525

2626
private def eraseVCArrays(tp: Type)(implicit ctx: Context): Type = {
2727
val transform = new TypeMap {
28-
//TODO: rewrite, don't create TypeMap for each invocation of eraseVCArrays
28+
//TODO: rewrite, don't create new TypeMap for each invocation of eraseVCArrays
2929
def apply(tp: Type) = mapOver {
3030
tp match {
31-
case JavaArrayType(ErasedValueType(tr, _)) =>
31+
case JavaArrayType(ErasedValueType(tr, eund)) =>
3232
val cls = tr.symbol.asClass
3333
defn.vcArrayOf(cls).typeRef
34+
//case tp: MethodType =>
35+
//val paramTypes = tp.paramTypes.mapConserve(eraseVCArrays)
36+
//val retType = eraseVCArrays(tp.resultType)
37+
//tp.derivedMethodType(tp.paramNames, paramTypes, retType)
38+
case ErasedValueType(tr, und) =>
39+
ErasedValueType(tr, eraseVCArrays(und))
3440
case _ =>
3541
tp
3642
}
@@ -121,12 +127,14 @@ class VCArrays extends MiniPhaseTransform with InfoTransformer {
121127
if (fun.symbol == defn.newArrayMethod) =>
122128
val Literal(Constant(ins)) = retTpt
123129
ins match {
124-
case JavaArrayType(ErasedValueType(tr, underlying)) =>
130+
case jat@JavaArrayType(ErasedValueType(tr, underlying)) =>
125131
val cls = tr.symbol.asClass
126132
val mod = cls.companionModule
127-
val arTpe = JavaArrayType(underlying)
133+
//TODO: und1 should be processed in case of EVT
134+
val und1 = eraseVCArrays(underlying)
135+
val arTpe = jat.derivedJavaArrayType(und1)
128136
New(defn.vcArrayOf(cls).typeRef,
129-
List(newArray(underlying, arTpe, tree.pos, dims.asInstanceOf[JavaSeqLiteral]).ensureConforms(arTpe),
137+
List(newArray(und1, arTpe, tree.pos, dims.asInstanceOf[JavaSeqLiteral]).ensureConforms(arTpe),
130138
ref(mod)))
131139
case _: Type =>
132140
val evtOpt = isArrayWithEVT(ins)
@@ -138,7 +146,8 @@ class VCArrays extends MiniPhaseTransform with InfoTransformer {
138146
val Literal(Constant(compTptType)) = compTpt
139147
val compTpt2 = eraseVCArrays((compTptType.asInstanceOf[Type]))
140148
newArray(compTpt2, retTpt2, tree.pos, dims.asInstanceOf[JavaSeqLiteral])
141-
case _ => tree
149+
case _ =>
150+
transformTypeOfTree(tree)
142151
}
143152
}
144153
// array.[]update(idx, elem) => array.arr().[]update(idx, elem)

test/dotc/tests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ class tests extends CompilerTest {
117117
@Test def pos_vc_array_caseclasses = compileFile(runDir, "valueclasses-array-caseclasses", args = "-Ycheck:all" :: Nil)
118118
@Test def pos_vc_array_arrayops = compileFile(runDir, "valueclasses-array-arrayops", args = "-Ycheck:all" :: Nil)
119119
@Test def pos_vc_array_array = compileFile(runDir, "valueclasses-array-array", args = "-Ycheck:all" :: Nil)
120+
@Test def pos_vc_array_und_array = compileFile(runDir, "valueclasses-array-und-array", args = "-Ycheck:all" :: Nil)
120121

121122
@Test def pos_all = compileFiles(posDir) // twice omitted to make tests run faster
122123

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
1
2+
1
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import scala.collection.mutable._
2+
class X(val x: Array[Y]) extends AnyVal
3+
class X0(val x: Array[Y0]) extends AnyVal
4+
class X00(val x: Array[Array[Y0]]) extends AnyVal
5+
class X2(val x: Array[Y2]) extends AnyVal
6+
class X3(val x: Array[Y3]) extends AnyVal
7+
class Y3(val x: Int) extends AnyVal
8+
class Y0(val a: Int) extends AnyVal
9+
class Y(val a: Array[X])
10+
class Y2(val a: Int) extends AnyVal
11+
class Z(val y: Y) extends AnyVal
12+
13+
object Test {
14+
def main(args: Array[String]) = {
15+
val ar0 = new Array[X](3)
16+
ar0(0) = new X(Array(new Y(Array(new X(Array())))))
17+
ar0(1) = new X(new Array[Y](4))
18+
val ar01 = new Array[X00](5)
19+
val ar011: Array[X00] = null
20+
val ar02 = Array(new X00(Array(Array(new Y0(7)))))
21+
22+
val y1 = Array(new Y(Array(new X(Array(new Y(new Array[X](2)), new Y(Array(new X(new Array[Y](4)))))))))
23+
val y2 = y1(0)
24+
25+
val z1 = Array(Array(new Y(Array(new X(Array(new Y(new Array[X](2)), new Y(Array(new X(new Array[Y](4))))))))))
26+
val z2 = z1(0)
27+
val z3 = z1(0)(0)
28+
val z4 = z2(0)
29+
println(z1.size)
30+
println(z2.size)
31+
32+
val y10 = Array(new X0(Array(new Y0(4), new Y0(3))))
33+
val y11 = Array(new X0(new Array[Y0](5)))
34+
val y20 = y10(0)
35+
36+
val z10 = Array(Array(new X0(Array(new Y0(4), new Y0(3)))))
37+
val z11 = Array(Array(new X0(new Array[Y0](5))))
38+
val z20 = z10(0)
39+
val z30 = z10(0)(0)
40+
val z40 = z20(0)
41+
42+
z10 map (x => Array(x(0)))
43+
y10 map (x => x)
44+
45+
val ar = Array(new X0(Array(new Y0(1))))
46+
47+
val ar2 = Array(new X(Array(new Y(Array[X](new X( new Array[Y](5)))))))
48+
49+
val t = new X3(Array(new Y3(1)))
50+
t.toString
51+
val t2 = new X3(new Array[Y3](4))
52+
53+
val ar3 = Array(new X2(new Array[Y2](3)))
54+
val ar4 = Array(new X2(Array(new Y2(3))))
55+
}
56+
}

0 commit comments

Comments
 (0)