@@ -1452,9 +1452,11 @@ trait Applications extends Compatibility {
1452
1452
/** Is alternative `alt1` with type `tp1` as specific as alternative
1453
1453
* `alt2` with type `tp2` ?
1454
1454
*
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).
1458
1460
* 2. A polymorphic member of type [a1 >: L1 <: U1, ..., an >: Ln <: Un]T is as
1459
1461
* specific as `alt2` of type `tp2` if T is as specific as `tp2` under the
1460
1462
* assumption that for i = 1,...,n each ai is an abstract type name bounded
@@ -1464,36 +1466,39 @@ trait Applications extends Compatibility {
1464
1466
* b. as specific as a member of any other type `tp2` if `tp1` is compatible
1465
1467
* with `tp2`.
1466
1468
*/
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
+ }
1497
1502
1498
1503
/** Test whether value type `tp1` is as specific as value type `tp2`.
1499
1504
* Let's abbreviate this to `tp1 <:s tp2`.
0 commit comments