File tree Expand file tree Collapse file tree 2 files changed +41
-8
lines changed
src/dotty/tools/dotc/typer
test/dotty/tools/backend/jvm Expand file tree Collapse file tree 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 =>
228228
229229 /** Whether `liftFun` is needed? It is the case if default arguments are used.
230230 */
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+
232245 ! isJavaAnnotConstr(methRef.symbol) &&
233- args.size < reqiredArgNum(funType)
246+ args.size < requiredArgNum(funType)
247+ }
234248
235249 /** A flag signalling that the typechecking the application was so far successful */
236250 private [this ] var _ok = true
@@ -250,12 +264,6 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
250264 case tp => tp // was: funType
251265 }
252266
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-
259267 lazy val liftedFunType =
260268 if (needLiftFun) {
261269 liftFun()
Original file line number Diff line number Diff line change @@ -475,4 +475,29 @@ class TestBCode extends DottyBytecodeTest {
475475 diffInstructions(testInstructions, refInstructions))
476476 }
477477 }
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+ }
478503}
You can’t perform that action at this time.
0 commit comments