File tree 2 files changed +41
-8
lines changed
src/dotty/tools/dotc/typer
test/dotty/tools/backend/jvm
2 files changed +41
-8
lines changed Original file line number Diff line number Diff line change @@ -228,9 +228,23 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
228
228
229
229
/** Whether `liftFun` is needed? It is the case if default arguments are used.
230
230
*/
231
- protected def needLiftFun : Boolean =
231
+ protected def needLiftFun : Boolean = {
232
+ def requiredArgNum (tp : Type ): Int = tp.widen match {
233
+ case funType : MethodType =>
234
+ val paramInfos = funType.paramInfos
235
+ val argsNum = paramInfos.size
236
+ if (argsNum >= 1 && paramInfos.last.isRepeatedParam)
237
+ // Repeated arguments do not count as required arguments
238
+ argsNum - 1
239
+ else
240
+ argsNum
241
+ case funType : PolyType => requiredArgNum(funType.resultType)
242
+ case tp => args.size
243
+ }
244
+
232
245
! isJavaAnnotConstr(methRef.symbol) &&
233
- args.size < reqiredArgNum(funType)
246
+ args.size < requiredArgNum(funType)
247
+ }
234
248
235
249
/** A flag signalling that the typechecking the application was so far successful */
236
250
private [this ] var _ok = true
@@ -250,12 +264,6 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
250
264
case tp => tp // was: funType
251
265
}
252
266
253
- def reqiredArgNum (tp : Type ): Int = tp.widen match {
254
- case funType : MethodType => funType.paramInfos.size
255
- case funType : PolyType => reqiredArgNum(funType.resultType)
256
- case tp => args.size
257
- }
258
-
259
267
lazy val liftedFunType =
260
268
if (needLiftFun) {
261
269
liftFun()
Original file line number Diff line number Diff line change @@ -475,4 +475,29 @@ class TestBCode extends DottyBytecodeTest {
475
475
diffInstructions(testInstructions, refInstructions))
476
476
}
477
477
}
478
+
479
+ /** Test that the receiver of a call to a method with varargs is not unnecessarily lifted */
480
+ @ Test def i5191 = {
481
+ val source =
482
+ """ class Test {
483
+ | def foo(args: String*): String = ""
484
+ | def self = this
485
+ |
486
+ | def test = self.foo()
487
+ |}
488
+ """ .stripMargin
489
+
490
+ checkBCode(source) { dir =>
491
+ val clsIn = dir.lookupName(" Test.class" , directory = false ).input
492
+ val clsNode = loadClassNode(clsIn)
493
+ val method = getMethod(clsNode, " test" )
494
+
495
+ val liftReceiver = instructionsFromMethod(method).exists {
496
+ case VarOp (Opcodes .ASTORE , _) => true // receiver lifted in local val
497
+ case _ => false
498
+ }
499
+ assertFalse(" Receiver of a call to a method with varargs is unnecessarily lifted" ,
500
+ liftReceiver)
501
+ }
502
+ }
478
503
}
You can’t perform that action at this time.
0 commit comments