@@ -1452,9 +1452,11 @@ trait Applications extends Compatibility {
14521452 /** Is alternative `alt1` with type `tp1` as specific as alternative
14531453 * `alt2` with type `tp2` ?
14541454 *
1455- * 1. A method `alt1` of type (p1: T1, ..., pn: Tn)U is as specific as `alt2`
1456- * if `alt2` is applicable to arguments (p1, ..., pn) of types T1,...,Tn
1457- * or if `alt1` is nullary.
1455+ * 1. A method `alt1` of type `(p1: T1, ..., pn: Tn)U` is as specific as `alt2`
1456+ * if `alt1` is nullary or `alt2` is applicable to arguments (p1, ..., pn) of
1457+ * types T1,...,Tn. If the last parameter `pn` has a vararg type T*, then
1458+ * `alt1` must be applicable to arbitrary numbers of `T` parameters (which
1459+ * implies that it must be a varargs method as well).
14581460 * 2. A polymorphic member of type [a1 >: L1 <: U1, ..., an >: Ln <: Un]T is as
14591461 * specific as `alt2` of type `tp2` if T is as specific as `tp2` under the
14601462 * assumption that for i = 1,...,n each ai is an abstract type name bounded
@@ -1464,36 +1466,39 @@ trait Applications extends Compatibility {
14641466 * b. as specific as a member of any other type `tp2` if `tp1` is compatible
14651467 * with `tp2`.
14661468 */
1467- def isAsSpecific (alt1 : TermRef , tp1 : Type , alt2 : TermRef , tp2 : Type ): Boolean = trace(i " isAsSpecific $tp1 $tp2" , overload) { tp1 match {
1468- case tp1 : MethodType => // (1)
1469- val formals1 =
1470- if (tp1.isVarArgsMethod && tp2.isVarArgsMethod) tp1.paramInfos.map(_.repeatedToSingle)
1471- else tp1.paramInfos
1472- isApplicableMethodRef(alt2, formals1, WildcardType ) ||
1473- tp1.paramInfos.isEmpty && tp2.isInstanceOf [LambdaType ]
1474- case tp1 : PolyType => // (2)
1475- inContext(ctx.fresh.setExploreTyperState()) {
1476- // Fully define the PolyType parameters so that the infos of the
1477- // tparams created below never contain TypeRefs whose underling types
1478- // contain uninstantiated TypeVars, this could lead to cycles in
1479- // `isSubType` as a TypeVar might get constrained by a TypeRef it's
1480- // part of.
1481- val tp1Params = tp1.newLikeThis(tp1.paramNames, tp1.paramInfos, defn.AnyType )
1482- fullyDefinedType(tp1Params, " type parameters of alternative" , alt1.symbol.span)
1483-
1484- val tparams = newTypeParams(alt1.symbol, tp1.paramNames, EmptyFlags , tp1.instantiateParamInfos(_))
1485- isAsSpecific(alt1, tp1.instantiate(tparams.map(_.typeRef)), alt2, tp2)
1486- }
1487- case _ => // (3)
1488- tp2 match {
1489- case tp2 : MethodType => true // (3a)
1490- case tp2 : PolyType if tp2.resultType.isInstanceOf [MethodType ] => true // (3a)
1491- case tp2 : PolyType => // (3b)
1492- explore(isAsSpecificValueType(tp1, constrained(tp2).resultType))
1493- case _ => // (3b)
1494- isAsSpecificValueType(tp1, tp2)
1495- }
1496- }}
1469+ def isAsSpecific (alt1 : TermRef , tp1 : Type , alt2 : TermRef , tp2 : Type ): Boolean = trace(i " isAsSpecific $tp1 $tp2" , overload) {
1470+ tp1 match
1471+ case tp1 : MethodType => // (1)
1472+ tp1.paramInfos.isEmpty && tp2.isInstanceOf [LambdaType ]
1473+ || {
1474+ if tp1.isVarArgsMethod
1475+ tp2.isVarArgsMethod
1476+ && isApplicableMethodRef(alt2, tp1.paramInfos.map(_.repeatedToSingle), WildcardType )
1477+ else
1478+ isApplicableMethodRef(alt2, tp1.paramInfos, WildcardType )
1479+ }
1480+ case tp1 : PolyType => // (2)
1481+ inContext(ctx.fresh.setExploreTyperState()) {
1482+ // Fully define the PolyType parameters so that the infos of the
1483+ // tparams created below never contain TypeRefs whose underling types
1484+ // contain uninstantiated TypeVars, this could lead to cycles in
1485+ // `isSubType` as a TypeVar might get constrained by a TypeRef it's
1486+ // part of.
1487+ val tp1Params = tp1.newLikeThis(tp1.paramNames, tp1.paramInfos, defn.AnyType )
1488+ fullyDefinedType(tp1Params, " type parameters of alternative" , alt1.symbol.span)
1489+
1490+ val tparams = newTypeParams(alt1.symbol, tp1.paramNames, EmptyFlags , tp1.instantiateParamInfos(_))
1491+ isAsSpecific(alt1, tp1.instantiate(tparams.map(_.typeRef)), alt2, tp2)
1492+ }
1493+ case _ => // (3)
1494+ tp2 match
1495+ case tp2 : MethodType => true // (3a)
1496+ case tp2 : PolyType if tp2.resultType.isInstanceOf [MethodType ] => true // (3a)
1497+ case tp2 : PolyType => // (3b)
1498+ explore(isAsSpecificValueType(tp1, constrained(tp2).resultType))
1499+ case _ => // 3b)
1500+ isAsSpecificValueType(tp1, tp2)
1501+ }
14971502
14981503 /** Test whether value type `tp1` is as specific as value type `tp2`.
14991504 * Let's abbreviate this to `tp1 <:s tp2`.
0 commit comments