Skip to content

Commit 8d2f6c0

Browse files
Fix handling of lifted varargs in ElimRepeated
Fixes #15078
1 parent e4b63e3 commit 8d2f6c0

File tree

6 files changed

+339
-11
lines changed

6 files changed

+339
-11
lines changed

compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala

+14-10
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,21 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
124124
tp
125125

126126
override def transformApply(tree: Apply)(using Context): Tree =
127-
val args = tree.args.mapConserve {
128-
case arg: Typed if isWildcardStarArg(arg) =>
127+
val args = tree.args.mapConserve { arg =>
128+
if isWildcardStarArg(arg) then
129+
val expr = arg match
130+
case t: Typed => t.expr
131+
case _ => arg // if the argument has been lifted it's not a Typed (often it's an Ident)
132+
129133
val isJavaDefined = tree.fun.symbol.is(JavaDefined)
130-
val tpe = arg.expr.tpe
131134
if isJavaDefined then
132-
adaptToArray(arg.expr)
133-
else if tpe.derivesFrom(defn.ArrayClass) then
134-
arrayToSeq(arg.expr)
135+
adaptToArray(expr)
136+
else if expr.tpe.derivesFrom(defn.ArrayClass) then
137+
arrayToSeq(expr)
135138
else
136-
arg.expr
137-
case arg => arg
139+
expr
140+
else
141+
arg
138142
}
139143
cpy.Apply(tree)(tree.fun, args)
140144

@@ -287,9 +291,9 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
287291
val array = tp.translateFromRepeated(toArray = true) // Array[? <: T]
288292
val element = array.elemType.hiBound // T
289293

290-
291294
if element <:< defn.AnyRefType
292295
|| ctx.mode.is(Mode.SafeNulls) && element.stripNull <:< defn.AnyRefType
293-
|| element.typeSymbol.isPrimitiveValueClass then array
296+
|| element.typeSymbol.isPrimitiveValueClass
297+
then array
294298
else defn.ArrayOf(TypeBounds.upper(AndType(element, defn.AnyRefType))) // Array[? <: T & AnyRef]
295299
}

