@@ -612,18 +612,24 @@ trait Applications extends Compatibility {
612612 }
613613 }
614614
615+ /** The degree to which an argument has to match a formal parameter */
616+ enum ArgMatch :
617+ case SubType // argument is a relaxed subtype of formal
618+ case Compatible // argument is compatible with formal
619+ case CompatibleCAP // capture-converted argument is compatible with formal
620+
615621 /** Subclass of Application for the cases where we are interested only
616622 * in a "can/cannot apply" answer, without needing to construct trees or
617623 * issue error messages.
618624 */
619- abstract class TestApplication [Arg ](methRef : TermRef , funType : Type , args : List [Arg ], resultType : Type , captureWild : Boolean )(using Context )
625+ abstract class TestApplication [Arg ](methRef : TermRef , funType : Type , args : List [Arg ], resultType : Type , argMatch : ArgMatch )(using Context )
620626 extends Application [Arg ](methRef, funType, args, resultType) {
621627 type TypedArg = Arg
622628 type Result = Unit
623629
624630 def applyKind = ApplyKind .Regular
625631
626- protected def argOK (arg : TypedArg , formal : Type ): Boolean = argType(arg, formal) match {
632+ protected def argOK (arg : TypedArg , formal : Type ): Boolean = argType(arg, formal) match
627633 case ref : TermRef if ref.denot.isOverloaded =>
628634 // in this case we could not resolve overloading because no alternative
629635 // matches expected type
@@ -633,15 +639,17 @@ trait Applications extends Compatibility {
633639 case SAMType (sam) => argtpe <:< sam.toFunctionType(isJava = formal.classSymbol.is(JavaDefined ))
634640 case _ => false
635641 }
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- }
644- }
642+ if argMatch == ArgMatch .SubType then
643+ argtpe relaxed_<:< formal.widenExpr
644+ else
645+ isCompatible(argtpe, formal)
646+ || ctx.mode.is(Mode .ImplicitsEnabled ) && SAMargOK
647+ || argMatch == ArgMatch .CompatibleCAP
648+ && {
649+ val argtpe1 = argtpe.widen
650+ val captured = captureWildcards(argtpe1)
651+ (captured ne argtpe1) && isCompatible(captured, formal.widenExpr)
652+ }
645653
646654 /** The type of the given argument */
647655 protected def argType (arg : Arg , formal : Type ): Type
@@ -661,8 +669,8 @@ trait Applications extends Compatibility {
661669 /** Subclass of Application for applicability tests with type arguments and value
662670 * argument trees.
663671 */
664- class ApplicableToTrees (methRef : TermRef , args : List [Tree ], resultType : Type , captureWild : Boolean )(using Context )
665- extends TestApplication (methRef, methRef.widen, args, resultType, captureWild ) {
672+ class ApplicableToTrees (methRef : TermRef , args : List [Tree ], resultType : Type , argMatch : ArgMatch )(using Context )
673+ extends TestApplication (methRef, methRef.widen, args, resultType, argMatch ) {
666674 def argType (arg : Tree , formal : Type ): Type =
667675 if untpd.isContextualClosure(arg) && defn.isContextFunctionType(formal) then arg.tpe
668676 else normalize(arg.tpe, formal)
@@ -672,18 +680,9 @@ trait Applications extends Compatibility {
672680 def harmonizeArgs (args : List [Tree ]): List [Tree ] = harmonize(args)
673681 }
674682
675- /** Subclass of Application for applicability tests with type arguments and value
676- * argument trees.
677- */
678- class ApplicableToTreesDirectly (methRef : TermRef , args : List [Tree ], resultType : Type )(using Context )
679- extends ApplicableToTrees (methRef, args, resultType, captureWild = false ) {
680- override def argOK (arg : TypedArg , formal : Type ): Boolean =
681- argType(arg, formal) relaxed_<:< formal.widenExpr
682- }
683-
684683 /** Subclass of Application for applicability tests with value argument types. */
685- class ApplicableToTypes (methRef : TermRef , args : List [Type ], resultType : Type , captureWild : Boolean )(using Context )
686- extends TestApplication (methRef, methRef, args, resultType, captureWild ) {
684+ class ApplicableToTypes (methRef : TermRef , args : List [Type ], resultType : Type , argMatch : ArgMatch )(using Context )
685+ extends TestApplication (methRef, methRef, args, resultType, argMatch ) {
687686 def argType (arg : Type , formal : Type ): Type = arg
688687 def treeToArg (arg : Tree ): Type = arg.tpe
689688 def isVarArg (arg : Type ): Boolean = arg.isRepeatedParam
@@ -1330,39 +1329,32 @@ trait Applications extends Compatibility {
13301329 /** Is given method reference applicable to argument trees `args`?
13311330 * @param resultType The expected result type of the application
13321331 */
1333- def isApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type , keepConstraint : Boolean , captureWild : Boolean )(using Context ): Boolean = {
1332+ def isApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type , keepConstraint : Boolean , argMatch : ArgMatch )(using Context ): Boolean = {
13341333 def isApp (using Context ): Boolean =
1335- new ApplicableToTrees (methRef, args, resultType, captureWild ).success
1334+ new ApplicableToTrees (methRef, args, resultType, argMatch ).success
13361335 if (keepConstraint) isApp else explore(isApp)
13371336 }
13381337
1339- /** Is given method reference applicable to argument trees `args` without inferring views
1340- * or capturing wildcards?
1341- * @param resultType The expected result type of the application
1342- */
1343- def isDirectlyApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type )(using Context ): Boolean =
1344- explore(new ApplicableToTreesDirectly (methRef, args, resultType).success)
1345-
13461338 /** Is given method reference applicable to argument types `args`?
13471339 * @param resultType The expected result type of the application
13481340 */
1349- def isApplicableMethodRef (methRef : TermRef , args : List [Type ], resultType : Type , captureWild : Boolean )(using Context ): Boolean =
1350- explore(new ApplicableToTypes (methRef, args, resultType, captureWild ).success)
1341+ def isApplicableMethodRef (methRef : TermRef , args : List [Type ], resultType : Type , argMatch : ArgMatch )(using Context ): Boolean =
1342+ explore(new ApplicableToTypes (methRef, args, resultType, argMatch ).success)
13511343
13521344 /** Is given type applicable to argument trees `args`, possibly after inserting an `apply`?
13531345 * @param resultType The expected result type of the application
13541346 */
13551347 def isApplicableType (tp : Type , args : List [Tree ], resultType : Type , keepConstraint : Boolean )(using Context ): Boolean =
13561348 onMethod(tp, args.nonEmpty) {
1357- isApplicableMethodRef(_, args, resultType, keepConstraint, captureWild = false )
1349+ isApplicableMethodRef(_, args, resultType, keepConstraint, ArgMatch . Compatible )
13581350 }
13591351
13601352 /** Is given type applicable to argument types `args`, possibly after inserting an `apply`?
13611353 * @param resultType The expected result type of the application
13621354 */
13631355 def isApplicableType (tp : Type , args : List [Type ], resultType : Type )(using Context ): Boolean =
13641356 onMethod(tp, args.nonEmpty) {
1365- isApplicableMethodRef(_, args, resultType, captureWild = false )
1357+ isApplicableMethodRef(_, args, resultType, ArgMatch . Compatible )
13661358 }
13671359
13681360 private def onMethod (tp : Type , followApply : Boolean )(p : TermRef => Boolean )(using Context ): Boolean = tp match {
@@ -1493,9 +1485,9 @@ trait Applications extends Compatibility {
14931485 || {
14941486 if tp1.isVarArgsMethod then
14951487 tp2.isVarArgsMethod
1496- && isApplicableMethodRef(alt2, tp1.paramInfos.map(_.repeatedToSingle), WildcardType , captureWild = false )
1488+ && isApplicableMethodRef(alt2, tp1.paramInfos.map(_.repeatedToSingle), WildcardType , ArgMatch . Compatible )
14971489 else
1498- isApplicableMethodRef(alt2, tp1.paramInfos, WildcardType , captureWild = false )
1490+ isApplicableMethodRef(alt2, tp1.paramInfos, WildcardType , ArgMatch . Compatible )
14991491 }
15001492 case tp1 : PolyType => // (2)
15011493 inContext(ctx.fresh.setExploreTyperState()) {
@@ -1804,7 +1796,7 @@ trait Applications extends Compatibility {
18041796 }
18051797
18061798 def narrowByTypes (alts : List [TermRef ], argTypes : List [Type ], resultType : Type ): List [TermRef ] =
1807- alts.filterConserve(isApplicableMethodRef(_, argTypes, resultType, captureWild = true ))
1799+ alts.filterConserve(isApplicableMethodRef(_, argTypes, resultType, ArgMatch . CompatibleCAP ))
18081800
18091801 /** Normalization steps before checking arguments:
18101802 *
@@ -1873,11 +1865,11 @@ trait Applications extends Compatibility {
18731865
18741866 def narrowByTrees (alts : List [TermRef ], args : List [Tree ], resultType : Type ): List [TermRef ] = {
18751867 val alts2 = alts.filterConserve(alt =>
1876- isDirectlyApplicableMethodRef (alt, args, resultType)
1868+ isApplicableMethodRef (alt, args, resultType, keepConstraint = false , ArgMatch . SubType )
18771869 )
18781870 if (alts2.isEmpty && ! ctx.isAfterTyper)
18791871 alts.filterConserve(alt =>
1880- isApplicableMethodRef(alt, args, resultType, keepConstraint = false , captureWild = true )
1872+ isApplicableMethodRef(alt, args, resultType, keepConstraint = false , ArgMatch . CompatibleCAP )
18811873 )
18821874 else
18831875 alts2
0 commit comments