@@ -616,7 +616,7 @@ trait Applications extends Compatibility {
616616 * in a "can/cannot apply" answer, without needing to construct trees or
617617 * issue error messages.
618618 */
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 )
620620 extends Application [Arg ](methRef, funType, args, resultType) {
621621 type TypedArg = Arg
622622 type Result = Unit
@@ -633,7 +633,14 @@ trait Applications extends Compatibility {
633633 case SAMType (sam) => argtpe <:< sam.toFunctionType(isJava = formal.classSymbol.is(JavaDefined ))
634634 case _ => false
635635 }
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+ }
637644 }
638645
639646 /** The type of the given argument */
@@ -654,8 +661,8 @@ trait Applications extends Compatibility {
654661 /** Subclass of Application for applicability tests with type arguments and value
655662 * argument trees.
656663 */
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 ) {
659666 def argType (arg : Tree , formal : Type ): Type =
660667 if untpd.isContextualClosure(arg) && defn.isContextFunctionType(formal) then arg.tpe
661668 else normalize(arg.tpe, formal)
@@ -669,14 +676,14 @@ trait Applications extends Compatibility {
669676 * argument trees.
670677 */
671678 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 ) {
673680 override def argOK (arg : TypedArg , formal : Type ): Boolean =
674681 argType(arg, formal) relaxed_<:< formal.widenExpr
675682 }
676683
677684 /** 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 ) {
680687 def argType (arg : Type , formal : Type ): Type = arg
681688 def treeToArg (arg : Tree ): Type = arg.tpe
682689 def isVarArg (arg : Type ): Boolean = arg.isRepeatedParam
@@ -1323,13 +1330,14 @@ trait Applications extends Compatibility {
13231330 /** Is given method reference applicable to argument trees `args`?
13241331 * @param resultType The expected result type of the application
13251332 */
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 = {
13271334 def isApp (using Context ): Boolean =
1328- new ApplicableToTrees (methRef, args, resultType).success
1335+ new ApplicableToTrees (methRef, args, resultType, captureWild ).success
13291336 if (keepConstraint) isApp else explore(isApp)
13301337 }
13311338
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?
13331341 * @param resultType The expected result type of the application
13341342 */
13351343 def isDirectlyApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type )(using Context ): Boolean =
@@ -1338,23 +1346,23 @@ trait Applications extends Compatibility {
13381346 /** Is given method reference applicable to argument types `args`?
13391347 * @param resultType The expected result type of the application
13401348 */
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)
13431351
13441352 /** Is given type applicable to argument trees `args`, possibly after inserting an `apply`?
13451353 * @param resultType The expected result type of the application
13461354 */
13471355 def isApplicableType (tp : Type , args : List [Tree ], resultType : Type , keepConstraint : Boolean )(using Context ): Boolean =
13481356 onMethod(tp, args.nonEmpty) {
1349- isApplicableMethodRef(_, args, resultType, keepConstraint)
1357+ isApplicableMethodRef(_, args, resultType, keepConstraint, captureWild = false )
13501358 }
13511359
13521360 /** Is given type applicable to argument types `args`, possibly after inserting an `apply`?
13531361 * @param resultType The expected result type of the application
13541362 */
13551363 def isApplicableType (tp : Type , args : List [Type ], resultType : Type )(using Context ): Boolean =
13561364 onMethod(tp, args.nonEmpty) {
1357- isApplicableMethodRef(_, args, resultType)
1365+ isApplicableMethodRef(_, args, resultType, captureWild = false )
13581366 }
13591367
13601368 private def onMethod (tp : Type , followApply : Boolean )(p : TermRef => Boolean )(using Context ): Boolean = tp match {
@@ -1485,9 +1493,9 @@ trait Applications extends Compatibility {
14851493 || {
14861494 if tp1.isVarArgsMethod then
14871495 tp2.isVarArgsMethod
1488- && isApplicableMethodRef(alt2, tp1.paramInfos.map(_.repeatedToSingle), WildcardType )
1496+ && isApplicableMethodRef(alt2, tp1.paramInfos.map(_.repeatedToSingle), WildcardType , captureWild = false )
14891497 else
1490- isApplicableMethodRef(alt2, tp1.paramInfos, WildcardType )
1498+ isApplicableMethodRef(alt2, tp1.paramInfos, WildcardType , captureWild = false )
14911499 }
14921500 case tp1 : PolyType => // (2)
14931501 inContext(ctx.fresh.setExploreTyperState()) {
@@ -1695,7 +1703,7 @@ trait Applications extends Compatibility {
16951703 */
16961704 def adaptByResult (chosen : TermRef , alts : List [TermRef ]) = pt match {
16971705 case pt : FunProto if ! explore(resultConforms(chosen.symbol, chosen, pt.resultType)) =>
1698- val conformingAlts = alts.filter (alt =>
1706+ val conformingAlts = alts.filterConserve (alt =>
16991707 (alt ne chosen) && explore(resultConforms(alt.symbol, alt, pt.resultType)))
17001708 conformingAlts match {
17011709 case Nil => chosen
@@ -1796,7 +1804,7 @@ trait Applications extends Compatibility {
17961804 }
17971805
17981806 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 ))
18001808
18011809 /** Normalization steps before checking arguments:
18021810 *
@@ -1869,7 +1877,7 @@ trait Applications extends Compatibility {
18691877 )
18701878 if (alts2.isEmpty && ! ctx.isAfterTyper)
18711879 alts.filterConserve(alt =>
1872- isApplicableMethodRef(alt, args, resultType, keepConstraint = false )
1880+ isApplicableMethodRef(alt, args, resultType, keepConstraint = false , captureWild = true )
18731881 )
18741882 else
18751883 alts2
@@ -1890,7 +1898,7 @@ trait Applications extends Compatibility {
18901898 narrowByTrees(alts2, pt.typedArgs(normArg(alts2, _, _)), resultType)
18911899
18921900 case pt @ PolyProto (targs1, pt1) =>
1893- val alts1 = alts.filter (pt.canInstantiate)
1901+ val alts1 = alts.filterConserve (pt.canInstantiate)
18941902 if isDetermined(alts1) then alts1
18951903 else
18961904 def withinBounds (alt : TermRef ) = alt.widen match
@@ -1904,7 +1912,7 @@ trait Applications extends Compatibility {
19041912 narrowByTypes(alts, args, resultType)
19051913
19061914 case pt =>
1907- val compat = alts.filter (normalizedCompatible(_, pt, keepConstraint = false ))
1915+ val compat = alts.filterConserve (normalizedCompatible(_, pt, keepConstraint = false ))
19081916 if (compat.isEmpty)
19091917 /*
19101918 * the case should not be moved to the enclosing match
@@ -1967,15 +1975,15 @@ trait Applications extends Compatibility {
19671975 skipParamClause(pt.typedArgs().tpes, Nil ), resType)
19681976 case _ =>
19691977 // prefer alternatives that need no eta expansion
1970- val noCurried = alts.filter (! resultIsMethod(_))
1978+ val noCurried = alts.filterConserve (! resultIsMethod(_))
19711979 val noCurriedCount = noCurried.length
19721980 if noCurriedCount == 1 then
19731981 noCurried
19741982 else if noCurriedCount > 1 && noCurriedCount < alts.length then
19751983 resolveOverloaded1(noCurried, pt)
19761984 else
19771985 // prefer alternatves that match without default parameters
1978- val noDefaults = alts.filter (! _.symbol.hasDefaultParams)
1986+ val noDefaults = alts.filterConserve (! _.symbol.hasDefaultParams)
19791987 val noDefaultsCount = noDefaults.length
19801988 if noDefaultsCount == 1 then
19811989 noDefaults
0 commit comments