compiler/test/dotty/tools/dotc/coverage/CoverageTests.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,11 @@ class CoverageTests:
6868
def computeCoverageInTmp(inputFile: Path, sourceRoot: Path, run: Boolean)(using TestGroup): Path =
6969
val target = Files.createTempDirectory("coverage")
7070
val options = defaultOptions.and("-Ycheck:instrumentCoverage", "-coverage-out", target.toString, "-sourceroot", sourceRoot.toString)
71-
val test = compileFile(inputFile.toString, options)
7271
if run then
72+
val test = compileDir(inputFile.getParent.toString, options)
7373
test.checkRuns()
7474
else
75+
val test = compileFile(inputFile.toString, options)
7576
test.checkCompile()
7677
target
7778

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class JavaVarargs_1 {
2+
static void method(String... args) {}
3+
4+
static Object multiple(Object first, String... others) {
5+
return String.valueOf(first) + others.length;
6+
}
7+
}
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
first0
2+
first0
3+
first3
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import java.nio.file.Files
2+
import java.io.File
3+
4+
def repeated(s: String*) = ()
5+
6+
def f(s: String) = s
7+
8+
@main
9+
def Test =
10+
repeated()
11+
repeated(f(""), "b")
12+
JavaVarargs_1.method()
13+
JavaVarargs_1.method("")
14+
15+
var m = JavaVarargs_1.multiple("first")
16+
println(m)
17+
m = JavaVarargs_1.multiple(f("first"))
18+
println(m)
19+
m = JavaVarargs_1.multiple(f("first"), "a", "b", "c")
20+
println(m)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
# Coverage data, format version: 3.0
2+
# Statement data:
3+
# - id
4+
# - source path
5+
# - package name
6+
# - class name
7+
# - class type (Class, Object or Trait)
8+
# - full class name
9+
# - method name
10+
# - start offset
11+
# - end offset
12+
# - line number
13+
# - symbol name
14+
# - tree name
15+
# - is branch
16+
# - invocations count
17+
# - is ignored
18+
# - description (can be multi-line)
19+
# ' ' sign
20+
# ------------------------------------------
21+
0
22+
varargs/test_1.scala
23+
<empty>
24+
test_1$package$
25+
Object
26+
<empty>.test_1$package$
27+
repeated
28+
48
29+
60
30+
3
31+
repeated
32+
DefDef
33+
false
34+
0
35+
false
36+
def repeated
37+
38+
1
39+
varargs/test_1.scala
40+
<empty>
41+
test_1$package$
42+
Object
43+
<empty>.test_1$package$
44+
f
45+
79
46+
84
47+
5
48+
f
49+
DefDef
50+
false
51+
0
52+
false
53+
def f
54+
55+
2
56+
varargs/test_1.scala
57+
<empty>
58+
test_1$package$
59+
Object
60+
<empty>.test_1$package$
61+
Test
62+
120
63+
130
64+
9
65+
repeated
66+
Apply
67+
false
68+
0
69+
false
70+
repeated()
71+
72+
3
73+
varargs/test_1.scala
74+
<empty>
75+
test_1$package$
76+
Object
77+
<empty>.test_1$package$
78+
Test
79+
142
80+
147
81+
10
82+
f
83+
Apply
84+
false
85+
0
86+
false
87+
f("")
88+
89+
4
90+
varargs/test_1.scala
91+
<empty>
92+
test_1$package$
93+
Object
94+
<empty>.test_1$package$
95+
Test
96+
133
97+
153
98+
10
99+
repeated
100+
Apply
101+
false
102+
0
103+
false
104+
repeated(f(""), "b")
105+
106+
5
107+
varargs/test_1.scala
108+
<empty>
109+
test_1$package$
110+
Object
111+
<empty>.test_1$package$
112+
Test
113+
156
114+
178
115+
11
116+
method
117+
Apply
118+
false
119+
0
120+
false
121+
JavaVarargs_1.method()
122+
123+
6
124+
varargs/test_1.scala
125+
<empty>
126+
test_1$package$
127+
Object
128+
<empty>.test_1$package$
129+
Test
130+
181
131+
205
132+
12
133+
method
134+
Apply
135+
false
136+
0
137+
false
138+
JavaVarargs_1.method("")
139+
140+
7
141+
varargs/test_1.scala
142+
<empty>
143+
test_1$package$
144+
Object
145+
<empty>.test_1$package$
146+
Test
147+
217
148+
248
149+
14
150+
multiple
151+
Apply
152+
false
153+
0
154+
false
155+
JavaVarargs_1.multiple("first")
156+
157+
8
158+
varargs/test_1.scala
159+
<empty>
160+
test_1$package$
161+
Object
162+
<empty>.test_1$package$
163+
Test
164+
251
165+
261
166+
15
167+
println
168+
Apply
169+
false
170+
0
171+
false
172+
println(m)
173+
174+
9
175+
varargs/test_1.scala
176+
<empty>
177+
test_1$package$
178+
Object
179+
<empty>.test_1$package$
180+
Test
181+
291
182+
301
183+
16
184+
f
185+
Apply
186+
false
187+
0
188+
false
189+
f("first")
190+
191+
10
192+
varargs/test_1.scala
193+
<empty>
194+
test_1$package$
195+
Object
196+
<empty>.test_1$package$
197+
Test
198+
268
199+
302
200+
16
201+
multiple
202+
Apply
203+
false
204+
0
205+
false
206+
JavaVarargs_1.multiple(f("first"))
207+
208+
11
209+
varargs/test_1.scala
210+
<empty>
211+
test_1$package$
212+
Object
213+
<empty>.test_1$package$
214+
Test
215+
305
216+
315
217+
17
218+
println
219+
Apply
220+
false
221+
0
222+
false
223+
println(m)
224+
225+
12
226+
varargs/test_1.scala
227+
<empty>
228+
test_1$package$
229+
Object
230+
<empty>.test_1$package$
231+
Test
232+
345
233+
355
234+
18
235+
f
236+
Apply
237+
false
238+
0
239+
false
240+
f("first")
241+
242+
13
243+
varargs/test_1.scala
244+
<empty>
245+
test_1$package$
246+
Object
247+
<empty>.test_1$package$
248+
Test
249+
322
250+
371
251+
18
252+
multiple
253+
Apply
254+
false
255+
0
256+
false
257+
JavaVarargs_1.multiple(f("first"), "a", "b", "c")
258+
259+
14
260+
varargs/test_1.scala
261+
<empty>
262+
test_1$package$
263+
Object
264+
<empty>.test_1$package$
265+
Test
266+
374
267+
384
268+
19
269+
println
270+
Apply
271+
false
272+
0
273+
false
274+
println(m)
275+
276+
15
277+
varargs/test_1.scala
278+
<empty>
279+
test_1$package$
280+
Object
281+
<empty>.test_1$package$
282+
Test
283+
101
284+
115
285+
8
286+
Test
287+
DefDef
288+
false
289+
0
290+
false
291+
@main
292+
def Test
293+

0 commit comments

Comments
 (0)