@@ -616,7 +616,7 @@ trait Applications extends Compatibility {
616
616
* in a "can/cannot apply" answer, without needing to construct trees or
617
617
* issue error messages.
618
618
*/
619
- abstract class TestApplication [Arg ](methRef : TermRef , funType : Type , args : List [Arg ], resultType : Type )(using Context )
619
+ abstract class TestApplication [Arg ](methRef : TermRef , funType : Type , args : List [Arg ], resultType : Type , captureWild : Boolean )(using Context )
620
620
extends Application [Arg ](methRef, funType, args, resultType) {
621
621
type TypedArg = Arg
622
622
type Result = Unit
@@ -633,7 +633,14 @@ trait Applications extends Compatibility {
633
633
case SAMType (sam) => argtpe <:< sam.toFunctionType(isJava = formal.classSymbol.is(JavaDefined ))
634
634
case _ => false
635
635
}
636
- isCompatible(argtpe, formal) || ctx.mode.is(Mode .ImplicitsEnabled ) && SAMargOK
636
+ isCompatible(argtpe, formal)
637
+ || ctx.mode.is(Mode .ImplicitsEnabled ) && SAMargOK
638
+ || captureWild
639
+ && {
640
+ val argtpe1 = argtpe.widen
641
+ val captured = captureWildcards(argtpe1)
642
+ (captured ne argtpe1) && (captured <:< formal.widenExpr)
643
+ }
637
644
}
638
645
639
646
/** The type of the given argument */
@@ -654,8 +661,8 @@ trait Applications extends Compatibility {
654
661
/** Subclass of Application for applicability tests with type arguments and value
655
662
* argument trees.
656
663
*/
657
- class ApplicableToTrees (methRef : TermRef , args : List [Tree ], resultType : Type )(using Context )
658
- extends TestApplication (methRef, methRef.widen, args, resultType) {
664
+ class ApplicableToTrees (methRef : TermRef , args : List [Tree ], resultType : Type , captureWild : Boolean )(using Context )
665
+ extends TestApplication (methRef, methRef.widen, args, resultType, captureWild ) {
659
666
def argType (arg : Tree , formal : Type ): Type =
660
667
if untpd.isContextualClosure(arg) && defn.isContextFunctionType(formal) then arg.tpe
661
668
else normalize(arg.tpe, formal)
@@ -669,14 +676,14 @@ trait Applications extends Compatibility {
669
676
* argument trees.
670
677
*/
671
678
class ApplicableToTreesDirectly (methRef : TermRef , args : List [Tree ], resultType : Type )(using Context )
672
- extends ApplicableToTrees (methRef, args, resultType) {
679
+ extends ApplicableToTrees (methRef, args, resultType, captureWild = false ) {
673
680
override def argOK (arg : TypedArg , formal : Type ): Boolean =
674
681
argType(arg, formal) relaxed_<:< formal.widenExpr
675
682
}
676
683
677
684
/** Subclass of Application for applicability tests with value argument types. */
678
- class ApplicableToTypes (methRef : TermRef , args : List [Type ], resultType : Type )(using Context )
679
- extends TestApplication (methRef, methRef, args, resultType) {
685
+ class ApplicableToTypes (methRef : TermRef , args : List [Type ], resultType : Type , captureWild : Boolean )(using Context )
686
+ extends TestApplication (methRef, methRef, args, resultType, captureWild ) {
680
687
def argType (arg : Type , formal : Type ): Type = arg
681
688
def treeToArg (arg : Tree ): Type = arg.tpe
682
689
def isVarArg (arg : Type ): Boolean = arg.isRepeatedParam
@@ -1323,13 +1330,14 @@ trait Applications extends Compatibility {
1323
1330
/** Is given method reference applicable to argument trees `args`?
1324
1331
* @param resultType The expected result type of the application
1325
1332
*/
1326
- def isApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type , keepConstraint : Boolean )(using Context ): Boolean = {
1333
+ def isApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type , keepConstraint : Boolean , captureWild : Boolean )(using Context ): Boolean = {
1327
1334
def isApp (using Context ): Boolean =
1328
- new ApplicableToTrees (methRef, args, resultType).success
1335
+ new ApplicableToTrees (methRef, args, resultType, captureWild ).success
1329
1336
if (keepConstraint) isApp else explore(isApp)
1330
1337
}
1331
1338
1332
- /** Is given method reference applicable to argument trees `args` without inferring views?
1339
+ /** Is given method reference applicable to argument trees `args` without inferring views
1340
+ * or capturing wildcards?
1333
1341
* @param resultType The expected result type of the application
1334
1342
*/
1335
1343
def isDirectlyApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type )(using Context ): Boolean =
@@ -1338,23 +1346,23 @@ trait Applications extends Compatibility {
1338
1346
/** Is given method reference applicable to argument types `args`?
1339
1347
* @param resultType The expected result type of the application
1340
1348
*/
1341
- def isApplicableMethodRef (methRef : TermRef , args : List [Type ], resultType : Type )(using Context ): Boolean =
1342
- explore(new ApplicableToTypes (methRef, args, resultType).success)
1349
+ def isApplicableMethodRef (methRef : TermRef , args : List [Type ], resultType : Type , captureWild : Boolean )(using Context ): Boolean =
1350
+ explore(new ApplicableToTypes (methRef, args, resultType, captureWild ).success)
1343
1351
1344
1352
/** Is given type applicable to argument trees `args`, possibly after inserting an `apply`?
1345
1353
* @param resultType The expected result type of the application
1346
1354
*/
1347
1355
def isApplicableType (tp : Type , args : List [Tree ], resultType : Type , keepConstraint : Boolean )(using Context ): Boolean =
1348
1356
onMethod(tp, args.nonEmpty) {
1349
- isApplicableMethodRef(_, args, resultType, keepConstraint)
1357
+ isApplicableMethodRef(_, args, resultType, keepConstraint, captureWild = false )
1350
1358
}
1351
1359
1352
1360
/** Is given type applicable to argument types `args`, possibly after inserting an `apply`?
1353
1361
* @param resultType The expected result type of the application
1354
1362
*/
1355
1363
def isApplicableType (tp : Type , args : List [Type ], resultType : Type )(using Context ): Boolean =
1356
1364
onMethod(tp, args.nonEmpty) {
1357
- isApplicableMethodRef(_, args, resultType)
1365
+ isApplicableMethodRef(_, args, resultType, captureWild = false )
1358
1366
}
1359
1367
1360
1368
private def onMethod (tp : Type , followApply : Boolean )(p : TermRef => Boolean )(using Context ): Boolean = tp match {
@@ -1485,9 +1493,9 @@ trait Applications extends Compatibility {
1485
1493
|| {
1486
1494
if tp1.isVarArgsMethod then
1487
1495
tp2.isVarArgsMethod
1488
- && isApplicableMethodRef(alt2, tp1.paramInfos.map(_.repeatedToSingle), WildcardType )
1496
+ && isApplicableMethodRef(alt2, tp1.paramInfos.map(_.repeatedToSingle), WildcardType , captureWild = false )
1489
1497
else
1490
- isApplicableMethodRef(alt2, tp1.paramInfos, WildcardType )
1498
+ isApplicableMethodRef(alt2, tp1.paramInfos, WildcardType , captureWild = false )
1491
1499
}
1492
1500
case tp1 : PolyType => // (2)
1493
1501
inContext(ctx.fresh.setExploreTyperState()) {
@@ -1695,7 +1703,7 @@ trait Applications extends Compatibility {
1695
1703
*/
1696
1704
def adaptByResult (chosen : TermRef , alts : List [TermRef ]) = pt match {
1697
1705
case pt : FunProto if ! explore(resultConforms(chosen.symbol, chosen, pt.resultType)) =>
1698
- val conformingAlts = alts.filter (alt =>
1706
+ val conformingAlts = alts.filterConserve (alt =>
1699
1707
(alt ne chosen) && explore(resultConforms(alt.symbol, alt, pt.resultType)))
1700
1708
conformingAlts match {
1701
1709
case Nil => chosen
@@ -1796,7 +1804,7 @@ trait Applications extends Compatibility {
1796
1804
}
1797
1805
1798
1806
def narrowByTypes (alts : List [TermRef ], argTypes : List [Type ], resultType : Type ): List [TermRef ] =
1799
- alts filter (isApplicableMethodRef(_, argTypes, resultType))
1807
+ alts.filterConserve (isApplicableMethodRef(_, argTypes, resultType, captureWild = true ))
1800
1808
1801
1809
/** Normalization steps before checking arguments:
1802
1810
*
@@ -1869,7 +1877,7 @@ trait Applications extends Compatibility {
1869
1877
)
1870
1878
if (alts2.isEmpty && ! ctx.isAfterTyper)
1871
1879
alts.filterConserve(alt =>
1872
- isApplicableMethodRef(alt, args, resultType, keepConstraint = false )
1880
+ isApplicableMethodRef(alt, args, resultType, keepConstraint = false , captureWild = true )
1873
1881
)
1874
1882
else
1875
1883
alts2
@@ -1890,7 +1898,7 @@ trait Applications extends Compatibility {
1890
1898
narrowByTrees(alts2, pt.typedArgs(normArg(alts2, _, _)), resultType)
1891
1899
1892
1900
case pt @ PolyProto (targs1, pt1) =>
1893
- val alts1 = alts.filter (pt.canInstantiate)
1901
+ val alts1 = alts.filterConserve (pt.canInstantiate)
1894
1902
if isDetermined(alts1) then alts1
1895
1903
else
1896
1904
def withinBounds (alt : TermRef ) = alt.widen match
@@ -1904,7 +1912,7 @@ trait Applications extends Compatibility {
1904
1912
narrowByTypes(alts, args, resultType)
1905
1913
1906
1914
case pt =>
1907
- val compat = alts.filter (normalizedCompatible(_, pt, keepConstraint = false ))
1915
+ val compat = alts.filterConserve (normalizedCompatible(_, pt, keepConstraint = false ))
1908
1916
if (compat.isEmpty)
1909
1917
/*
1910
1918
* the case should not be moved to the enclosing match
@@ -1967,15 +1975,15 @@ trait Applications extends Compatibility {
1967
1975
skipParamClause(pt.typedArgs().tpes, Nil ), resType)
1968
1976
case _ =>
1969
1977
// prefer alternatives that need no eta expansion
1970
- val noCurried = alts.filter (! resultIsMethod(_))
1978
+ val noCurried = alts.filterConserve (! resultIsMethod(_))
1971
1979
val noCurriedCount = noCurried.length
1972
1980
if noCurriedCount == 1 then
1973
1981
noCurried
1974
1982
else if noCurriedCount > 1 && noCurriedCount < alts.length then
1975
1983
resolveOverloaded1(noCurried, pt)
1976
1984
else
1977
1985
// prefer alternatves that match without default parameters
1978
- val noDefaults = alts.filter (! _.symbol.hasDefaultParams)
1986
+ val noDefaults = alts.filterConserve (! _.symbol.hasDefaultParams)
1979
1987
val noDefaultsCount = noDefaults.length
1980
1988
if noDefaultsCount == 1 then
1981
1989
noDefaults
0 commit comments