@@ -1293,7 +1293,15 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
12931293 val formals1 =
12941294 if (tp1.isVarArgsMethod && tp2.isVarArgsMethod) tp1.paramInfos.map(_.repeatedToSingle)
12951295 else tp1.paramInfos
1296- isApplicable(alt2, formals1, WildcardType ) ||
1296+
1297+ class IsAsSpecific (methRef : TermRef , args : List [Type ], resultType : Type )(implicit ctx : Context )
1298+ extends ApplicableToTypes (methRef, args, resultType) {
1299+ override def argOK (arg : TypedArg , formal : Type ): Boolean =
1300+ // simulate X* not being in subtyping relationship with any other type
1301+ ! (arg.isRepeatedParam || formal.isRepeatedParam) && super .argOK(arg, formal)
1302+ }
1303+
1304+ ctx.test(ctx => new IsAsSpecific (alt2, formals1, WildcardType )(ctx).success) ||
12971305 tp1.paramInfos.isEmpty && tp2.isInstanceOf [LambdaType ]
12981306 case tp1 : PolyType => // (2)
12991307 val nestedCtx = ctx.fresh.setExploreTyperState()
@@ -1420,24 +1428,45 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
14201428 if (winsType1 || ! winsType2) 1 else 0
14211429 else if (ownerScore == - 1 )
14221430 if (winsType2 || ! winsType1) - 1 else 0
1423- else if (winsType1)
1431+ else if (winsType1)
14241432 if (winsType2) 0 else 1
14251433 else
14261434 if (winsType2) - 1 else 0
14271435 }
14281436
1429- val fullType1 = widenImplied(alt1.widen, alt1)
1430- val fullType2 = widenImplied(alt2.widen, alt2)
1437+ def paramInfos (tp : Type ): List [Type ] = tp.stripPoly match {
1438+ case mt : MethodType => mt.paramInfos
1439+ case _ => Nil
1440+ }
1441+
1442+ @ annotation.tailrec def lengthCompare (xs : List [_], ys : List [_]): Int = (xs, ys) match {
1443+ case (_ :: xs, _ :: ys) => lengthCompare(xs, ys)
1444+ case (Nil , Nil ) => 0
1445+ case (_, Nil ) => 1
1446+ case (Nil , _) => - 1
1447+ }
1448+
1449+ val wideAlt1 = alt1.widen
1450+ val wideAlt2 = alt2.widen
1451+ val fullType1 = widenImplied(wideAlt1, alt1)
1452+ val fullType2 = widenImplied(wideAlt2, alt2)
14311453 val strippedType1 = stripImplicit(fullType1)
14321454 val strippedType2 = stripImplicit(fullType2)
14331455
14341456 val result = compareWithTypes(strippedType1, strippedType2)
1435- if (result != 0 ) result
1436- else if (strippedType1 eq fullType1)
1437- if (strippedType2 eq fullType2) 0 // no implicits either side: its' a draw
1438- else 1 // prefer 1st alternative with no implicits
1439- else if (strippedType2 eq fullType2) - 1 // prefer 2nd alternative with no implicits
1440- else compareWithTypes(fullType1, fullType2) // continue by comparing implicits parameters
1457+ if (result != 0 ) result else {
1458+ val varArgLengthTiebreaker =
1459+ if (wideAlt1.isVarArgsMethod || wideAlt2.isVarArgsMethod)
1460+ lengthCompare(paramInfos(wideAlt1), paramInfos(wideAlt2))
1461+ else 0
1462+
1463+ if (varArgLengthTiebreaker != 0 ) varArgLengthTiebreaker
1464+ else if (strippedType1 eq fullType1)
1465+ if (strippedType2 eq fullType2) 0 // no implicits either side: its' a draw
1466+ else 1 // prefer 1st alternative with no implicits
1467+ else if (strippedType2 eq fullType2) - 1 // prefer 2nd alternative with no implicits
1468+ else compareWithTypes(fullType1, fullType2) // continue by comparing implicits parameters
1469+ }
14411470 }}
14421471
14431472 def narrowMostSpecific (alts : List [TermRef ])(implicit ctx : Context ): List [TermRef ] = track(" narrowMostSpecific" ) {
@@ -1674,6 +1703,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
16741703 candidates.flatMap(cloneCandidate)
16751704 }
16761705
1706+ import config .Printers .debug
1707+ debug.println(i " candidates= \n\t $candidates% \n\t % " )
16771708 val found = narrowMostSpecific(candidates)
16781709 if (found.length <= 1 ) found
16791710 else pt match {
0 commit comments