Skip to content

Commit 1f3f7e7

Browse files
committed
add more vararg tests
1 parent c680f7d commit 1f3f7e7

File tree

6 files changed

+248
-118
lines changed

6 files changed

+248
-118
lines changed

compiler/src/dotty/tools/dotc/typer/Dynamic.scala

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -185,23 +185,20 @@ trait Dynamic {
185185
val vargss = termArgss(tree)
186186

187187
def handleRepeated(base: untpd.Tree, possiblyCurried: List[List[Tree]], isReflectSelectable: Boolean) = {
188-
val handled = possiblyCurried.map { args =>
189-
val isRepeated = args.exists(_.tpe.widen.isRepeatedParam)
190-
if isRepeated && isReflectSelectable then
191-
List(untpd.TypedSplice(tpd.repeatedSeq(args, TypeTree(defn.AnyType))))
192-
else args.map { t =>
193-
val clzSym = t.tpe.resultType.classSymbol.asClass
194-
if ValueClasses.isDerivedValueClass(clzSym) && isReflectSelectable then
195-
val underlying = ValueClasses.valueClassUnbox(clzSym).asTerm
196-
tpd.Select(t, underlying.name)
197-
else
198-
t
199-
}.map(untpd.TypedSplice(_))
188+
val args = possiblyCurried.flatten.map { t =>
189+
val clzSym = t.tpe.resultType.classSymbol.asClass
190+
if clzSym.isDerivedValueClass && isReflectSelectable then
191+
val underlying = ValueClasses.valueClassUnbox(clzSym).asTerm
192+
tpd.Select(t, underlying.name)
193+
else
194+
t
200195
}
196+
val handledFlat =
197+
if isReflectSelectable then List(untpd.TypedSplice(tpd.repeatedSeq(args, TypeTree(defn.AnyType))))
198+
else if args.isEmpty then List()
199+
else List(untpd.TypedSplice(tpd.repeatedSeq(args, TypeTree(args.map(_.tpe).reduce(_ | _)))))
201200

202-
if isReflectSelectable
203-
then untpd.Apply(base, handled.flatten)
204-
else handled.foldLeft(base)((base, args) => untpd.Apply(base, args))
201+
untpd.Apply(base, handledFlat)
205202
}
206203

207204
def structuralCall(selectorName: TermName, classOfs: => List[Tree]) = {
@@ -265,7 +262,7 @@ trait Dynamic {
265262
*/
266263
def maybeBoxingCast(tpe: Type) =
267264
val maybeBoxed =
268-
if tpe.classSymbol.isDerivedValueClass && qual.tpe <:< defn.ReflectSelectableTypeRef then
265+
if tpe.classSymbol.isDerivedValueClass && qual.tpe.isReflectSelectableTypeRef then
269266
val genericUnderlying = ValueClasses.valueClassUnbox(tpe.classSymbol.asClass)
270267
val underlying = tpe.select(genericUnderlying).widen.resultType
271268
New(tpe.widen, tree.cast(underlying) :: Nil)
@@ -295,7 +292,7 @@ trait Dynamic {
295292
fail(i"has a parameter type with an unstable erasure") :: Nil
296293
else
297294
TypeErasure.erasure(tpe).asInstanceOf[MethodType].paramInfos.map { tpe =>
298-
if ValueClasses.isDerivedValueClass(tpe.widen.classSymbol) then
295+
if tpe.widen.classSymbol.isDerivedValueClass then
299296
clsOf(ValueClasses.valueClassUnbox(tpe.classSymbol.asClass).info)
300297
else
301298
clsOf(tpe)

tests/pos/i17100.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ trait Sel extends Selectable
22

33
extension (s: Sel)
44
def selectDynamic(name: String) = ???
5-
def applyDynamic(name: String)(x: Int) = ???
5+
def applyDynamic(name: String)(x: Int*) = ???
66
def applyDynamic(name: String)() = ???
77

88
val sel = (new Sel {}).asInstanceOf[Sel{ def foo: String; def bar(x: Int): Int; def baz(): Int }]

tests/run/i14340.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
class Container1 extends reflect.Selectable
22

3-
class Container2(values: Map[String, Any], methods: Map[String, Int => Any]) extends Selectable:
3+
class Container2(values: Map[String, Any], methods: Map[String, Seq[Int] => Any]) extends Selectable:
44
def selectDynamic(name: String) = values(name)
5-
def applyDynamic(name: String)(arg: Int) = methods(name)(arg)
5+
def applyDynamic(name: String)(arg: Int*) = methods(name)(arg)
66

77
class Foo(val value: Int) extends AnyVal
88
class Bar[A](val value: A) extends AnyVal
@@ -29,7 +29,7 @@ object Helpers:
2929
)
3030

3131
val cont2methods = Map(
32-
"fooFromInt" -> { (i: Int) => Foo(i) }
32+
"fooFromInt" -> { (i: Seq[Int]) => Foo(i.head) }
3333
)
3434

3535
val cont2 = Container2(cont2values, cont2methods).asInstanceOf[Container2 {
@@ -39,7 +39,7 @@ object Helpers:
3939
def qux2: Bar[Container2 { def foo: Foo }]
4040
def fooFromInt(i: Int): Foo
4141
}]
42-
42+
4343

4444
println(cont1.foo.value)
4545
println(cont2.foo.value)
@@ -49,7 +49,7 @@ object Helpers:
4949

5050
println(cont1.qux1.value.foo.value)
5151
println(cont2.qux1.value.foo.value)
52-
52+
5353
println(cont1.qux2.value.foo.value)
5454
println(cont2.qux2.value.foo.value)
5555

tests/run/i16995.check

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,62 @@
1-
1
2-
check
3-
6
4-
7
5-
5
6-
3
7-
3
8-
3
9-
7
10-
3
1+
foo
2+
foo0
3+
fooI 1
4+
fooN 1
5+
fooII 1 2
6+
fooNN 1 2
7+
fooIvarargs 1 2
8+
fooNvarargs 1 2
9+
fooIseq 1 2
10+
fooNseq 1 2
11+
fooIIvarargs 1 2
12+
fooNNvarargs 1 2
13+
fooI_I 1 2
14+
fooN_N 1 2
15+
foo0_II 1 2
16+
foo0_NN 1 2
17+
foo0_Ivarargs 1 2
18+
foo0_Nvarargs 1 2
19+
foo0_I_I 1 2
20+
foo0_N_N 1 2
21+
22+
foo
23+
foo0
24+
fooI 1
25+
fooN 1
26+
fooII 1 2
27+
fooNN 1 2
28+
fooIvarargs 1 2
29+
fooNvarargs 1 2
30+
fooIseq 1 2
31+
fooNseq 1 2
32+
fooIIvarargs 1 2 3
33+
fooNNvarargs 1 2
34+
fooI_I 1 2
35+
fooN_N 1 2
36+
foo0_II 1 2
37+
foo0_NN 1 2
38+
foo0_Ivarargs 1 2
39+
foo0_Nvarargs 1 2
40+
foo0_I_I 1 2
41+
foo0_N_N 1 2
42+
43+
foo
44+
foo0
45+
fooI 1
46+
fooN 1
47+
fooII 1 2
48+
fooNN 1 2
49+
fooIvarargs 1 2
50+
fooNvarargs 1 2
51+
fooIseq 1 2
52+
fooNseq 1 2
53+
fooIIvarargs 1 2
54+
fooNNvarargs 1 2
55+
fooI_I 1 2
56+
fooN_N 1 2
57+
foo0_II 1 2
58+
foo0_NN 1 2
59+
foo0_Ivarargs 1 2
60+
foo0_Nvarargs 1 2
61+
foo0_I_I 1 2
62+
foo0_N_N 1 2

0 commit comments

Comments
 (0)